blob: 1ea08931762ddf2e92df86c8f44cbee76633e394 [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 Benjamin5df5be1a2017-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
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004841TEST(SSLTest, SealRecord) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004842 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004843 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004844 ASSERT_TRUE(client_ctx);
4845 ASSERT_TRUE(server_ctx);
4846
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004847 bssl::UniquePtr<SSL> client, server;
4848 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004849 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004850
4851 const std::vector<uint8_t> record = {1, 2, 3, 4, 5};
4852 std::vector<uint8_t> prefix(
4853 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004854 body(record.size()),
4855 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004856 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4857 bssl::MakeSpan(body), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004858 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004859
4860 std::vector<uint8_t> sealed;
4861 sealed.insert(sealed.end(), prefix.begin(), prefix.end());
4862 sealed.insert(sealed.end(), body.begin(), body.end());
4863 sealed.insert(sealed.end(), suffix.begin(), suffix.end());
4864 std::vector<uint8_t> sealed_copy = sealed;
4865
4866 bssl::Span<uint8_t> plaintext;
4867 size_t record_len;
4868 uint8_t alert = 255;
4869 EXPECT_EQ(bssl::OpenRecord(server.get(), &plaintext, &record_len, &alert,
4870 bssl::MakeSpan(sealed)),
4871 bssl::OpenRecordResult::kOK);
4872 EXPECT_EQ(record_len, sealed.size());
4873 EXPECT_EQ(plaintext, record);
4874 EXPECT_EQ(255, alert);
4875}
4876
4877TEST(SSLTest, SealRecordInPlace) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004878 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004879 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004880 ASSERT_TRUE(client_ctx);
4881 ASSERT_TRUE(server_ctx);
4882
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004883 bssl::UniquePtr<SSL> client, server;
4884 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004885 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004886
4887 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
4888 std::vector<uint8_t> record = plaintext;
4889 std::vector<uint8_t> prefix(
4890 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004891 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004892 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4893 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004894 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004895 record.insert(record.begin(), prefix.begin(), prefix.end());
4896 record.insert(record.end(), suffix.begin(), suffix.end());
4897
4898 bssl::Span<uint8_t> result;
4899 size_t record_len;
4900 uint8_t alert;
4901 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
4902 bssl::MakeSpan(record)),
4903 bssl::OpenRecordResult::kOK);
4904 EXPECT_EQ(record_len, record.size());
4905 EXPECT_EQ(plaintext, result);
4906}
4907
4908TEST(SSLTest, SealRecordTrailingData) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004909 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004910 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004911 ASSERT_TRUE(client_ctx);
4912 ASSERT_TRUE(server_ctx);
4913
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004914 bssl::UniquePtr<SSL> client, server;
4915 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004916 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004917
4918 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
4919 std::vector<uint8_t> record = plaintext;
4920 std::vector<uint8_t> prefix(
4921 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004922 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004923 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4924 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004925 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004926 record.insert(record.begin(), prefix.begin(), prefix.end());
4927 record.insert(record.end(), suffix.begin(), suffix.end());
4928 record.insert(record.end(), {5, 4, 3, 2, 1});
4929
4930 bssl::Span<uint8_t> result;
4931 size_t record_len;
4932 uint8_t alert;
4933 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
4934 bssl::MakeSpan(record)),
4935 bssl::OpenRecordResult::kOK);
4936 EXPECT_EQ(record_len, record.size() - 5);
4937 EXPECT_EQ(plaintext, result);
4938}
4939
4940TEST(SSLTest, SealRecordInvalidSpanSize) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004941 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004942 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004943 ASSERT_TRUE(client_ctx);
4944 ASSERT_TRUE(server_ctx);
4945
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004946 bssl::UniquePtr<SSL> client, server;
4947 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004948 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004949
4950 std::vector<uint8_t> record = {1, 2, 3, 4, 5};
4951 std::vector<uint8_t> prefix(
4952 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004953 body(record.size()),
4954 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004955
4956 auto expect_err = []() {
4957 int err = ERR_get_error();
4958 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
4959 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_BUFFER_TOO_SMALL);
4960 ERR_clear_error();
4961 };
4962 EXPECT_FALSE(bssl::SealRecord(
4963 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004964 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004965 expect_err();
4966 EXPECT_FALSE(bssl::SealRecord(
4967 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004968 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004969 expect_err();
4970
4971 EXPECT_FALSE(
4972 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4973 bssl::MakeSpan(record.data(), record.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004974 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004975 expect_err();
4976 EXPECT_FALSE(
4977 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4978 bssl::MakeSpan(record.data(), record.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004979 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004980 expect_err();
4981
4982 EXPECT_FALSE(bssl::SealRecord(
4983 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004984 bssl::MakeSpan(suffix.data(), suffix.size() - 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004985 expect_err();
4986 EXPECT_FALSE(bssl::SealRecord(
4987 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004988 bssl::MakeSpan(suffix.data(), suffix.size() + 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004989 expect_err();
4990}
4991
David Benjamin617b8182017-08-29 15:33:10 -04004992// The client should gracefully handle no suitable ciphers being enabled.
4993TEST(SSLTest, NoCiphersAvailable) {
4994 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4995 ASSERT_TRUE(ctx);
4996
4997 // Configure |client_ctx| with a cipher list that does not intersect with its
4998 // version configuration.
4999 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
5000 ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
5001 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
5002
5003 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
5004 ASSERT_TRUE(ssl);
5005 SSL_set_connect_state(ssl.get());
5006
5007 UniquePtr<BIO> rbio(BIO_new(BIO_s_mem())), wbio(BIO_new(BIO_s_mem()));
5008 ASSERT_TRUE(rbio);
5009 ASSERT_TRUE(wbio);
5010 SSL_set0_rbio(ssl.get(), rbio.release());
5011 SSL_set0_wbio(ssl.get(), wbio.release());
5012
5013 int ret = SSL_do_handshake(ssl.get());
5014 EXPECT_EQ(-1, ret);
5015 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), ret));
5016 uint32_t err = ERR_get_error();
5017 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
5018 EXPECT_EQ(SSL_R_NO_CIPHERS_AVAILABLE, ERR_GET_REASON(err));
5019}
5020
David Benjamina4bafd32017-10-03 15:06:29 -04005021TEST_P(SSLVersionTest, SessionVersion) {
5022 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5023 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5024
5025 bssl::UniquePtr<SSL_SESSION> session =
5026 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5027 ASSERT_TRUE(session);
5028 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
5029
5030 // Sessions in TLS 1.3 and later should be single-use.
5031 EXPECT_EQ(version() == TLS1_3_VERSION,
5032 !!SSL_SESSION_should_be_single_use(session.get()));
5033
5034 // Making fake sessions for testing works.
5035 session.reset(SSL_SESSION_new(client_ctx_.get()));
5036 ASSERT_TRUE(session);
5037 ASSERT_TRUE(SSL_SESSION_set_protocol_version(session.get(), version()));
5038 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
5039}
5040
David Benjaminfdb7a352017-10-12 17:34:18 -04005041TEST_P(SSLVersionTest, SSLPending) {
5042 UniquePtr<SSL> ssl(SSL_new(client_ctx_.get()));
5043 ASSERT_TRUE(ssl);
5044 EXPECT_EQ(0, SSL_pending(ssl.get()));
5045
5046 ASSERT_TRUE(Connect());
5047 EXPECT_EQ(0, SSL_pending(client_.get()));
David Benjaminb3ed0712021-11-12 14:43:21 -05005048 EXPECT_EQ(0, SSL_has_pending(client_.get()));
David Benjaminfdb7a352017-10-12 17:34:18 -04005049
5050 ASSERT_EQ(5, SSL_write(server_.get(), "hello", 5));
5051 ASSERT_EQ(5, SSL_write(server_.get(), "world", 5));
5052 EXPECT_EQ(0, SSL_pending(client_.get()));
David Benjaminb3ed0712021-11-12 14:43:21 -05005053 EXPECT_EQ(0, SSL_has_pending(client_.get()));
David Benjaminfdb7a352017-10-12 17:34:18 -04005054
5055 char buf[10];
5056 ASSERT_EQ(1, SSL_peek(client_.get(), buf, 1));
5057 EXPECT_EQ(5, SSL_pending(client_.get()));
David Benjaminb3ed0712021-11-12 14:43:21 -05005058 EXPECT_EQ(1, SSL_has_pending(client_.get()));
David Benjaminfdb7a352017-10-12 17:34:18 -04005059
5060 ASSERT_EQ(1, SSL_read(client_.get(), buf, 1));
5061 EXPECT_EQ(4, SSL_pending(client_.get()));
David Benjaminb3ed0712021-11-12 14:43:21 -05005062 EXPECT_EQ(1, SSL_has_pending(client_.get()));
David Benjaminfdb7a352017-10-12 17:34:18 -04005063
5064 ASSERT_EQ(4, SSL_read(client_.get(), buf, 10));
5065 EXPECT_EQ(0, SSL_pending(client_.get()));
David Benjaminb3ed0712021-11-12 14:43:21 -05005066 if (is_dtls()) {
5067 // In DTLS, the two records would have been read as a single datagram and
5068 // buffered inside |client_|. Thus, |SSL_has_pending| should return true.
5069 //
5070 // This test is slightly unrealistic. It relies on |ConnectClientAndServer|
5071 // using a |BIO| pair, which does not preserve datagram boundaries. Reading
5072 // 1 byte, then 4 bytes, from the first record also relies on
5073 // https://crbug.com/boringssl/65. But it does test the codepaths. When
5074 // fixing either of these bugs, this test may need to be redone.
5075 EXPECT_EQ(1, SSL_has_pending(client_.get()));
5076 } else {
5077 // In TLS, we do not overread, so |SSL_has_pending| should report no data is
5078 // buffered.
5079 EXPECT_EQ(0, SSL_has_pending(client_.get()));
5080 }
David Benjaminfdb7a352017-10-12 17:34:18 -04005081
5082 ASSERT_EQ(2, SSL_read(client_.get(), buf, 2));
5083 EXPECT_EQ(3, SSL_pending(client_.get()));
David Benjaminb3ed0712021-11-12 14:43:21 -05005084 EXPECT_EQ(1, SSL_has_pending(client_.get()));
David Benjaminfdb7a352017-10-12 17:34:18 -04005085}
5086
David Benjamina031b612017-10-11 20:48:25 -04005087// Test that post-handshake tickets consumed by |SSL_shutdown| are ignored.
5088TEST(SSLTest, ShutdownIgnoresTickets) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04005089 bssl::UniquePtr<SSL_CTX> ctx(CreateContextWithTestCertificate(TLS_method()));
David Benjamina031b612017-10-11 20:48:25 -04005090 ASSERT_TRUE(ctx);
5091 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_3_VERSION));
5092 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
5093
David Benjamina031b612017-10-11 20:48:25 -04005094 SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_BOTH);
5095
5096 bssl::UniquePtr<SSL> client, server;
5097 ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
5098
5099 SSL_CTX_sess_set_new_cb(ctx.get(), [](SSL *ssl, SSL_SESSION *session) -> int {
5100 ADD_FAILURE() << "New session callback called during SSL_shutdown";
5101 return 0;
5102 });
5103
5104 // Send close_notify.
5105 EXPECT_EQ(0, SSL_shutdown(server.get()));
5106 EXPECT_EQ(0, SSL_shutdown(client.get()));
5107
5108 // Receive close_notify.
5109 EXPECT_EQ(1, SSL_shutdown(server.get()));
5110 EXPECT_EQ(1, SSL_shutdown(client.get()));
5111}
5112
David Benjamin6cc352e2017-11-02 17:21:39 -04005113TEST(SSLTest, SignatureAlgorithmProperties) {
5114 EXPECT_EQ(EVP_PKEY_NONE, SSL_get_signature_algorithm_key_type(0x1234));
5115 EXPECT_EQ(nullptr, SSL_get_signature_algorithm_digest(0x1234));
5116 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(0x1234));
5117
5118 EXPECT_EQ(EVP_PKEY_RSA,
5119 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
5120 EXPECT_EQ(EVP_md5_sha1(),
5121 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
5122 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
5123
5124 EXPECT_EQ(EVP_PKEY_EC, SSL_get_signature_algorithm_key_type(
5125 SSL_SIGN_ECDSA_SECP256R1_SHA256));
5126 EXPECT_EQ(EVP_sha256(), SSL_get_signature_algorithm_digest(
5127 SSL_SIGN_ECDSA_SECP256R1_SHA256));
5128 EXPECT_FALSE(
5129 SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_ECDSA_SECP256R1_SHA256));
5130
5131 EXPECT_EQ(EVP_PKEY_RSA,
David Benjamin6879e192018-04-13 16:01:02 -04005132 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04005133 EXPECT_EQ(EVP_sha384(),
David Benjamin6879e192018-04-13 16:01:02 -04005134 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PSS_RSAE_SHA384));
5135 EXPECT_TRUE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04005136}
5137
Adam Langley85967952018-07-03 08:04:58 -07005138static int XORCompressFunc(SSL *ssl, CBB *out, const uint8_t *in,
5139 size_t in_len) {
5140 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07005141 if (!CBB_add_u8(out, in[i] ^ 0x55)) {
Adam Langley85967952018-07-03 08:04:58 -07005142 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07005143 }
5144 }
5145
5146 SSL_set_app_data(ssl, XORCompressFunc);
5147
Adam Langley85967952018-07-03 08:04:58 -07005148 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07005149}
5150
Adam Langley85967952018-07-03 08:04:58 -07005151static int XORDecompressFunc(SSL *ssl, CRYPTO_BUFFER **out,
5152 size_t uncompressed_len, const uint8_t *in,
5153 size_t in_len) {
5154 if (in_len != uncompressed_len) {
5155 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07005156 }
5157
5158 uint8_t *data;
Adam Langley85967952018-07-03 08:04:58 -07005159 *out = CRYPTO_BUFFER_alloc(&data, uncompressed_len);
5160 if (*out == nullptr) {
5161 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07005162 }
5163
Adam Langley85967952018-07-03 08:04:58 -07005164 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07005165 data[i] = in[i] ^ 0x55;
5166 }
5167
5168 SSL_set_app_data(ssl, XORDecompressFunc);
5169
Adam Langley85967952018-07-03 08:04:58 -07005170 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07005171}
5172
5173TEST(SSLTest, CertCompression) {
5174 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04005175 bssl::UniquePtr<SSL_CTX> server_ctx(
5176 CreateContextWithTestCertificate(TLS_method()));
Adam Langley0080d832018-06-07 16:39:49 -07005177 ASSERT_TRUE(client_ctx);
5178 ASSERT_TRUE(server_ctx);
5179
Adam Langley0080d832018-06-07 16:39:49 -07005180 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
5181 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
5182 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
5183 client_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
5184 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
5185 server_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
5186
5187 bssl::UniquePtr<SSL> client, server;
5188 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
5189 server_ctx.get()));
5190
5191 EXPECT_TRUE(SSL_get_app_data(client.get()) == XORDecompressFunc);
5192 EXPECT_TRUE(SSL_get_app_data(server.get()) == XORCompressFunc);
5193}
5194
Adam Langleyddb57cf2018-01-26 09:17:53 -08005195void MoveBIOs(SSL *dest, SSL *src) {
5196 BIO *rbio = SSL_get_rbio(src);
5197 BIO_up_ref(rbio);
5198 SSL_set0_rbio(dest, rbio);
5199
5200 BIO *wbio = SSL_get_wbio(src);
5201 BIO_up_ref(wbio);
5202 SSL_set0_wbio(dest, wbio);
5203
5204 SSL_set0_rbio(src, nullptr);
5205 SSL_set0_wbio(src, nullptr);
5206}
5207
5208TEST(SSLTest, Handoff) {
5209 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
5210 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04005211 bssl::UniquePtr<SSL_CTX> handshaker_ctx(
5212 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08005213 ASSERT_TRUE(client_ctx);
5214 ASSERT_TRUE(server_ctx);
5215 ASSERT_TRUE(handshaker_ctx);
5216
Matthew Braithwaite134fb892019-11-26 17:56:11 -08005217 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_CLIENT);
5218 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Anton Bikineev50e7ea52022-01-23 22:35:48 +01005219 SSL_CTX_set_handoff_mode(server_ctx.get(), true);
Matthew Braithwaite134fb892019-11-26 17:56:11 -08005220 uint8_t keys[48];
David Benjamin243b5cc2019-12-04 11:23:50 -05005221 SSL_CTX_get_tlsext_ticket_keys(server_ctx.get(), &keys, sizeof(keys));
Matthew Braithwaite134fb892019-11-26 17:56:11 -08005222 SSL_CTX_set_tlsext_ticket_keys(handshaker_ctx.get(), &keys, sizeof(keys));
Adam Langleyddb57cf2018-01-26 09:17:53 -08005223
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005224 for (bool early_data : {false, true}) {
5225 SCOPED_TRACE(early_data);
5226 for (bool is_resume : {false, true}) {
5227 SCOPED_TRACE(is_resume);
5228 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04005229 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
5230 server_ctx.get()));
5231 SSL_set_early_data_enabled(client.get(), early_data);
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005232 if (is_resume) {
5233 ASSERT_TRUE(g_last_session);
David Benjamin9b2cdb72021-04-01 23:21:53 -04005234 SSL_set_session(client.get(), g_last_session.get());
5235 if (early_data) {
5236 EXPECT_GT(g_last_session->ticket_max_early_data, 0u);
5237 }
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005238 }
David Benjamin9b2cdb72021-04-01 23:21:53 -04005239
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005240
5241 int client_ret = SSL_do_handshake(client.get());
5242 int client_err = SSL_get_error(client.get(), client_ret);
5243
5244 uint8_t byte_written;
David Benjamin9b2cdb72021-04-01 23:21:53 -04005245 if (early_data && is_resume) {
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005246 ASSERT_EQ(client_err, 0);
5247 EXPECT_TRUE(SSL_in_early_data(client.get()));
5248 // Attempt to write early data.
5249 byte_written = 43;
5250 EXPECT_EQ(SSL_write(client.get(), &byte_written, 1), 1);
5251 } else {
5252 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
5253 }
5254
5255 int server_ret = SSL_do_handshake(server.get());
5256 int server_err = SSL_get_error(server.get(), server_ret);
5257 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
5258
5259 ScopedCBB cbb;
5260 Array<uint8_t> handoff;
5261 SSL_CLIENT_HELLO hello;
5262 ASSERT_TRUE(CBB_init(cbb.get(), 256));
5263 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
5264 ASSERT_TRUE(CBBFinishArray(cbb.get(), &handoff));
5265
5266 bssl::UniquePtr<SSL> handshaker(SSL_new(handshaker_ctx.get()));
5267 // Note split handshakes determines 0-RTT support, for both the current
5268 // handshake and newly-issued tickets, entirely by |handshaker|. There is
5269 // no need to call |SSL_set_early_data_enabled| on |server|.
5270 SSL_set_early_data_enabled(handshaker.get(), 1);
5271 ASSERT_TRUE(SSL_apply_handoff(handshaker.get(), handoff));
5272
5273 MoveBIOs(handshaker.get(), server.get());
5274
5275 int handshake_ret = SSL_do_handshake(handshaker.get());
5276 int handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
5277 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
5278
5279 // Double-check that additional calls to |SSL_do_handshake| continue
Adam Langley472d91c2020-02-18 12:12:35 -08005280 // to get |SSL_ERROR_HANDBACK|.
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005281 handshake_ret = SSL_do_handshake(handshaker.get());
5282 handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
5283 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
5284
5285 ScopedCBB cbb_handback;
5286 Array<uint8_t> handback;
5287 ASSERT_TRUE(CBB_init(cbb_handback.get(), 1024));
5288 ASSERT_TRUE(SSL_serialize_handback(handshaker.get(), cbb_handback.get()));
5289 ASSERT_TRUE(CBBFinishArray(cbb_handback.get(), &handback));
5290
5291 bssl::UniquePtr<SSL> server2(SSL_new(server_ctx.get()));
5292 ASSERT_TRUE(SSL_apply_handback(server2.get(), handback));
5293
5294 MoveBIOs(server2.get(), handshaker.get());
5295 ASSERT_TRUE(CompleteHandshakes(client.get(), server2.get()));
5296 EXPECT_EQ(is_resume, SSL_session_reused(client.get()));
5297
David Benjamin9b2cdb72021-04-01 23:21:53 -04005298 if (early_data && is_resume) {
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08005299 // In this case, one byte of early data has already been written above.
5300 EXPECT_TRUE(SSL_early_data_accepted(client.get()));
5301 } else {
5302 byte_written = 42;
5303 EXPECT_EQ(SSL_write(client.get(), &byte_written, 1), 1);
5304 }
5305 uint8_t byte;
5306 EXPECT_EQ(SSL_read(server2.get(), &byte, 1), 1);
5307 EXPECT_EQ(byte_written, byte);
5308
5309 byte = 44;
5310 EXPECT_EQ(SSL_write(server2.get(), &byte, 1), 1);
5311 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
5312 EXPECT_EQ(44, byte);
Matthew Braithwaite134fb892019-11-26 17:56:11 -08005313 }
Matthew Braithwaite134fb892019-11-26 17:56:11 -08005314 }
Adam Langleyddb57cf2018-01-26 09:17:53 -08005315}
5316
5317TEST(SSLTest, HandoffDeclined) {
5318 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04005319 bssl::UniquePtr<SSL_CTX> server_ctx(
5320 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08005321 ASSERT_TRUE(client_ctx);
5322 ASSERT_TRUE(server_ctx);
5323
Anton Bikineev50e7ea52022-01-23 22:35:48 +01005324 SSL_CTX_set_handoff_mode(server_ctx.get(), true);
Adam Langleyddb57cf2018-01-26 09:17:53 -08005325 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
5326
Adam Langleyddb57cf2018-01-26 09:17:53 -08005327 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04005328 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
5329 server_ctx.get()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08005330
5331 int client_ret = SSL_do_handshake(client.get());
5332 int client_err = SSL_get_error(client.get(), client_ret);
5333 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
5334
5335 int server_ret = SSL_do_handshake(server.get());
5336 int server_err = SSL_get_error(server.get(), server_ret);
5337 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
5338
5339 ScopedCBB cbb;
Adam Langleyc9827e02019-04-12 14:46:50 -07005340 SSL_CLIENT_HELLO hello;
Adam Langleyddb57cf2018-01-26 09:17:53 -08005341 ASSERT_TRUE(CBB_init(cbb.get(), 256));
Adam Langleyc9827e02019-04-12 14:46:50 -07005342 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
Adam Langleyddb57cf2018-01-26 09:17:53 -08005343
5344 ASSERT_TRUE(SSL_decline_handoff(server.get()));
5345
5346 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
5347
5348 uint8_t byte = 42;
5349 EXPECT_EQ(SSL_write(client.get(), &byte, 1), 1);
5350 EXPECT_EQ(SSL_read(server.get(), &byte, 1), 1);
5351 EXPECT_EQ(42, byte);
5352
5353 byte = 43;
5354 EXPECT_EQ(SSL_write(server.get(), &byte, 1), 1);
5355 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
5356 EXPECT_EQ(43, byte);
5357}
5358
Adam Langley826ce152018-08-03 10:31:21 -07005359static std::string SigAlgsToString(Span<const uint16_t> sigalgs) {
5360 std::string ret = "{";
5361
5362 for (uint16_t v : sigalgs) {
5363 if (ret.size() > 1) {
5364 ret += ", ";
5365 }
5366
5367 char buf[8];
5368 snprintf(buf, sizeof(buf) - 1, "0x%02x", v);
5369 buf[sizeof(buf)-1] = 0;
5370 ret += std::string(buf);
5371 }
5372
5373 ret += "}";
5374 return ret;
5375}
5376
5377void ExpectSigAlgsEqual(Span<const uint16_t> expected,
5378 Span<const uint16_t> actual) {
5379 bool matches = false;
5380 if (expected.size() == actual.size()) {
5381 matches = true;
5382
5383 for (size_t i = 0; i < expected.size(); i++) {
5384 if (expected[i] != actual[i]) {
5385 matches = false;
5386 break;
5387 }
5388 }
5389 }
5390
5391 if (!matches) {
5392 ADD_FAILURE() << "expected: " << SigAlgsToString(expected)
5393 << " got: " << SigAlgsToString(actual);
5394 }
5395}
5396
5397TEST(SSLTest, SigAlgs) {
5398 static const struct {
5399 std::vector<int> input;
5400 bool ok;
5401 std::vector<uint16_t> expected;
5402 } kTests[] = {
5403 {{}, true, {}},
5404 {{1}, false, {}},
5405 {{1, 2, 3}, false, {}},
5406 {{NID_sha256, EVP_PKEY_ED25519}, false, {}},
5407 {{NID_sha256, EVP_PKEY_RSA, NID_sha256, EVP_PKEY_RSA}, false, {}},
5408
5409 {{NID_sha256, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA256}},
5410 {{NID_sha512, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA512}},
5411 {{NID_sha256, EVP_PKEY_RSA_PSS}, true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
5412 {{NID_undef, EVP_PKEY_ED25519}, true, {SSL_SIGN_ED25519}},
5413 {{NID_undef, EVP_PKEY_ED25519, NID_sha384, EVP_PKEY_EC},
5414 true,
5415 {SSL_SIGN_ED25519, SSL_SIGN_ECDSA_SECP384R1_SHA384}},
5416 };
5417
5418 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
5419
5420 unsigned n = 1;
5421 for (const auto &test : kTests) {
5422 SCOPED_TRACE(n++);
5423
5424 const bool ok =
5425 SSL_CTX_set1_sigalgs(ctx.get(), test.input.data(), test.input.size());
5426 EXPECT_EQ(ok, test.ok);
5427
5428 if (!ok) {
5429 ERR_clear_error();
5430 }
5431
5432 if (!test.ok) {
5433 continue;
5434 }
5435
5436 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
5437 }
5438}
5439
5440TEST(SSLTest, SigAlgsList) {
5441 static const struct {
5442 const char *input;
5443 bool ok;
5444 std::vector<uint16_t> expected;
5445 } kTests[] = {
5446 {"", false, {}},
5447 {":", false, {}},
5448 {"+", false, {}},
5449 {"RSA", false, {}},
5450 {"RSA+", false, {}},
5451 {"RSA+SHA256:", false, {}},
5452 {":RSA+SHA256:", false, {}},
5453 {":RSA+SHA256+:", false, {}},
5454 {"!", false, {}},
5455 {"\x01", false, {}},
5456 {"RSA+SHA256:RSA+SHA384:RSA+SHA256", false, {}},
5457 {"RSA-PSS+SHA256:rsa_pss_rsae_sha256", false, {}},
5458
5459 {"RSA+SHA256", true, {SSL_SIGN_RSA_PKCS1_SHA256}},
5460 {"RSA+SHA256:ed25519",
5461 true,
5462 {SSL_SIGN_RSA_PKCS1_SHA256, SSL_SIGN_ED25519}},
5463 {"ECDSA+SHA256:RSA+SHA512",
5464 true,
5465 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PKCS1_SHA512}},
5466 {"ecdsa_secp256r1_sha256:rsa_pss_rsae_sha256",
5467 true,
5468 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PSS_RSAE_SHA256}},
5469 {"RSA-PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
5470 {"PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
5471 };
5472
5473 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
5474
5475 unsigned n = 1;
5476 for (const auto &test : kTests) {
5477 SCOPED_TRACE(n++);
5478
5479 const bool ok = SSL_CTX_set1_sigalgs_list(ctx.get(), test.input);
5480 EXPECT_EQ(ok, test.ok);
5481
5482 if (!ok) {
5483 if (test.ok) {
5484 ERR_print_errors_fp(stderr);
5485 }
5486 ERR_clear_error();
5487 }
5488
5489 if (!test.ok) {
5490 continue;
5491 }
5492
5493 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
5494 }
5495}
5496
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07005497TEST(SSLTest, ApplyHandoffRemovesUnsupportedCiphers) {
5498 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
5499 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
5500
5501 // handoff is a handoff message that has been artificially modified to pretend
5502 // that only cipher 0x0A is supported. When it is applied to |server|, all
5503 // ciphers but that one should be removed.
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07005504 //
5505 // To make a new one of these, try sticking this in the |Handoff| test above:
5506 //
5507 // hexdump(stderr, "", handoff.data(), handoff.size());
5508 // sed -e 's/\(..\)/0x\1, /g'
5509 //
5510 // and modify serialize_features() to emit only cipher 0x0A.
5511
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07005512 uint8_t handoff[] = {
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07005513 0x30, 0x81, 0x9a, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
5514 0x00, 0x00, 0x7e, 0x03, 0x03, 0x30, 0x8e, 0x8f, 0x79, 0xd2, 0x87, 0x39,
5515 0xc2, 0x23, 0x23, 0x13, 0xca, 0x3c, 0x80, 0x44, 0xfd, 0x80, 0x83, 0x62,
5516 0x3c, 0xcc, 0xf8, 0x76, 0xd3, 0x62, 0xbb, 0x54, 0xe3, 0xc4, 0x39, 0x24,
5517 0xa5, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07005518 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
5519 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07005520 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
5521 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
5522 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
5523 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
5524 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x02, 0x00,
5525 0x0a, 0x04, 0x0a, 0x00, 0x15, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00,
5526 0x1d,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07005527 };
5528
5529 EXPECT_EQ(20u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
5530 ASSERT_TRUE(
5531 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
5532 EXPECT_EQ(1u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
5533}
5534
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07005535TEST(SSLTest, ApplyHandoffRemovesUnsupportedCurves) {
5536 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
5537 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
5538
5539 // handoff is a handoff message that has been artificially modified to pretend
5540 // that only one curve is supported. When it is applied to |server|, all
5541 // curves but that one should be removed.
5542 //
5543 // See |ApplyHandoffRemovesUnsupportedCiphers| for how to make a new one of
5544 // these.
5545 uint8_t handoff[] = {
5546 0x30, 0x81, 0xc0, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
5547 0x00, 0x00, 0x7e, 0x03, 0x03, 0x98, 0x30, 0xce, 0xd9, 0xb0, 0xdf, 0x5f,
5548 0x82, 0x05, 0x4a, 0x43, 0x67, 0x7e, 0xdb, 0x6a, 0x4f, 0x21, 0x18, 0x4e,
5549 0x0d, 0x94, 0x63, 0x18, 0x8b, 0x54, 0x89, 0xdb, 0x8b, 0x1d, 0x84, 0xbc,
5550 0x09, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
5551 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
5552 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
5553 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
5554 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
5555 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
5556 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
5557 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x30, 0x00,
5558 0x02, 0x00, 0x0a, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x8c, 0x00, 0x8d, 0x00,
5559 0x9c, 0x00, 0x9d, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xc0, 0x09, 0xc0,
5560 0x0a, 0xc0, 0x13, 0xc0, 0x14, 0xc0, 0x2b, 0xc0, 0x2c, 0xc0, 0x2f, 0xc0,
5561 0x30, 0xc0, 0x35, 0xc0, 0x36, 0xcc, 0xa8, 0xcc, 0xa9, 0xcc, 0xac, 0x04,
5562 0x02, 0x00, 0x17,
5563 };
5564
5565 // The zero length means that the default list of groups is used.
5566 EXPECT_EQ(0u, server->config->supported_group_list.size());
5567 ASSERT_TRUE(
5568 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
5569 EXPECT_EQ(1u, server->config->supported_group_list.size());
5570}
5571
Adam Langleyba9ad662018-12-17 13:59:38 -08005572TEST(SSLTest, ZeroSizedWiteFlushesHandshakeMessages) {
5573 // If there are pending handshake mesages, an |SSL_write| of zero bytes should
5574 // flush them.
David Benjamin9b2cdb72021-04-01 23:21:53 -04005575 bssl::UniquePtr<SSL_CTX> server_ctx(
5576 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyba9ad662018-12-17 13:59:38 -08005577 EXPECT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
5578 EXPECT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
Adam Langleyba9ad662018-12-17 13:59:38 -08005579
5580 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
5581 EXPECT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
5582 EXPECT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
5583
5584 bssl::UniquePtr<SSL> client, server;
5585 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
5586 server_ctx.get()));
5587
5588 BIO *client_wbio = SSL_get_wbio(client.get());
5589 EXPECT_EQ(0u, BIO_wpending(client_wbio));
5590 EXPECT_TRUE(SSL_key_update(client.get(), SSL_KEY_UPDATE_NOT_REQUESTED));
5591 EXPECT_EQ(0u, BIO_wpending(client_wbio));
5592 EXPECT_EQ(0, SSL_write(client.get(), nullptr, 0));
5593 EXPECT_NE(0u, BIO_wpending(client_wbio));
5594}
5595
David Benjamin5869eb32018-07-17 00:59:45 -04005596TEST_P(SSLVersionTest, VerifyBeforeCertRequest) {
5597 // Configure the server to request client certificates.
5598 SSL_CTX_set_custom_verify(
5599 server_ctx_.get(), SSL_VERIFY_PEER,
5600 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
5601
5602 // Configure the client to reject the server certificate.
5603 SSL_CTX_set_custom_verify(
5604 client_ctx_.get(), SSL_VERIFY_PEER,
5605 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_invalid; });
5606
5607 // cert_cb should not be called. Verification should fail first.
5608 SSL_CTX_set_cert_cb(client_ctx_.get(),
5609 [](SSL *ssl, void *arg) {
5610 ADD_FAILURE() << "cert_cb unexpectedly called";
5611 return 0;
5612 },
5613 nullptr);
5614
5615 bssl::UniquePtr<SSL> client, server;
5616 EXPECT_FALSE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
5617 server_ctx_.get()));
5618}
5619
David Benjamin492c9aa2018-08-31 16:35:22 -05005620// Test that ticket-based sessions on the client get fake session IDs.
5621TEST_P(SSLVersionTest, FakeIDsForTickets) {
5622 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5623 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5624
5625 bssl::UniquePtr<SSL_SESSION> session =
5626 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5627 ASSERT_TRUE(session);
5628
5629 EXPECT_TRUE(SSL_SESSION_has_ticket(session.get()));
5630 unsigned session_id_length;
5631 SSL_SESSION_get_id(session.get(), &session_id_length);
5632 EXPECT_NE(session_id_length, 0u);
5633}
5634
David Benjamin6c04bd12018-07-19 18:13:09 -04005635// These tests test multi-threaded behavior. They are intended to run with
5636// ThreadSanitizer.
David Benjamin5b33eff2018-09-22 16:52:48 -07005637#if defined(OPENSSL_THREADS)
David Benjamin6c04bd12018-07-19 18:13:09 -04005638TEST_P(SSLVersionTest, SessionCacheThreads) {
5639 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
5640 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5641 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5642
5643 if (version() == TLS1_3_VERSION) {
5644 // Our TLS 1.3 implementation does not support stateful resumption.
5645 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
5646 return;
5647 }
5648
5649 // Establish two client sessions to test with.
5650 bssl::UniquePtr<SSL_SESSION> session1 =
5651 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5652 ASSERT_TRUE(session1);
5653 bssl::UniquePtr<SSL_SESSION> session2 =
5654 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5655 ASSERT_TRUE(session2);
5656
5657 auto connect_with_session = [&](SSL_SESSION *session) {
5658 ClientConfig config;
5659 config.session = session;
5660 UniquePtr<SSL> client, server;
5661 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
5662 server_ctx_.get(), config));
5663 };
5664
5665 // Resume sessions in parallel with establishing new ones.
5666 {
5667 std::vector<std::thread> threads;
5668 threads.emplace_back([&] { connect_with_session(nullptr); });
5669 threads.emplace_back([&] { connect_with_session(nullptr); });
5670 threads.emplace_back([&] { connect_with_session(session1.get()); });
5671 threads.emplace_back([&] { connect_with_session(session1.get()); });
5672 threads.emplace_back([&] { connect_with_session(session2.get()); });
5673 threads.emplace_back([&] { connect_with_session(session2.get()); });
5674 for (auto &thread : threads) {
5675 thread.join();
5676 }
5677 }
5678
David Benjamina10017c2021-06-16 16:00:13 -04005679 // Hit the maximum session cache size across multiple threads, to test the
5680 // size enforcement logic.
David Benjamin6c04bd12018-07-19 18:13:09 -04005681 size_t limit = SSL_CTX_sess_number(server_ctx_.get()) + 2;
5682 SSL_CTX_sess_set_cache_size(server_ctx_.get(), limit);
5683 {
5684 std::vector<std::thread> threads;
5685 for (int i = 0; i < 4; i++) {
5686 threads.emplace_back([&]() {
5687 connect_with_session(nullptr);
5688 EXPECT_LE(SSL_CTX_sess_number(server_ctx_.get()), limit);
5689 });
5690 }
5691 for (auto &thread : threads) {
5692 thread.join();
5693 }
5694 EXPECT_EQ(SSL_CTX_sess_number(server_ctx_.get()), limit);
5695 }
David Benjamina10017c2021-06-16 16:00:13 -04005696
5697 // Reset the session cache, this time with a mock clock.
5698 ASSERT_NO_FATAL_FAILURE(ResetContexts());
5699 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
5700 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5701 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5702 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
5703
5704 // Make some sessions at an arbitrary start time. Then expire them.
5705 g_current_time.tv_sec = 1000;
5706 bssl::UniquePtr<SSL_SESSION> expired_session1 =
5707 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5708 ASSERT_TRUE(expired_session1);
5709 bssl::UniquePtr<SSL_SESSION> expired_session2 =
5710 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5711 ASSERT_TRUE(expired_session2);
5712 g_current_time.tv_sec += 100 * SSL_DEFAULT_SESSION_TIMEOUT;
5713
5714 session1 = CreateClientSession(client_ctx_.get(), server_ctx_.get());
5715 ASSERT_TRUE(session1);
5716
5717 // Every 256 connections, we flush stale sessions from the session cache. Test
5718 // this logic is correctly synchronized with other connection attempts.
5719 static const int kNumConnections = 256;
5720 {
5721 std::vector<std::thread> threads;
5722 threads.emplace_back([&] {
5723 for (int i = 0; i < kNumConnections; i++) {
5724 connect_with_session(nullptr);
5725 }
5726 });
5727 threads.emplace_back([&] {
5728 for (int i = 0; i < kNumConnections; i++) {
5729 connect_with_session(nullptr);
5730 }
5731 });
5732 threads.emplace_back([&] {
5733 // Never connect with |expired_session2|. The session cache eagerly
5734 // removes expired sessions when it sees them. Leaving |expired_session2|
5735 // untouched ensures it is instead cleared by periodic flushing.
5736 for (int i = 0; i < kNumConnections; i++) {
5737 connect_with_session(expired_session1.get());
5738 }
5739 });
5740 threads.emplace_back([&] {
5741 for (int i = 0; i < kNumConnections; i++) {
5742 connect_with_session(session1.get());
5743 }
5744 });
5745 for (auto &thread : threads) {
5746 thread.join();
5747 }
5748 }
David Benjamin6c04bd12018-07-19 18:13:09 -04005749}
5750
5751TEST_P(SSLVersionTest, SessionTicketThreads) {
5752 for (bool renew_ticket : {false, true}) {
5753 SCOPED_TRACE(renew_ticket);
5754 ResetContexts();
5755 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5756 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5757 if (renew_ticket) {
5758 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
5759 }
5760
5761 // Establish two client sessions to test with.
5762 bssl::UniquePtr<SSL_SESSION> session1 =
5763 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5764 ASSERT_TRUE(session1);
5765 bssl::UniquePtr<SSL_SESSION> session2 =
5766 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5767 ASSERT_TRUE(session2);
5768
5769 auto connect_with_session = [&](SSL_SESSION *session) {
5770 ClientConfig config;
5771 config.session = session;
5772 UniquePtr<SSL> client, server;
5773 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
5774 server_ctx_.get(), config));
5775 };
5776
5777 // Resume sessions in parallel with establishing new ones.
5778 {
5779 std::vector<std::thread> threads;
5780 threads.emplace_back([&] { connect_with_session(nullptr); });
5781 threads.emplace_back([&] { connect_with_session(nullptr); });
5782 threads.emplace_back([&] { connect_with_session(session1.get()); });
5783 threads.emplace_back([&] { connect_with_session(session1.get()); });
5784 threads.emplace_back([&] { connect_with_session(session2.get()); });
5785 threads.emplace_back([&] { connect_with_session(session2.get()); });
5786 for (auto &thread : threads) {
5787 thread.join();
5788 }
5789 }
5790 }
5791}
5792
5793// SSL_CTX_get0_certificate needs to lock internally. Test this works.
5794TEST(SSLTest, GetCertificateThreads) {
5795 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
5796 ASSERT_TRUE(ctx);
5797 bssl::UniquePtr<X509> cert = GetTestCertificate();
5798 ASSERT_TRUE(cert);
5799 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
5800
5801 // Existing code expects |SSL_CTX_get0_certificate| to be callable from two
5802 // threads concurrently. It originally was an immutable operation. Now we
5803 // implement it with a thread-safe cache, so it is worth testing.
5804 X509 *cert2_thread;
5805 std::thread thread(
5806 [&] { cert2_thread = SSL_CTX_get0_certificate(ctx.get()); });
5807 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
5808 thread.join();
5809
5810 EXPECT_EQ(cert2, cert2_thread);
5811 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
5812}
David Benjamin4cce9552018-12-13 12:20:54 -06005813
5814// Functions which access properties on the negotiated session are thread-safe
5815// where needed. Prior to TLS 1.3, clients resuming sessions and servers
5816// performing stateful resumption will share an underlying SSL_SESSION object,
5817// potentially across threads.
5818TEST_P(SSLVersionTest, SessionPropertiesThreads) {
5819 if (version() == TLS1_3_VERSION) {
5820 // Our TLS 1.3 implementation does not support stateful resumption.
5821 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
5822 return;
5823 }
5824
5825 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
5826 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5827 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5828
5829 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
5830 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
5831
5832 // Configure mutual authentication, so we have more session state.
5833 SSL_CTX_set_custom_verify(
5834 client_ctx_.get(), SSL_VERIFY_PEER,
5835 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
5836 SSL_CTX_set_custom_verify(
5837 server_ctx_.get(), SSL_VERIFY_PEER,
5838 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
5839
5840 // Establish a client session to test with.
5841 bssl::UniquePtr<SSL_SESSION> session =
5842 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5843 ASSERT_TRUE(session);
5844
5845 // Resume with it twice.
5846 UniquePtr<SSL> ssls[4];
5847 ClientConfig config;
5848 config.session = session.get();
5849 ASSERT_TRUE(ConnectClientAndServer(&ssls[0], &ssls[1], client_ctx_.get(),
5850 server_ctx_.get(), config));
5851 ASSERT_TRUE(ConnectClientAndServer(&ssls[2], &ssls[3], client_ctx_.get(),
5852 server_ctx_.get(), config));
5853
5854 // Read properties in parallel.
5855 auto read_properties = [](const SSL *ssl) {
5856 EXPECT_TRUE(SSL_get_peer_cert_chain(ssl));
5857 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(ssl));
5858 EXPECT_TRUE(peer);
5859 EXPECT_TRUE(SSL_get_current_cipher(ssl));
5860 EXPECT_TRUE(SSL_get_curve_id(ssl));
5861 };
5862
5863 std::vector<std::thread> threads;
5864 for (const auto &ssl_ptr : ssls) {
5865 const SSL *ssl = ssl_ptr.get();
5866 threads.emplace_back([=] { read_properties(ssl); });
5867 }
5868 for (auto &thread : threads) {
5869 thread.join();
5870 }
5871}
David Benjamina486c6c2019-03-28 18:32:38 -05005872#endif // OPENSSL_THREADS
David Benjamin6c04bd12018-07-19 18:13:09 -04005873
Steven Valdezc8e0f902018-07-14 11:23:01 -04005874constexpr size_t kNumQUICLevels = 4;
5875static_assert(ssl_encryption_initial < kNumQUICLevels,
5876 "kNumQUICLevels is wrong");
5877static_assert(ssl_encryption_early_data < kNumQUICLevels,
5878 "kNumQUICLevels is wrong");
5879static_assert(ssl_encryption_handshake < kNumQUICLevels,
5880 "kNumQUICLevels is wrong");
5881static_assert(ssl_encryption_application < kNumQUICLevels,
5882 "kNumQUICLevels is wrong");
5883
David Benjamin1e859052020-02-09 16:04:58 -05005884const char *LevelToString(ssl_encryption_level_t level) {
5885 switch (level) {
5886 case ssl_encryption_initial:
5887 return "initial";
5888 case ssl_encryption_early_data:
5889 return "early data";
5890 case ssl_encryption_handshake:
5891 return "handshake";
5892 case ssl_encryption_application:
5893 return "application";
5894 }
5895 return "<unknown>";
5896}
5897
Steven Valdezc8e0f902018-07-14 11:23:01 -04005898class MockQUICTransport {
5899 public:
David Benjamind6343572019-08-15 17:29:02 -04005900 enum class Role { kClient, kServer };
5901
5902 explicit MockQUICTransport(Role role) : role_(role) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005903 // The caller is expected to configure initial secrets.
5904 levels_[ssl_encryption_initial].write_secret = {1};
5905 levels_[ssl_encryption_initial].read_secret = {1};
5906 }
5907
5908 void set_peer(MockQUICTransport *peer) { peer_ = peer; }
5909
5910 bool has_alert() const { return has_alert_; }
5911 ssl_encryption_level_t alert_level() const { return alert_level_; }
5912 uint8_t alert() const { return alert_; }
5913
5914 bool PeerSecretsMatch(ssl_encryption_level_t level) const {
5915 return levels_[level].write_secret == peer_->levels_[level].read_secret &&
Steven Valdez384d0ea2018-11-06 10:45:36 -05005916 levels_[level].read_secret == peer_->levels_[level].write_secret &&
5917 levels_[level].cipher == peer_->levels_[level].cipher;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005918 }
5919
David Benjamin1e859052020-02-09 16:04:58 -05005920 bool HasReadSecret(ssl_encryption_level_t level) const {
5921 return !levels_[level].read_secret.empty();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005922 }
5923
David Benjamin1e859052020-02-09 16:04:58 -05005924 bool HasWriteSecret(ssl_encryption_level_t level) const {
5925 return !levels_[level].write_secret.empty();
5926 }
5927
David Benjamin5298ef92020-03-13 12:17:30 -04005928 void AllowOutOfOrderWrites() { allow_out_of_order_writes_ = true; }
5929
David Benjamin1e859052020-02-09 16:04:58 -05005930 bool SetReadSecret(ssl_encryption_level_t level, const SSL_CIPHER *cipher,
5931 Span<const uint8_t> secret) {
5932 if (HasReadSecret(level)) {
5933 ADD_FAILURE() << LevelToString(level) << " read secret configured twice";
5934 return false;
5935 }
5936
5937 if (role_ == Role::kClient && level == ssl_encryption_early_data) {
5938 ADD_FAILURE() << "Unexpected early data read secret";
5939 return false;
5940 }
5941
5942 ssl_encryption_level_t ack_level =
5943 level == ssl_encryption_early_data ? ssl_encryption_application : level;
5944 if (!HasWriteSecret(ack_level)) {
5945 ADD_FAILURE() << LevelToString(level)
5946 << " read secret configured before ACK write secret";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005947 return false;
5948 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05005949
5950 if (cipher == nullptr) {
David Benjamin1e859052020-02-09 16:04:58 -05005951 ADD_FAILURE() << "Unexpected null cipher";
Steven Valdez384d0ea2018-11-06 10:45:36 -05005952 return false;
5953 }
5954
David Benjamin1e859052020-02-09 16:04:58 -05005955 if (level != ssl_encryption_early_data &&
5956 SSL_CIPHER_get_id(cipher) != levels_[level].cipher) {
5957 ADD_FAILURE() << "Cipher suite inconsistent";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005958 return false;
5959 }
David Benjamind6343572019-08-15 17:29:02 -04005960
David Benjamin1e859052020-02-09 16:04:58 -05005961 levels_[level].read_secret.assign(secret.begin(), secret.end());
5962 levels_[level].cipher = SSL_CIPHER_get_id(cipher);
5963 return true;
5964 }
5965
5966 bool SetWriteSecret(ssl_encryption_level_t level, const SSL_CIPHER *cipher,
5967 Span<const uint8_t> secret) {
5968 if (HasWriteSecret(level)) {
5969 ADD_FAILURE() << LevelToString(level) << " write secret configured twice";
David Benjamind6343572019-08-15 17:29:02 -04005970 return false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005971 }
David Benjamind6343572019-08-15 17:29:02 -04005972
David Benjamin1e859052020-02-09 16:04:58 -05005973 if (role_ == Role::kServer && level == ssl_encryption_early_data) {
5974 ADD_FAILURE() << "Unexpected early data write secret";
5975 return false;
5976 }
5977
5978 if (cipher == nullptr) {
5979 ADD_FAILURE() << "Unexpected null cipher";
5980 return false;
5981 }
5982
5983 levels_[level].write_secret.assign(secret.begin(), secret.end());
Steven Valdez384d0ea2018-11-06 10:45:36 -05005984 levels_[level].cipher = SSL_CIPHER_get_id(cipher);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005985 return true;
5986 }
5987
5988 bool WriteHandshakeData(ssl_encryption_level_t level,
5989 Span<const uint8_t> data) {
5990 if (levels_[level].write_secret.empty()) {
David Benjamin1e859052020-02-09 16:04:58 -05005991 ADD_FAILURE() << LevelToString(level)
5992 << " write secret not yet configured";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005993 return false;
5994 }
David Benjamin5298ef92020-03-13 12:17:30 -04005995
5996 // Although the levels are conceptually separate, BoringSSL finishes writing
5997 // data from a previous level before installing keys for the next level.
5998 if (!allow_out_of_order_writes_) {
5999 switch (level) {
6000 case ssl_encryption_early_data:
6001 ADD_FAILURE() << "unexpected handshake data at early data level";
6002 return false;
6003 case ssl_encryption_initial:
6004 if (!levels_[ssl_encryption_handshake].write_secret.empty()) {
6005 ADD_FAILURE()
6006 << LevelToString(level)
6007 << " handshake data written after handshake keys installed";
6008 return false;
6009 }
6010 OPENSSL_FALLTHROUGH;
6011 case ssl_encryption_handshake:
6012 if (!levels_[ssl_encryption_application].write_secret.empty()) {
6013 ADD_FAILURE()
6014 << LevelToString(level)
6015 << " handshake data written after application keys installed";
6016 return false;
6017 }
6018 OPENSSL_FALLTHROUGH;
6019 case ssl_encryption_application:
6020 break;
6021 }
6022 }
6023
Steven Valdezc8e0f902018-07-14 11:23:01 -04006024 levels_[level].write_data.insert(levels_[level].write_data.end(),
6025 data.begin(), data.end());
6026 return true;
6027 }
6028
6029 bool SendAlert(ssl_encryption_level_t level, uint8_t alert_value) {
6030 if (has_alert_) {
6031 ADD_FAILURE() << "duplicate alert sent";
6032 return false;
6033 }
6034
6035 if (levels_[level].write_secret.empty()) {
David Benjamin1e859052020-02-09 16:04:58 -05006036 ADD_FAILURE() << LevelToString(level)
6037 << " write secret not yet configured";
Steven Valdezc8e0f902018-07-14 11:23:01 -04006038 return false;
6039 }
6040
6041 has_alert_ = true;
6042 alert_level_ = level;
6043 alert_ = alert_value;
6044 return true;
6045 }
6046
6047 bool ReadHandshakeData(std::vector<uint8_t> *out,
6048 ssl_encryption_level_t level,
6049 size_t num = std::numeric_limits<size_t>::max()) {
6050 if (levels_[level].read_secret.empty()) {
David Benjamind6343572019-08-15 17:29:02 -04006051 ADD_FAILURE() << "data read before keys configured in level " << level;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006052 return false;
6053 }
6054 // The peer may not have configured any keys yet.
6055 if (peer_->levels_[level].write_secret.empty()) {
David Benjamind0b97942019-08-21 12:54:20 -04006056 out->clear();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006057 return true;
6058 }
6059 // Check the peer computed the same key.
6060 if (peer_->levels_[level].write_secret != levels_[level].read_secret) {
David Benjamind6343572019-08-15 17:29:02 -04006061 ADD_FAILURE() << "peer write key does not match read key in level "
6062 << level;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006063 return false;
6064 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05006065 if (peer_->levels_[level].cipher != levels_[level].cipher) {
David Benjamind6343572019-08-15 17:29:02 -04006066 ADD_FAILURE() << "peer cipher does not match in level " << level;
Steven Valdez384d0ea2018-11-06 10:45:36 -05006067 return false;
6068 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04006069 std::vector<uint8_t> *peer_data = &peer_->levels_[level].write_data;
6070 num = std::min(num, peer_data->size());
6071 out->assign(peer_data->begin(), peer_data->begin() + num);
6072 peer_data->erase(peer_data->begin(), peer_data->begin() + num);
6073 return true;
6074 }
6075
6076 private:
David Benjamind6343572019-08-15 17:29:02 -04006077 Role role_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006078 MockQUICTransport *peer_ = nullptr;
6079
David Benjamin5298ef92020-03-13 12:17:30 -04006080 bool allow_out_of_order_writes_ = false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006081 bool has_alert_ = false;
6082 ssl_encryption_level_t alert_level_ = ssl_encryption_initial;
6083 uint8_t alert_ = 0;
6084
6085 struct Level {
6086 std::vector<uint8_t> write_data;
6087 std::vector<uint8_t> write_secret;
6088 std::vector<uint8_t> read_secret;
Steven Valdez384d0ea2018-11-06 10:45:36 -05006089 uint32_t cipher = 0;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006090 };
6091 Level levels_[kNumQUICLevels];
6092};
6093
6094class MockQUICTransportPair {
6095 public:
David Benjamind6343572019-08-15 17:29:02 -04006096 MockQUICTransportPair()
6097 : client_(MockQUICTransport::Role::kClient),
6098 server_(MockQUICTransport::Role::kServer) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04006099 client_.set_peer(&server_);
David Benjamind6343572019-08-15 17:29:02 -04006100 server_.set_peer(&client_);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006101 }
6102
6103 ~MockQUICTransportPair() {
Steven Valdezc8e0f902018-07-14 11:23:01 -04006104 client_.set_peer(nullptr);
David Benjamind6343572019-08-15 17:29:02 -04006105 server_.set_peer(nullptr);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006106 }
6107
6108 MockQUICTransport *client() { return &client_; }
6109 MockQUICTransport *server() { return &server_; }
6110
6111 bool SecretsMatch(ssl_encryption_level_t level) const {
David Benjamin1e859052020-02-09 16:04:58 -05006112 // We only need to check |HasReadSecret| and |HasWriteSecret| on |client_|.
6113 // |PeerSecretsMatch| checks that |server_| is analogously configured.
6114 return client_.PeerSecretsMatch(level) &&
6115 client_.HasWriteSecret(level) &&
6116 (level == ssl_encryption_early_data || client_.HasReadSecret(level));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006117 }
6118
6119 private:
6120 MockQUICTransport client_;
6121 MockQUICTransport server_;
6122};
6123
6124class QUICMethodTest : public testing::Test {
6125 protected:
6126 void SetUp() override {
6127 client_ctx_.reset(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04006128 server_ctx_ = CreateContextWithTestCertificate(TLS_method());
Steven Valdezc8e0f902018-07-14 11:23:01 -04006129 ASSERT_TRUE(client_ctx_);
6130 ASSERT_TRUE(server_ctx_);
6131
Steven Valdezc8e0f902018-07-14 11:23:01 -04006132 SSL_CTX_set_min_proto_version(server_ctx_.get(), TLS1_3_VERSION);
6133 SSL_CTX_set_max_proto_version(server_ctx_.get(), TLS1_3_VERSION);
6134 SSL_CTX_set_min_proto_version(client_ctx_.get(), TLS1_3_VERSION);
6135 SSL_CTX_set_max_proto_version(client_ctx_.get(), TLS1_3_VERSION);
Nick Harper74161f42020-07-24 15:35:27 -07006136
6137 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
6138 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
6139 sizeof(kALPNProtos)),
6140 0);
6141 SSL_CTX_set_alpn_select_cb(
6142 server_ctx_.get(),
6143 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
6144 unsigned in_len, void *arg) -> int {
6145 return SSL_select_next_proto(
6146 const_cast<uint8_t **>(out), out_len, in, in_len,
6147 kALPNProtos, sizeof(kALPNProtos)) == OPENSSL_NPN_NEGOTIATED
6148 ? SSL_TLSEXT_ERR_OK
6149 : SSL_TLSEXT_ERR_NOACK;
6150 },
6151 nullptr);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006152 }
6153
6154 static MockQUICTransport *TransportFromSSL(const SSL *ssl) {
6155 return ex_data_.Get(ssl);
6156 }
6157
6158 static bool ProvideHandshakeData(
6159 SSL *ssl, size_t num = std::numeric_limits<size_t>::max()) {
6160 MockQUICTransport *transport = TransportFromSSL(ssl);
6161 ssl_encryption_level_t level = SSL_quic_read_level(ssl);
6162 std::vector<uint8_t> data;
6163 return transport->ReadHandshakeData(&data, level, num) &&
6164 SSL_provide_quic_data(ssl, level, data.data(), data.size());
6165 }
6166
David Benjamin5298ef92020-03-13 12:17:30 -04006167 void AllowOutOfOrderWrites() {
6168 allow_out_of_order_writes_ = true;
6169 }
6170
Steven Valdezc8e0f902018-07-14 11:23:01 -04006171 bool CreateClientAndServer() {
6172 client_.reset(SSL_new(client_ctx_.get()));
6173 server_.reset(SSL_new(server_ctx_.get()));
6174 if (!client_ || !server_) {
6175 return false;
6176 }
6177
6178 SSL_set_connect_state(client_.get());
6179 SSL_set_accept_state(server_.get());
6180
David Benjamind6343572019-08-15 17:29:02 -04006181 transport_.reset(new MockQUICTransportPair);
6182 ex_data_.Set(client_.get(), transport_->client());
6183 ex_data_.Set(server_.get(), transport_->server());
David Benjamin5298ef92020-03-13 12:17:30 -04006184 if (allow_out_of_order_writes_) {
6185 transport_->client()->AllowOutOfOrderWrites();
6186 transport_->server()->AllowOutOfOrderWrites();
6187 }
Nick Harper7c522992020-04-30 14:15:49 -07006188 static const uint8_t client_transport_params[] = {0};
6189 if (!SSL_set_quic_transport_params(client_.get(), client_transport_params,
6190 sizeof(client_transport_params)) ||
6191 !SSL_set_quic_transport_params(server_.get(),
6192 server_transport_params_.data(),
6193 server_transport_params_.size()) ||
6194 !SSL_set_quic_early_data_context(
6195 server_.get(), server_quic_early_data_context_.data(),
6196 server_quic_early_data_context_.size())) {
Nick Harper72cff812020-03-26 18:06:16 -07006197 return false;
6198 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04006199 return true;
6200 }
6201
Nick Harper72cff812020-03-26 18:06:16 -07006202 enum class ExpectedError {
6203 kNoError,
6204 kClientError,
6205 kServerError,
6206 };
6207
David Benjamind6343572019-08-15 17:29:02 -04006208 // CompleteHandshakesForQUIC runs |SSL_do_handshake| on |client_| and
6209 // |server_| until each completes once. It returns true on success and false
6210 // on failure.
6211 bool CompleteHandshakesForQUIC() {
Nick Harper72cff812020-03-26 18:06:16 -07006212 return RunQUICHandshakesAndExpectError(ExpectedError::kNoError);
6213 }
6214
6215 // Runs |SSL_do_handshake| on |client_| and |server_| until each completes
6216 // once. If |expect_client_error| is true, it will return true only if the
6217 // client handshake failed. Otherwise, it returns true if both handshakes
6218 // succeed and false otherwise.
6219 bool RunQUICHandshakesAndExpectError(ExpectedError expected_error) {
David Benjamind6343572019-08-15 17:29:02 -04006220 bool client_done = false, server_done = false;
6221 while (!client_done || !server_done) {
6222 if (!client_done) {
6223 if (!ProvideHandshakeData(client_.get())) {
6224 ADD_FAILURE() << "ProvideHandshakeData(client_) failed";
6225 return false;
6226 }
6227 int client_ret = SSL_do_handshake(client_.get());
David Benjamin2fb729d2020-02-20 17:37:33 -05006228 int client_err = SSL_get_error(client_.get(), client_ret);
David Benjamind6343572019-08-15 17:29:02 -04006229 if (client_ret == 1) {
6230 client_done = true;
David Benjamin2fb729d2020-02-20 17:37:33 -05006231 } else if (client_ret != -1 || client_err != SSL_ERROR_WANT_READ) {
Nick Harper72cff812020-03-26 18:06:16 -07006232 if (expected_error == ExpectedError::kClientError) {
6233 return true;
6234 }
David Benjamin2fb729d2020-02-20 17:37:33 -05006235 ADD_FAILURE() << "Unexpected client output: " << client_ret << " "
6236 << client_err;
6237 return false;
David Benjamind6343572019-08-15 17:29:02 -04006238 }
6239 }
6240
6241 if (!server_done) {
6242 if (!ProvideHandshakeData(server_.get())) {
6243 ADD_FAILURE() << "ProvideHandshakeData(server_) failed";
6244 return false;
6245 }
6246 int server_ret = SSL_do_handshake(server_.get());
David Benjamin2fb729d2020-02-20 17:37:33 -05006247 int server_err = SSL_get_error(server_.get(), server_ret);
David Benjamind6343572019-08-15 17:29:02 -04006248 if (server_ret == 1) {
6249 server_done = true;
David Benjamin2fb729d2020-02-20 17:37:33 -05006250 } else if (server_ret != -1 || server_err != SSL_ERROR_WANT_READ) {
Nick Harper72cff812020-03-26 18:06:16 -07006251 if (expected_error == ExpectedError::kServerError) {
6252 return true;
6253 }
David Benjamin2fb729d2020-02-20 17:37:33 -05006254 ADD_FAILURE() << "Unexpected server output: " << server_ret << " "
6255 << server_err;
6256 return false;
David Benjamind6343572019-08-15 17:29:02 -04006257 }
6258 }
6259 }
Nick Harper72cff812020-03-26 18:06:16 -07006260 return expected_error == ExpectedError::kNoError;
David Benjamind6343572019-08-15 17:29:02 -04006261 }
6262
6263 bssl::UniquePtr<SSL_SESSION> CreateClientSessionForQUIC() {
6264 g_last_session = nullptr;
6265 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6266 if (!CreateClientAndServer() ||
6267 !CompleteHandshakesForQUIC()) {
6268 return nullptr;
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006269 }
6270
David Benjamind6343572019-08-15 17:29:02 -04006271 // The server sent NewSessionTicket messages in the handshake.
6272 if (!ProvideHandshakeData(client_.get()) ||
6273 !SSL_process_quic_post_handshake(client_.get())) {
6274 return nullptr;
6275 }
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006276
David Benjamind6343572019-08-15 17:29:02 -04006277 return std::move(g_last_session);
6278 }
6279
6280 void ExpectHandshakeSuccess() {
6281 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_application));
6282 EXPECT_EQ(ssl_encryption_application, SSL_quic_read_level(client_.get()));
6283 EXPECT_EQ(ssl_encryption_application, SSL_quic_write_level(client_.get()));
6284 EXPECT_EQ(ssl_encryption_application, SSL_quic_read_level(server_.get()));
6285 EXPECT_EQ(ssl_encryption_application, SSL_quic_write_level(server_.get()));
6286 EXPECT_FALSE(transport_->client()->has_alert());
6287 EXPECT_FALSE(transport_->server()->has_alert());
6288
6289 // SSL_do_handshake is now idempotent.
6290 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
6291 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006292 }
6293
David Benjamin1e859052020-02-09 16:04:58 -05006294 // Returns a default SSL_QUIC_METHOD. Individual methods may be overwritten by
6295 // the test.
6296 SSL_QUIC_METHOD DefaultQUICMethod() {
6297 return SSL_QUIC_METHOD{
6298 SetReadSecretCallback, SetWriteSecretCallback, AddHandshakeDataCallback,
6299 FlushFlightCallback, SendAlertCallback,
6300 };
6301 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04006302
David Benjamin1e859052020-02-09 16:04:58 -05006303 static int SetReadSecretCallback(SSL *ssl, ssl_encryption_level_t level,
6304 const SSL_CIPHER *cipher,
6305 const uint8_t *secret, size_t secret_len) {
6306 return TransportFromSSL(ssl)->SetReadSecret(
6307 level, cipher, MakeConstSpan(secret, secret_len));
6308 }
6309
6310 static int SetWriteSecretCallback(SSL *ssl, ssl_encryption_level_t level,
6311 const SSL_CIPHER *cipher,
6312 const uint8_t *secret, size_t secret_len) {
6313 return TransportFromSSL(ssl)->SetWriteSecret(
6314 level, cipher, MakeConstSpan(secret, secret_len));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006315 }
6316
David Benjamincc9d9352018-10-30 19:45:22 -05006317 static int AddHandshakeDataCallback(SSL *ssl,
6318 enum ssl_encryption_level_t level,
6319 const uint8_t *data, size_t len) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04006320 EXPECT_EQ(level, SSL_quic_write_level(ssl));
6321 return TransportFromSSL(ssl)->WriteHandshakeData(level,
6322 MakeConstSpan(data, len));
6323 }
6324
6325 static int FlushFlightCallback(SSL *ssl) { return 1; }
6326
6327 static int SendAlertCallback(SSL *ssl, ssl_encryption_level_t level,
6328 uint8_t alert) {
6329 EXPECT_EQ(level, SSL_quic_write_level(ssl));
6330 return TransportFromSSL(ssl)->SendAlert(level, alert);
6331 }
6332
6333 bssl::UniquePtr<SSL_CTX> client_ctx_;
6334 bssl::UniquePtr<SSL_CTX> server_ctx_;
6335
6336 static UnownedSSLExData<MockQUICTransport> ex_data_;
David Benjamind6343572019-08-15 17:29:02 -04006337 std::unique_ptr<MockQUICTransportPair> transport_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006338
6339 bssl::UniquePtr<SSL> client_;
6340 bssl::UniquePtr<SSL> server_;
David Benjamin5298ef92020-03-13 12:17:30 -04006341
Nick Harper7c522992020-04-30 14:15:49 -07006342 std::vector<uint8_t> server_transport_params_ = {1};
6343 std::vector<uint8_t> server_quic_early_data_context_ = {2};
6344
David Benjamin5298ef92020-03-13 12:17:30 -04006345 bool allow_out_of_order_writes_ = false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006346};
6347
6348UnownedSSLExData<MockQUICTransport> QUICMethodTest::ex_data_;
6349
David Benjaminfd863b62019-07-25 13:51:32 -04006350// Test a full handshake and resumption work.
Steven Valdezc8e0f902018-07-14 11:23:01 -04006351TEST_F(QUICMethodTest, Basic) {
David Benjamin1e859052020-02-09 16:04:58 -05006352 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006353
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006354 g_last_session = nullptr;
6355
6356 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6357 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006358 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6359 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
David Benjamind6343572019-08-15 17:29:02 -04006360
Steven Valdezc8e0f902018-07-14 11:23:01 -04006361 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04006362 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdezc8e0f902018-07-14 11:23:01 -04006363
David Benjamind6343572019-08-15 17:29:02 -04006364 ExpectHandshakeSuccess();
6365 EXPECT_FALSE(SSL_session_reused(client_.get()));
6366 EXPECT_FALSE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006367
6368 // The server sent NewSessionTicket messages in the handshake.
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006369 EXPECT_FALSE(g_last_session);
6370 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6371 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
6372 EXPECT_TRUE(g_last_session);
6373
6374 // Create a second connection to verify resumption works.
David Benjamind6343572019-08-15 17:29:02 -04006375 ASSERT_TRUE(CreateClientAndServer());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006376 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
6377 SSL_set_session(client_.get(), session.get());
6378
David Benjamind6343572019-08-15 17:29:02 -04006379 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006380
David Benjamind6343572019-08-15 17:29:02 -04006381 ExpectHandshakeSuccess();
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006382 EXPECT_TRUE(SSL_session_reused(client_.get()));
6383 EXPECT_TRUE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006384}
6385
David Benjaminfd863b62019-07-25 13:51:32 -04006386// Test that HelloRetryRequest in QUIC works.
6387TEST_F(QUICMethodTest, HelloRetryRequest) {
David Benjamin1e859052020-02-09 16:04:58 -05006388 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjaminfd863b62019-07-25 13:51:32 -04006389
6390 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6391 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6392
6393 // BoringSSL predicts the most preferred curve, so using different preferences
6394 // will trigger HelloRetryRequest.
6395 static const int kClientPrefs[] = {NID_X25519, NID_X9_62_prime256v1};
6396 ASSERT_TRUE(SSL_CTX_set1_curves(client_ctx_.get(), kClientPrefs,
6397 OPENSSL_ARRAY_SIZE(kClientPrefs)));
6398 static const int kServerPrefs[] = {NID_X9_62_prime256v1, NID_X25519};
6399 ASSERT_TRUE(SSL_CTX_set1_curves(server_ctx_.get(), kServerPrefs,
6400 OPENSSL_ARRAY_SIZE(kServerPrefs)));
6401
6402 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04006403 ASSERT_TRUE(CompleteHandshakesForQUIC());
6404 ExpectHandshakeSuccess();
6405}
David Benjaminfd863b62019-07-25 13:51:32 -04006406
Nick Harpere32549e2020-05-06 14:27:11 -07006407// Test that the client does not send a legacy_session_id in the ClientHello.
6408TEST_F(QUICMethodTest, NoLegacySessionId) {
6409 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6410
6411 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6412 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6413 // Check that the session ID length is 0 in an early callback.
6414 SSL_CTX_set_select_certificate_cb(
6415 server_ctx_.get(),
6416 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
6417 EXPECT_EQ(client_hello->session_id_len, 0u);
6418 return ssl_select_cert_success;
6419 });
6420
6421 ASSERT_TRUE(CreateClientAndServer());
6422 ASSERT_TRUE(CompleteHandshakesForQUIC());
6423
6424 ExpectHandshakeSuccess();
6425}
6426
David Benjamin1e859052020-02-09 16:04:58 -05006427// Test that, even in a 1-RTT handshake, the server installs keys at the right
6428// time. Half-RTT keys are available early, but 1-RTT read keys are deferred.
6429TEST_F(QUICMethodTest, HalfRTTKeys) {
6430 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6431
6432 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6433 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6434 ASSERT_TRUE(CreateClientAndServer());
6435
6436 // The client sends ClientHello.
6437 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6438 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client_.get(), -1));
6439
6440 // The server reads ClientHello and sends ServerHello..Finished.
6441 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6442 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6443 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
6444
6445 // At this point, the server has half-RTT write keys, but it cannot access
6446 // 1-RTT read keys until client Finished.
6447 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
6448 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
6449
6450 // Finish up the client and server handshakes.
6451 ASSERT_TRUE(CompleteHandshakesForQUIC());
6452
6453 // Both sides can now exchange 1-RTT data.
6454 ExpectHandshakeSuccess();
6455}
6456
David Benjamind6343572019-08-15 17:29:02 -04006457TEST_F(QUICMethodTest, ZeroRTTAccept) {
David Benjamin1e859052020-02-09 16:04:58 -05006458 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjamind6343572019-08-15 17:29:02 -04006459
6460 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6461 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6462 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6463 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6464 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6465
6466 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6467 ASSERT_TRUE(session);
6468
6469 ASSERT_TRUE(CreateClientAndServer());
6470 SSL_set_session(client_.get(), session.get());
6471
6472 // The client handshake should return immediately into the early data state.
6473 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6474 EXPECT_TRUE(SSL_in_early_data(client_.get()));
6475 // The transport should have keys for sending 0-RTT data.
David Benjamin1e859052020-02-09 16:04:58 -05006476 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04006477
6478 // The server will consume the ClientHello and also enter the early data
6479 // state.
6480 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6481 ASSERT_EQ(SSL_do_handshake(server_.get()), 1);
6482 EXPECT_TRUE(SSL_in_early_data(server_.get()));
6483 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_early_data));
David Benjamin1e859052020-02-09 16:04:58 -05006484 // At this point, the server has half-RTT write keys, but it cannot access
6485 // 1-RTT read keys until client Finished.
6486 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
6487 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
David Benjamind6343572019-08-15 17:29:02 -04006488
6489 // Finish up the client and server handshakes.
6490 ASSERT_TRUE(CompleteHandshakesForQUIC());
6491
6492 // Both sides can now exchange 1-RTT data.
6493 ExpectHandshakeSuccess();
6494 EXPECT_TRUE(SSL_session_reused(client_.get()));
6495 EXPECT_TRUE(SSL_session_reused(server_.get()));
6496 EXPECT_FALSE(SSL_in_early_data(client_.get()));
6497 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6498 EXPECT_TRUE(SSL_early_data_accepted(client_.get()));
6499 EXPECT_TRUE(SSL_early_data_accepted(server_.get()));
Nick Harper5e086952020-09-30 13:59:14 -07006500
6501 // Finish handling post-handshake messages after the first 0-RTT resumption.
6502 EXPECT_TRUE(ProvideHandshakeData(client_.get()));
6503 EXPECT_TRUE(SSL_process_quic_post_handshake(client_.get()));
6504
6505 // Perform a second 0-RTT resumption attempt, and confirm that 0-RTT is
6506 // accepted again.
6507 ASSERT_TRUE(CreateClientAndServer());
6508 SSL_set_session(client_.get(), g_last_session.get());
6509
6510 // The client handshake should return immediately into the early data state.
6511 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6512 EXPECT_TRUE(SSL_in_early_data(client_.get()));
6513 // The transport should have keys for sending 0-RTT data.
6514 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
6515
6516 // The server will consume the ClientHello and also enter the early data
6517 // state.
6518 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6519 ASSERT_EQ(SSL_do_handshake(server_.get()), 1);
6520 EXPECT_TRUE(SSL_in_early_data(server_.get()));
6521 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_early_data));
6522 // At this point, the server has half-RTT write keys, but it cannot access
6523 // 1-RTT read keys until client Finished.
6524 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
6525 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
6526
6527 // Finish up the client and server handshakes.
6528 ASSERT_TRUE(CompleteHandshakesForQUIC());
6529
6530 // Both sides can now exchange 1-RTT data.
6531 ExpectHandshakeSuccess();
6532 EXPECT_TRUE(SSL_session_reused(client_.get()));
6533 EXPECT_TRUE(SSL_session_reused(server_.get()));
6534 EXPECT_FALSE(SSL_in_early_data(client_.get()));
6535 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6536 EXPECT_TRUE(SSL_early_data_accepted(client_.get()));
6537 EXPECT_TRUE(SSL_early_data_accepted(server_.get()));
6538 EXPECT_EQ(SSL_get_early_data_reason(client_.get()), ssl_early_data_accepted);
6539 EXPECT_EQ(SSL_get_early_data_reason(server_.get()), ssl_early_data_accepted);
David Benjamind6343572019-08-15 17:29:02 -04006540}
6541
Nick Harper7c522992020-04-30 14:15:49 -07006542TEST_F(QUICMethodTest, ZeroRTTRejectMismatchedParameters) {
6543 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6544
6545 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6546 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6547 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6548 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6549 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6550
6551
6552 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6553 ASSERT_TRUE(session);
6554
Nick Harper85194322020-05-20 16:59:29 -07006555 ASSERT_TRUE(CreateClientAndServer());
6556 static const uint8_t new_context[] = {4};
6557 ASSERT_TRUE(SSL_set_quic_early_data_context(server_.get(), new_context,
6558 sizeof(new_context)));
6559 SSL_set_session(client_.get(), session.get());
Nick Harper7c522992020-04-30 14:15:49 -07006560
Nick Harper85194322020-05-20 16:59:29 -07006561 // The client handshake should return immediately into the early data
6562 // state.
6563 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6564 EXPECT_TRUE(SSL_in_early_data(client_.get()));
6565 // The transport should have keys for sending 0-RTT data.
6566 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
Nick Harper7c522992020-04-30 14:15:49 -07006567
Nick Harper85194322020-05-20 16:59:29 -07006568 // The server will consume the ClientHello, but it will not accept 0-RTT.
6569 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6570 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6571 EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
6572 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6573 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_early_data));
Nick Harper7c522992020-04-30 14:15:49 -07006574
Nick Harper85194322020-05-20 16:59:29 -07006575 // The client consumes the server response and signals 0-RTT rejection.
6576 for (;;) {
6577 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6578 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
6579 int err = SSL_get_error(client_.get(), -1);
6580 if (err == SSL_ERROR_EARLY_DATA_REJECTED) {
6581 break;
Nick Harper7c522992020-04-30 14:15:49 -07006582 }
Nick Harper85194322020-05-20 16:59:29 -07006583 ASSERT_EQ(SSL_ERROR_WANT_READ, err);
Nick Harper7c522992020-04-30 14:15:49 -07006584 }
Nick Harper85194322020-05-20 16:59:29 -07006585
6586 // As in TLS over TCP, 0-RTT rejection is sticky.
6587 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
6588 ASSERT_EQ(SSL_ERROR_EARLY_DATA_REJECTED, SSL_get_error(client_.get(), -1));
6589
6590 // Finish up the client and server handshakes.
6591 SSL_reset_early_data_reject(client_.get());
6592 ASSERT_TRUE(CompleteHandshakesForQUIC());
6593
6594 // Both sides can now exchange 1-RTT data.
6595 ExpectHandshakeSuccess();
6596 EXPECT_TRUE(SSL_session_reused(client_.get()));
6597 EXPECT_TRUE(SSL_session_reused(server_.get()));
6598 EXPECT_FALSE(SSL_in_early_data(client_.get()));
6599 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6600 EXPECT_FALSE(SSL_early_data_accepted(client_.get()));
6601 EXPECT_FALSE(SSL_early_data_accepted(server_.get()));
6602}
6603
6604TEST_F(QUICMethodTest, NoZeroRTTTicketWithoutEarlyDataContext) {
6605 server_quic_early_data_context_ = {};
6606 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6607
6608 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6609 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6610 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6611 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6612 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6613
6614 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6615 ASSERT_TRUE(session);
6616 EXPECT_FALSE(SSL_SESSION_early_data_capable(session.get()));
Nick Harper7c522992020-04-30 14:15:49 -07006617}
6618
David Benjamind6343572019-08-15 17:29:02 -04006619TEST_F(QUICMethodTest, ZeroRTTReject) {
David Benjamin1e859052020-02-09 16:04:58 -05006620 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjamind6343572019-08-15 17:29:02 -04006621
6622 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6623 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6624 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6625 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6626 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6627
6628 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6629 ASSERT_TRUE(session);
6630
6631 for (bool reject_hrr : {false, true}) {
6632 SCOPED_TRACE(reject_hrr);
6633
6634 ASSERT_TRUE(CreateClientAndServer());
6635 if (reject_hrr) {
6636 // Configure the server to prefer P-256, which will reject 0-RTT via
6637 // HelloRetryRequest.
6638 int p256 = NID_X9_62_prime256v1;
6639 ASSERT_TRUE(SSL_set1_curves(server_.get(), &p256, 1));
6640 } else {
6641 // Disable 0-RTT on the server, so it will reject it.
6642 SSL_set_early_data_enabled(server_.get(), 0);
David Benjaminfd863b62019-07-25 13:51:32 -04006643 }
David Benjamind6343572019-08-15 17:29:02 -04006644 SSL_set_session(client_.get(), session.get());
David Benjaminfd863b62019-07-25 13:51:32 -04006645
David Benjamind6343572019-08-15 17:29:02 -04006646 // The client handshake should return immediately into the early data state.
6647 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6648 EXPECT_TRUE(SSL_in_early_data(client_.get()));
6649 // The transport should have keys for sending 0-RTT data.
David Benjamin1e859052020-02-09 16:04:58 -05006650 EXPECT_TRUE(
6651 transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04006652
6653 // The server will consume the ClientHello, but it will not accept 0-RTT.
David Benjaminfd863b62019-07-25 13:51:32 -04006654 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
David Benjamind6343572019-08-15 17:29:02 -04006655 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6656 EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
6657 EXPECT_FALSE(SSL_in_early_data(server_.get()));
David Benjamin1e859052020-02-09 16:04:58 -05006658 EXPECT_FALSE(
6659 transport_->server()->HasReadSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04006660
6661 // The client consumes the server response and signals 0-RTT rejection.
6662 for (;;) {
6663 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6664 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
6665 int err = SSL_get_error(client_.get(), -1);
6666 if (err == SSL_ERROR_EARLY_DATA_REJECTED) {
6667 break;
6668 }
6669 ASSERT_EQ(SSL_ERROR_WANT_READ, err);
David Benjaminfd863b62019-07-25 13:51:32 -04006670 }
6671
David Benjamind6343572019-08-15 17:29:02 -04006672 // As in TLS over TCP, 0-RTT rejection is sticky.
6673 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
6674 ASSERT_EQ(SSL_ERROR_EARLY_DATA_REJECTED, SSL_get_error(client_.get(), -1));
6675
6676 // Finish up the client and server handshakes.
6677 SSL_reset_early_data_reject(client_.get());
6678 ASSERT_TRUE(CompleteHandshakesForQUIC());
6679
6680 // Both sides can now exchange 1-RTT data.
6681 ExpectHandshakeSuccess();
6682 EXPECT_TRUE(SSL_session_reused(client_.get()));
6683 EXPECT_TRUE(SSL_session_reused(server_.get()));
6684 EXPECT_FALSE(SSL_in_early_data(client_.get()));
6685 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6686 EXPECT_FALSE(SSL_early_data_accepted(client_.get()));
6687 EXPECT_FALSE(SSL_early_data_accepted(server_.get()));
David Benjaminfd863b62019-07-25 13:51:32 -04006688 }
David Benjaminfd863b62019-07-25 13:51:32 -04006689}
6690
David Benjaminee0716f2019-11-19 14:16:28 +08006691TEST_F(QUICMethodTest, NoZeroRTTKeysBeforeReverify) {
David Benjamin1e859052020-02-09 16:04:58 -05006692 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjaminee0716f2019-11-19 14:16:28 +08006693
6694 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6695 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6696 SSL_CTX_set_reverify_on_resume(client_ctx_.get(), 1);
6697 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
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
6701 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6702 ASSERT_TRUE(session);
6703
6704 ASSERT_TRUE(CreateClientAndServer());
6705 SSL_set_session(client_.get(), session.get());
6706
6707 // Configure the certificate (re)verification to never complete. The client
6708 // handshake should pause.
6709 SSL_set_custom_verify(
6710 client_.get(), SSL_VERIFY_PEER,
6711 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
6712 return ssl_verify_retry;
6713 });
6714 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6715 ASSERT_EQ(SSL_get_error(client_.get(), -1),
6716 SSL_ERROR_WANT_CERTIFICATE_VERIFY);
6717
6718 // The early data keys have not yet been released.
David Benjamin1e859052020-02-09 16:04:58 -05006719 EXPECT_FALSE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjaminee0716f2019-11-19 14:16:28 +08006720
6721 // After the verification completes, the handshake progresses to the 0-RTT
6722 // point and releases keys.
6723 SSL_set_custom_verify(
6724 client_.get(), SSL_VERIFY_PEER,
6725 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
6726 return ssl_verify_ok;
6727 });
6728 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6729 EXPECT_TRUE(SSL_in_early_data(client_.get()));
David Benjamin1e859052020-02-09 16:04:58 -05006730 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjaminee0716f2019-11-19 14:16:28 +08006731}
6732
Steven Valdezc8e0f902018-07-14 11:23:01 -04006733// Test only releasing data to QUIC one byte at a time on request, to maximize
6734// state machine pauses. Additionally, test that existing asynchronous callbacks
6735// still work.
6736TEST_F(QUICMethodTest, Async) {
David Benjamin1e859052020-02-09 16:04:58 -05006737 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006738
6739 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6740 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6741 ASSERT_TRUE(CreateClientAndServer());
6742
6743 // Install an asynchronous certificate callback.
6744 bool cert_cb_ok = false;
6745 SSL_set_cert_cb(server_.get(),
6746 [](SSL *, void *arg) -> int {
6747 return *static_cast<bool *>(arg) ? 1 : -1;
6748 },
6749 &cert_cb_ok);
6750
6751 for (;;) {
6752 int client_ret = SSL_do_handshake(client_.get());
6753 if (client_ret != 1) {
6754 ASSERT_EQ(client_ret, -1);
6755 ASSERT_EQ(SSL_get_error(client_.get(), client_ret), SSL_ERROR_WANT_READ);
6756 ASSERT_TRUE(ProvideHandshakeData(client_.get(), 1));
6757 }
6758
6759 int server_ret = SSL_do_handshake(server_.get());
6760 if (server_ret != 1) {
6761 ASSERT_EQ(server_ret, -1);
6762 int ssl_err = SSL_get_error(server_.get(), server_ret);
6763 switch (ssl_err) {
6764 case SSL_ERROR_WANT_READ:
6765 ASSERT_TRUE(ProvideHandshakeData(server_.get(), 1));
6766 break;
6767 case SSL_ERROR_WANT_X509_LOOKUP:
6768 ASSERT_FALSE(cert_cb_ok);
6769 cert_cb_ok = true;
6770 break;
6771 default:
6772 FAIL() << "Unexpected SSL_get_error result: " << ssl_err;
6773 }
6774 }
6775
6776 if (client_ret == 1 && server_ret == 1) {
6777 break;
6778 }
6779 }
6780
David Benjamind6343572019-08-15 17:29:02 -04006781 ExpectHandshakeSuccess();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006782}
6783
6784// Test buffering write data until explicit flushes.
6785TEST_F(QUICMethodTest, Buffered) {
David Benjamin5298ef92020-03-13 12:17:30 -04006786 AllowOutOfOrderWrites();
6787
Steven Valdezc8e0f902018-07-14 11:23:01 -04006788 struct BufferedFlight {
6789 std::vector<uint8_t> data[kNumQUICLevels];
6790 };
6791 static UnownedSSLExData<BufferedFlight> buffered_flights;
6792
David Benjamincc9d9352018-10-30 19:45:22 -05006793 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
6794 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04006795 BufferedFlight *flight = buffered_flights.Get(ssl);
6796 flight->data[level].insert(flight->data[level].end(), data, data + len);
6797 return 1;
6798 };
6799
6800 auto flush_flight = [](SSL *ssl) -> int {
6801 BufferedFlight *flight = buffered_flights.Get(ssl);
6802 for (size_t level = 0; level < kNumQUICLevels; level++) {
6803 if (!flight->data[level].empty()) {
6804 if (!TransportFromSSL(ssl)->WriteHandshakeData(
6805 static_cast<ssl_encryption_level_t>(level),
6806 flight->data[level])) {
6807 return 0;
6808 }
6809 flight->data[level].clear();
6810 }
6811 }
6812 return 1;
6813 };
6814
David Benjamin1e859052020-02-09 16:04:58 -05006815 SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6816 quic_method.add_handshake_data = add_handshake_data;
6817 quic_method.flush_flight = flush_flight;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006818
6819 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6820 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6821 ASSERT_TRUE(CreateClientAndServer());
6822
6823 BufferedFlight client_flight, server_flight;
6824 buffered_flights.Set(client_.get(), &client_flight);
6825 buffered_flights.Set(server_.get(), &server_flight);
6826
David Benjamind6343572019-08-15 17:29:02 -04006827 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdezc8e0f902018-07-14 11:23:01 -04006828
David Benjamind6343572019-08-15 17:29:02 -04006829 ExpectHandshakeSuccess();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006830}
6831
6832// Test that excess data at one level is rejected. That is, if a single
6833// |SSL_provide_quic_data| call included both ServerHello and
6834// EncryptedExtensions in a single chunk, BoringSSL notices and rejects this on
6835// key change.
6836TEST_F(QUICMethodTest, ExcessProvidedData) {
David Benjamin5298ef92020-03-13 12:17:30 -04006837 AllowOutOfOrderWrites();
6838
David Benjamincc9d9352018-10-30 19:45:22 -05006839 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
6840 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04006841 // Switch everything to the initial level.
6842 return TransportFromSSL(ssl)->WriteHandshakeData(ssl_encryption_initial,
6843 MakeConstSpan(data, len));
6844 };
6845
David Benjamin1e859052020-02-09 16:04:58 -05006846 SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6847 quic_method.add_handshake_data = add_handshake_data;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006848
6849 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6850 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6851 ASSERT_TRUE(CreateClientAndServer());
6852
6853 // Send the ClientHello and ServerHello through Finished.
6854 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6855 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
6856 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6857 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6858 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
6859
6860 // The client is still waiting for the ServerHello at initial
6861 // encryption.
6862 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
6863
David Benjamincc9d9352018-10-30 19:45:22 -05006864 // |add_handshake_data| incorrectly wrote everything at the initial level, so
6865 // this queues up ServerHello through Finished in one chunk.
Steven Valdezc8e0f902018-07-14 11:23:01 -04006866 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6867
6868 // The client reads ServerHello successfully, but then rejects the buffered
6869 // EncryptedExtensions on key change.
6870 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6871 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_SSL);
6872 uint32_t err = ERR_get_error();
6873 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
David Benjaminf9cc26f2020-02-09 16:49:31 -05006874 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_EXCESS_HANDSHAKE_DATA);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006875
David Benjamin1e859052020-02-09 16:04:58 -05006876 // The client sends an alert in response to this. The alert is sent at
6877 // handshake level because we install write secrets before read secrets and
6878 // the error is discovered when installing the read secret. (How to send
6879 // alerts on protocol syntax errors near key changes is ambiguous in general.)
David Benjamind6343572019-08-15 17:29:02 -04006880 ASSERT_TRUE(transport_->client()->has_alert());
David Benjamin1e859052020-02-09 16:04:58 -05006881 EXPECT_EQ(transport_->client()->alert_level(), ssl_encryption_handshake);
David Benjamind6343572019-08-15 17:29:02 -04006882 EXPECT_EQ(transport_->client()->alert(), SSL_AD_UNEXPECTED_MESSAGE);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006883
David Benjamin5298ef92020-03-13 12:17:30 -04006884 // Sanity-check handshake secrets. The error is discovered while setting the
6885 // read secret, so only the write secret has been installed.
David Benjamin1e859052020-02-09 16:04:58 -05006886 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_handshake));
David Benjamin5298ef92020-03-13 12:17:30 -04006887 EXPECT_FALSE(transport_->client()->HasReadSecret(ssl_encryption_handshake));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006888}
6889
6890// Test that |SSL_provide_quic_data| will reject data at the wrong level.
6891TEST_F(QUICMethodTest, ProvideWrongLevel) {
David Benjamin1e859052020-02-09 16:04:58 -05006892 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006893
6894 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6895 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6896 ASSERT_TRUE(CreateClientAndServer());
6897
6898 // Send the ClientHello and ServerHello through Finished.
6899 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6900 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
6901 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6902 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6903 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
6904
6905 // The client is still waiting for the ServerHello at initial
6906 // encryption.
6907 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
6908
6909 // Data cannot be provided at the next level.
6910 std::vector<uint8_t> data;
6911 ASSERT_TRUE(
David Benjamind6343572019-08-15 17:29:02 -04006912 transport_->client()->ReadHandshakeData(&data, ssl_encryption_initial));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006913 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_handshake,
6914 data.data(), data.size()));
6915 ERR_clear_error();
6916
6917 // Progress to EncryptedExtensions.
6918 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
6919 data.data(), data.size()));
6920 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6921 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
6922 ASSERT_EQ(ssl_encryption_handshake, SSL_quic_read_level(client_.get()));
6923
6924 // Data cannot be provided at the previous level.
6925 ASSERT_TRUE(
David Benjamind6343572019-08-15 17:29:02 -04006926 transport_->client()->ReadHandshakeData(&data, ssl_encryption_handshake));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006927 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
6928 data.data(), data.size()));
6929}
6930
6931TEST_F(QUICMethodTest, TooMuchData) {
David Benjamin1e859052020-02-09 16:04:58 -05006932 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006933
6934 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6935 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6936 ASSERT_TRUE(CreateClientAndServer());
6937
6938 size_t limit =
6939 SSL_quic_max_handshake_flight_len(client_.get(), ssl_encryption_initial);
6940 uint8_t b = 0;
6941 for (size_t i = 0; i < limit; i++) {
6942 ASSERT_TRUE(
6943 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
6944 }
6945
6946 EXPECT_FALSE(
6947 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
6948}
6949
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006950// Provide invalid post-handshake data.
6951TEST_F(QUICMethodTest, BadPostHandshake) {
David Benjamin1e859052020-02-09 16:04:58 -05006952 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006953
6954 g_last_session = nullptr;
6955
6956 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6957 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6958 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6959 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6960 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04006961 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006962
6963 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
6964 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
David Benjamind6343572019-08-15 17:29:02 -04006965 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_application));
6966 EXPECT_FALSE(transport_->client()->has_alert());
6967 EXPECT_FALSE(transport_->server()->has_alert());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006968
6969 // Junk sent as part of post-handshake data should cause an error.
6970 uint8_t kJunk[] = {0x17, 0x0, 0x0, 0x4, 0xB, 0xE, 0xE, 0xF};
6971 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_application,
6972 kJunk, sizeof(kJunk)));
6973 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 0);
6974}
6975
Nick Harper80ddfc72020-03-11 18:26:31 -07006976static void ExpectReceivedTransportParamsEqual(const SSL *ssl,
6977 Span<const uint8_t> expected) {
6978 const uint8_t *received;
6979 size_t received_len;
6980 SSL_get_peer_quic_transport_params(ssl, &received, &received_len);
6981 ASSERT_EQ(received_len, expected.size());
6982 EXPECT_EQ(Bytes(received, received_len), Bytes(expected));
6983}
6984
6985TEST_F(QUICMethodTest, SetTransportParameters) {
6986 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6987 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6988 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6989
6990 ASSERT_TRUE(CreateClientAndServer());
6991 uint8_t kClientParams[] = {1, 2, 3, 4};
6992 uint8_t kServerParams[] = {5, 6, 7};
6993 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6994 sizeof(kClientParams)));
6995 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6996 sizeof(kServerParams)));
6997
6998 ASSERT_TRUE(CompleteHandshakesForQUIC());
6999 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
7000 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
7001}
7002
7003TEST_F(QUICMethodTest, SetTransportParamsInCallback) {
7004 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7005 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7006 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7007
7008 ASSERT_TRUE(CreateClientAndServer());
7009 uint8_t kClientParams[] = {1, 2, 3, 4};
7010 static uint8_t kServerParams[] = {5, 6, 7};
7011 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
7012 sizeof(kClientParams)));
7013 SSL_CTX_set_tlsext_servername_callback(
7014 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
7015 EXPECT_TRUE(SSL_set_quic_transport_params(ssl, kServerParams,
7016 sizeof(kServerParams)));
7017 return SSL_TLSEXT_ERR_OK;
7018 });
7019
7020 ASSERT_TRUE(CompleteHandshakesForQUIC());
7021 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
7022 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
7023}
7024
Nick Harper6bfd25c2020-03-30 17:15:19 -07007025TEST_F(QUICMethodTest, ForbidCrossProtocolResumptionClient) {
7026 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7027
7028 g_last_session = nullptr;
7029
7030 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7031 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
7032 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7033 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7034
7035 ASSERT_TRUE(CreateClientAndServer());
7036 ASSERT_TRUE(CompleteHandshakesForQUIC());
7037
7038 ExpectHandshakeSuccess();
7039 EXPECT_FALSE(SSL_session_reused(client_.get()));
7040 EXPECT_FALSE(SSL_session_reused(server_.get()));
7041
7042 // The server sent NewSessionTicket messages in the handshake.
7043 EXPECT_FALSE(g_last_session);
7044 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
7045 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
7046 EXPECT_TRUE(g_last_session);
7047
7048 // Pretend that g_last_session came from a TLS-over-TCP connection.
7049 g_last_session.get()->is_quic = false;
7050
7051 // Create a second connection and verify that resumption does not occur with
7052 // a session from a non-QUIC connection. This tests that the client does not
7053 // offer over QUIC a session believed to be received over TCP. The server
7054 // believes this is a QUIC session, so if the client offered the session, the
7055 // server would have resumed it.
7056 ASSERT_TRUE(CreateClientAndServer());
7057 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
7058 SSL_set_session(client_.get(), session.get());
7059
7060 ASSERT_TRUE(CompleteHandshakesForQUIC());
7061 ExpectHandshakeSuccess();
7062 EXPECT_FALSE(SSL_session_reused(client_.get()));
7063 EXPECT_FALSE(SSL_session_reused(server_.get()));
7064}
7065
7066TEST_F(QUICMethodTest, ForbidCrossProtocolResumptionServer) {
7067 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7068
7069 g_last_session = nullptr;
7070
7071 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7072 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
7073 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7074 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7075
7076 ASSERT_TRUE(CreateClientAndServer());
7077 ASSERT_TRUE(CompleteHandshakesForQUIC());
7078
7079 ExpectHandshakeSuccess();
7080 EXPECT_FALSE(SSL_session_reused(client_.get()));
7081 EXPECT_FALSE(SSL_session_reused(server_.get()));
7082
7083 // The server sent NewSessionTicket messages in the handshake.
7084 EXPECT_FALSE(g_last_session);
7085 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
7086 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
7087 EXPECT_TRUE(g_last_session);
7088
7089 // Attempt a resumption with g_last_session using TLS_method.
7090 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
7091 ASSERT_TRUE(client_ctx);
7092
7093 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), nullptr));
7094
7095 bssl::UniquePtr<SSL> client(SSL_new(client_ctx.get())),
7096 server(SSL_new(server_ctx_.get()));
7097 ASSERT_TRUE(client);
7098 ASSERT_TRUE(server);
7099 SSL_set_connect_state(client.get());
7100 SSL_set_accept_state(server.get());
7101
7102 // The TLS-over-TCP client will refuse to resume with a quic session, so
7103 // mark is_quic = false to bypass the client check to test the server check.
7104 g_last_session.get()->is_quic = false;
7105 SSL_set_session(client.get(), g_last_session.get());
7106
7107 BIO *bio1, *bio2;
7108 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
7109
7110 // SSL_set_bio takes ownership.
7111 SSL_set_bio(client.get(), bio1, bio1);
7112 SSL_set_bio(server.get(), bio2, bio2);
7113 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
7114
7115 EXPECT_FALSE(SSL_session_reused(client.get()));
7116 EXPECT_FALSE(SSL_session_reused(server.get()));
7117}
7118
Nick Harper72cff812020-03-26 18:06:16 -07007119TEST_F(QUICMethodTest, ClientRejectsMissingTransportParams) {
7120 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7121 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7122 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7123
7124 ASSERT_TRUE(CreateClientAndServer());
7125 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), nullptr, 0));
7126 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
7127}
7128
7129TEST_F(QUICMethodTest, ServerRejectsMissingTransportParams) {
7130 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7131 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7132 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7133
7134 ASSERT_TRUE(CreateClientAndServer());
7135 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), nullptr, 0));
7136 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kClientError));
7137}
7138
David Schinazi3d8b8c32021-01-14 11:25:49 -08007139TEST_F(QUICMethodTest, QuicLegacyCodepointEnabled) {
7140 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7141 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7142 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7143
7144 ASSERT_TRUE(CreateClientAndServer());
7145 uint8_t kClientParams[] = {1, 2, 3, 4};
7146 uint8_t kServerParams[] = {5, 6, 7};
7147 SSL_set_quic_use_legacy_codepoint(client_.get(), 1);
7148 SSL_set_quic_use_legacy_codepoint(server_.get(), 1);
7149 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
7150 sizeof(kClientParams)));
7151 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
7152 sizeof(kServerParams)));
7153
7154 ASSERT_TRUE(CompleteHandshakesForQUIC());
7155 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
7156 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
7157}
7158
7159TEST_F(QUICMethodTest, QuicLegacyCodepointDisabled) {
7160 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7161 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7162 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7163
7164 ASSERT_TRUE(CreateClientAndServer());
7165 uint8_t kClientParams[] = {1, 2, 3, 4};
7166 uint8_t kServerParams[] = {5, 6, 7};
7167 SSL_set_quic_use_legacy_codepoint(client_.get(), 0);
7168 SSL_set_quic_use_legacy_codepoint(server_.get(), 0);
7169 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
7170 sizeof(kClientParams)));
7171 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
7172 sizeof(kServerParams)));
7173
7174 ASSERT_TRUE(CompleteHandshakesForQUIC());
7175 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
7176 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
7177}
7178
7179TEST_F(QUICMethodTest, QuicLegacyCodepointClientOnly) {
7180 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7181 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7182 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7183
7184 ASSERT_TRUE(CreateClientAndServer());
7185 uint8_t kClientParams[] = {1, 2, 3, 4};
7186 uint8_t kServerParams[] = {5, 6, 7};
7187 SSL_set_quic_use_legacy_codepoint(client_.get(), 1);
7188 SSL_set_quic_use_legacy_codepoint(server_.get(), 0);
7189 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
7190 sizeof(kClientParams)));
7191 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
7192 sizeof(kServerParams)));
7193
7194 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
7195}
7196
7197TEST_F(QUICMethodTest, QuicLegacyCodepointServerOnly) {
7198 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7199 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7200 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7201
7202 ASSERT_TRUE(CreateClientAndServer());
7203 uint8_t kClientParams[] = {1, 2, 3, 4};
7204 uint8_t kServerParams[] = {5, 6, 7};
7205 SSL_set_quic_use_legacy_codepoint(client_.get(), 0);
7206 SSL_set_quic_use_legacy_codepoint(server_.get(), 1);
7207 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
7208 sizeof(kClientParams)));
7209 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
7210 sizeof(kServerParams)));
7211
7212 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
7213}
7214
David Benjaminc47bfce2021-01-20 17:10:32 -05007215// Test that the default QUIC code point is consistent with
7216// |TLSEXT_TYPE_quic_transport_parameters|. This test ensures we remember to
7217// update the two values together.
7218TEST_F(QUICMethodTest, QuicCodePointDefault) {
7219 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7220 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7221 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7222 SSL_CTX_set_select_certificate_cb(
7223 server_ctx_.get(),
7224 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
7225 const uint8_t *data;
7226 size_t len;
7227 if (!SSL_early_callback_ctx_extension_get(
7228 client_hello, TLSEXT_TYPE_quic_transport_parameters, &data,
7229 &len)) {
7230 ADD_FAILURE() << "Could not find quic_transport_parameters extension";
7231 return ssl_select_cert_error;
7232 }
7233 return ssl_select_cert_success;
7234 });
7235
7236 ASSERT_TRUE(CreateClientAndServer());
7237 ASSERT_TRUE(CompleteHandshakesForQUIC());
7238}
7239
Adam Langley7540cc22019-04-18 09:56:13 -07007240extern "C" {
7241int BORINGSSL_enum_c_type_test(void);
7242}
7243
7244TEST(SSLTest, EnumTypes) {
7245 EXPECT_EQ(sizeof(int), sizeof(ssl_private_key_result_t));
7246 EXPECT_EQ(1, BORINGSSL_enum_c_type_test());
7247}
7248
David Benjaminb29e1e12019-05-06 14:44:46 -05007249TEST_P(SSLVersionTest, DoubleSSLError) {
7250 // Connect the inner SSL connections.
7251 ASSERT_TRUE(Connect());
7252
7253 // Make a pair of |BIO|s which wrap |client_| and |server_|.
7254 UniquePtr<BIO_METHOD> bio_method(BIO_meth_new(0, nullptr));
7255 ASSERT_TRUE(bio_method);
7256 ASSERT_TRUE(BIO_meth_set_read(
7257 bio_method.get(), [](BIO *bio, char *out, int len) -> int {
7258 SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
7259 int ret = SSL_read(ssl, out, len);
7260 int ssl_ret = SSL_get_error(ssl, ret);
7261 if (ssl_ret == SSL_ERROR_WANT_READ) {
7262 BIO_set_retry_read(bio);
7263 }
7264 return ret;
7265 }));
7266 ASSERT_TRUE(BIO_meth_set_write(
7267 bio_method.get(), [](BIO *bio, const char *in, int len) -> int {
7268 SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
7269 int ret = SSL_write(ssl, in, len);
7270 int ssl_ret = SSL_get_error(ssl, ret);
7271 if (ssl_ret == SSL_ERROR_WANT_WRITE) {
7272 BIO_set_retry_write(bio);
7273 }
7274 return ret;
7275 }));
7276 ASSERT_TRUE(BIO_meth_set_ctrl(
7277 bio_method.get(), [](BIO *bio, int cmd, long larg, void *parg) -> long {
7278 // |SSL| objects require |BIO_flush| support.
7279 if (cmd == BIO_CTRL_FLUSH) {
7280 return 1;
7281 }
7282 return 0;
7283 }));
7284
7285 UniquePtr<BIO> client_bio(BIO_new(bio_method.get()));
7286 ASSERT_TRUE(client_bio);
7287 BIO_set_data(client_bio.get(), client_.get());
7288 BIO_set_init(client_bio.get(), 1);
7289
7290 UniquePtr<BIO> server_bio(BIO_new(bio_method.get()));
7291 ASSERT_TRUE(server_bio);
7292 BIO_set_data(server_bio.get(), server_.get());
7293 BIO_set_init(server_bio.get(), 1);
7294
7295 // Wrap the inner connections in another layer of SSL.
7296 UniquePtr<SSL> client_outer(SSL_new(client_ctx_.get()));
7297 ASSERT_TRUE(client_outer);
7298 SSL_set_connect_state(client_outer.get());
7299 SSL_set_bio(client_outer.get(), client_bio.get(), client_bio.get());
7300 client_bio.release(); // |SSL_set_bio| takes ownership.
7301
7302 UniquePtr<SSL> server_outer(SSL_new(server_ctx_.get()));
7303 ASSERT_TRUE(server_outer);
7304 SSL_set_accept_state(server_outer.get());
7305 SSL_set_bio(server_outer.get(), server_bio.get(), server_bio.get());
7306 server_bio.release(); // |SSL_set_bio| takes ownership.
7307
7308 // Configure |client_outer| to reject the server certificate.
7309 SSL_set_custom_verify(
7310 client_outer.get(), SSL_VERIFY_PEER,
7311 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
7312 return ssl_verify_invalid;
7313 });
7314
7315 for (;;) {
7316 int client_ret = SSL_do_handshake(client_outer.get());
7317 int client_err = SSL_get_error(client_outer.get(), client_ret);
7318 if (client_err != SSL_ERROR_WANT_READ &&
7319 client_err != SSL_ERROR_WANT_WRITE) {
7320 // The client handshake should terminate on a certificate verification
7321 // error.
7322 EXPECT_EQ(SSL_ERROR_SSL, client_err);
7323 uint32_t err = ERR_peek_error();
7324 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
7325 EXPECT_EQ(SSL_R_CERTIFICATE_VERIFY_FAILED, ERR_GET_REASON(err));
7326 break;
7327 }
7328
7329 // Run the server handshake and continue.
7330 int server_ret = SSL_do_handshake(server_outer.get());
7331 int server_err = SSL_get_error(server_outer.get(), server_ret);
7332 ASSERT_TRUE(server_err == SSL_ERROR_NONE ||
7333 server_err == SSL_ERROR_WANT_READ ||
7334 server_err == SSL_ERROR_WANT_WRITE);
7335 }
7336}
7337
David Benjamin1b819472020-06-09 14:01:02 -04007338TEST_P(SSLVersionTest, SameKeyResume) {
7339 uint8_t key[48];
7340 RAND_bytes(key, sizeof(key));
7341
7342 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
7343 ASSERT_TRUE(server_ctx2);
7344 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
7345 ASSERT_TRUE(
7346 SSL_CTX_set_tlsext_ticket_keys(server_ctx_.get(), key, sizeof(key)));
7347 ASSERT_TRUE(
7348 SSL_CTX_set_tlsext_ticket_keys(server_ctx2.get(), key, sizeof(key)));
7349
7350 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7351 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
7352 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
7353
7354 // Establish a session for |server_ctx_|.
7355 bssl::UniquePtr<SSL_SESSION> session =
7356 CreateClientSession(client_ctx_.get(), server_ctx_.get());
7357 ASSERT_TRUE(session);
7358 ClientConfig config;
7359 config.session = session.get();
7360
7361 // Resuming with |server_ctx_| again works.
7362 bssl::UniquePtr<SSL> client, server;
7363 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7364 server_ctx_.get(), config));
7365 EXPECT_TRUE(SSL_session_reused(client.get()));
7366 EXPECT_TRUE(SSL_session_reused(server.get()));
7367
7368 // Resuming with |server_ctx2| also works.
7369 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7370 server_ctx2.get(), config));
7371 EXPECT_TRUE(SSL_session_reused(client.get()));
7372 EXPECT_TRUE(SSL_session_reused(server.get()));
7373}
7374
7375TEST_P(SSLVersionTest, DifferentKeyNoResume) {
7376 uint8_t key1[48], key2[48];
7377 RAND_bytes(key1, sizeof(key1));
7378 RAND_bytes(key2, sizeof(key2));
7379
7380 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
7381 ASSERT_TRUE(server_ctx2);
7382 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
7383 ASSERT_TRUE(
7384 SSL_CTX_set_tlsext_ticket_keys(server_ctx_.get(), key1, sizeof(key1)));
7385 ASSERT_TRUE(
7386 SSL_CTX_set_tlsext_ticket_keys(server_ctx2.get(), key2, sizeof(key2)));
7387
7388 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7389 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
7390 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
7391
7392 // Establish a session for |server_ctx_|.
7393 bssl::UniquePtr<SSL_SESSION> session =
7394 CreateClientSession(client_ctx_.get(), server_ctx_.get());
7395 ASSERT_TRUE(session);
7396 ClientConfig config;
7397 config.session = session.get();
7398
7399 // Resuming with |server_ctx_| again works.
7400 bssl::UniquePtr<SSL> client, server;
7401 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7402 server_ctx_.get(), config));
7403 EXPECT_TRUE(SSL_session_reused(client.get()));
7404 EXPECT_TRUE(SSL_session_reused(server.get()));
7405
7406 // Resuming with |server_ctx2| does not work.
7407 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7408 server_ctx2.get(), config));
7409 EXPECT_FALSE(SSL_session_reused(client.get()));
7410 EXPECT_FALSE(SSL_session_reused(server.get()));
7411}
7412
7413TEST_P(SSLVersionTest, UnrelatedServerNoResume) {
7414 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
7415 ASSERT_TRUE(server_ctx2);
7416 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
7417
7418 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7419 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
7420 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
7421
7422 // Establish a session for |server_ctx_|.
7423 bssl::UniquePtr<SSL_SESSION> session =
7424 CreateClientSession(client_ctx_.get(), server_ctx_.get());
7425 ASSERT_TRUE(session);
7426 ClientConfig config;
7427 config.session = session.get();
7428
7429 // Resuming with |server_ctx_| again works.
7430 bssl::UniquePtr<SSL> client, server;
7431 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7432 server_ctx_.get(), config));
7433 EXPECT_TRUE(SSL_session_reused(client.get()));
7434 EXPECT_TRUE(SSL_session_reused(server.get()));
7435
7436 // Resuming with |server_ctx2| does not work.
7437 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7438 server_ctx2.get(), config));
7439 EXPECT_FALSE(SSL_session_reused(client.get()));
7440 EXPECT_FALSE(SSL_session_reused(server.get()));
7441}
7442
Adam Langley47cefed2021-05-26 13:36:40 -07007443Span<const uint8_t> SessionIDOf(const SSL* ssl) {
7444 const SSL_SESSION *session = SSL_get_session(ssl);
7445 unsigned len;
7446 const uint8_t *data = SSL_SESSION_get_id(session, &len);
7447 return MakeConstSpan(data, len);
7448}
7449
7450TEST_P(SSLVersionTest, TicketSessionIDsMatch) {
7451 // This checks that the session IDs at client and server match after a ticket
7452 // resumption. It's unclear whether this should be true, but Envoy depends
7453 // on it in their tests so this will give an early signal if we break it.
7454 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7455 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
7456
7457 bssl::UniquePtr<SSL_SESSION> session =
7458 CreateClientSession(client_ctx_.get(), server_ctx_.get());
7459
7460 bssl::UniquePtr<SSL> client, server;
7461 ClientConfig config;
7462 config.session = session.get();
7463 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7464 server_ctx_.get(), config));
7465 EXPECT_TRUE(SSL_session_reused(client.get()));
7466 EXPECT_TRUE(SSL_session_reused(server.get()));
7467
7468 EXPECT_EQ(Bytes(SessionIDOf(client.get())), Bytes(SessionIDOf(server.get())));
7469}
7470
David Benjamin0e7dbd52019-05-15 16:01:18 -04007471TEST(SSLTest, WriteWhileExplicitRenegotiate) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04007472 bssl::UniquePtr<SSL_CTX> ctx(CreateContextWithTestCertificate(TLS_method()));
David Benjamin0e7dbd52019-05-15 16:01:18 -04007473 ASSERT_TRUE(ctx);
7474
David Benjamin0e7dbd52019-05-15 16:01:18 -04007475 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_2_VERSION));
7476 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_2_VERSION));
7477 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
7478 ctx.get(), "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"));
7479
7480 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04007481 ASSERT_TRUE(CreateClientAndServer(&client, &server, ctx.get(), ctx.get()));
David Benjamin0e7dbd52019-05-15 16:01:18 -04007482 SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_explicit);
David Benjamin9b2cdb72021-04-01 23:21:53 -04007483 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
David Benjamin0e7dbd52019-05-15 16:01:18 -04007484
7485 static const uint8_t kInput[] = {'h', 'e', 'l', 'l', 'o'};
7486
7487 // Write "hello" until the buffer is full, so |client| has a pending write.
7488 size_t num_writes = 0;
7489 for (;;) {
7490 int ret = SSL_write(client.get(), kInput, sizeof(kInput));
7491 if (ret != int(sizeof(kInput))) {
7492 ASSERT_EQ(-1, ret);
7493 ASSERT_EQ(SSL_ERROR_WANT_WRITE, SSL_get_error(client.get(), ret));
7494 break;
7495 }
7496 num_writes++;
7497 }
7498
7499 // Encrypt a HelloRequest.
7500 uint8_t in[] = {SSL3_MT_HELLO_REQUEST, 0, 0, 0};
7501#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
7502 // Fuzzer-mode records are unencrypted.
7503 uint8_t record[5 + sizeof(in)];
7504 record[0] = SSL3_RT_HANDSHAKE;
7505 record[1] = 3;
7506 record[2] = 3; // TLS 1.2
7507 record[3] = 0;
7508 record[4] = sizeof(record) - 5;
7509 memcpy(record + 5, in, sizeof(in));
7510#else
7511 // Extract key material from |server|.
7512 static const size_t kKeyLen = 32;
7513 static const size_t kNonceLen = 12;
7514 ASSERT_EQ(2u * (kKeyLen + kNonceLen), SSL_get_key_block_len(server.get()));
7515 uint8_t key_block[2u * (kKeyLen + kNonceLen)];
7516 ASSERT_TRUE(
7517 SSL_generate_key_block(server.get(), key_block, sizeof(key_block)));
7518 Span<uint8_t> key = MakeSpan(key_block + kKeyLen, kKeyLen);
7519 Span<uint8_t> nonce =
7520 MakeSpan(key_block + kKeyLen + kKeyLen + kNonceLen, kNonceLen);
7521
7522 uint8_t ad[13];
7523 uint64_t seq = SSL_get_write_sequence(server.get());
7524 for (size_t i = 0; i < 8; i++) {
7525 // The nonce is XORed with the sequence number.
7526 nonce[11 - i] ^= uint8_t(seq);
7527 ad[7 - i] = uint8_t(seq);
7528 seq >>= 8;
7529 }
7530
7531 ad[8] = SSL3_RT_HANDSHAKE;
7532 ad[9] = 3;
7533 ad[10] = 3; // TLS 1.2
7534 ad[11] = 0;
7535 ad[12] = sizeof(in);
7536
7537 uint8_t record[5 + sizeof(in) + 16];
7538 record[0] = SSL3_RT_HANDSHAKE;
7539 record[1] = 3;
7540 record[2] = 3; // TLS 1.2
7541 record[3] = 0;
7542 record[4] = sizeof(record) - 5;
7543
7544 ScopedEVP_AEAD_CTX aead;
7545 ASSERT_TRUE(EVP_AEAD_CTX_init(aead.get(), EVP_aead_chacha20_poly1305(),
7546 key.data(), key.size(),
7547 EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr));
7548 size_t len;
7549 ASSERT_TRUE(EVP_AEAD_CTX_seal(aead.get(), record + 5, &len,
7550 sizeof(record) - 5, nonce.data(), nonce.size(),
7551 in, sizeof(in), ad, sizeof(ad)));
7552 ASSERT_EQ(sizeof(record) - 5, len);
7553#endif // BORINGSSL_UNSAFE_FUZZER_MODE
7554
7555 ASSERT_EQ(int(sizeof(record)),
7556 BIO_write(SSL_get_wbio(server.get()), record, sizeof(record)));
7557
7558 // |SSL_read| should pick up the HelloRequest.
7559 uint8_t byte;
7560 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
7561 ASSERT_EQ(SSL_ERROR_WANT_RENEGOTIATE, SSL_get_error(client.get(), -1));
7562
7563 // Drain the data from the |client|.
7564 uint8_t buf[sizeof(kInput)];
7565 for (size_t i = 0; i < num_writes; i++) {
7566 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
7567 EXPECT_EQ(Bytes(buf), Bytes(kInput));
7568 }
7569
7570 // |client| should be able to finish the pending write and continue to write,
7571 // despite the paused HelloRequest.
7572 ASSERT_EQ(int(sizeof(kInput)),
7573 SSL_write(client.get(), kInput, sizeof(kInput)));
7574 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
7575 EXPECT_EQ(Bytes(buf), Bytes(kInput));
7576
7577 ASSERT_EQ(int(sizeof(kInput)),
7578 SSL_write(client.get(), kInput, sizeof(kInput)));
7579 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
7580 EXPECT_EQ(Bytes(buf), Bytes(kInput));
7581
7582 // |SSL_read| is stuck until we acknowledge the HelloRequest.
7583 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
7584 ASSERT_EQ(SSL_ERROR_WANT_RENEGOTIATE, SSL_get_error(client.get(), -1));
7585
7586 ASSERT_TRUE(SSL_renegotiate(client.get()));
7587 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
7588 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
7589
7590 // We never renegotiate as a server.
7591 ASSERT_EQ(-1, SSL_read(server.get(), buf, sizeof(buf)));
7592 ASSERT_EQ(SSL_ERROR_SSL, SSL_get_error(server.get(), -1));
7593 uint32_t err = ERR_get_error();
7594 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
7595 EXPECT_EQ(SSL_R_NO_RENEGOTIATION, ERR_GET_REASON(err));
7596}
7597
David Benjaminf9e0cda2020-03-23 18:29:09 -04007598
7599TEST(SSLTest, CopyWithoutEarlyData) {
7600 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04007601 bssl::UniquePtr<SSL_CTX> server_ctx(
7602 CreateContextWithTestCertificate(TLS_method()));
David Benjaminf9e0cda2020-03-23 18:29:09 -04007603 ASSERT_TRUE(client_ctx);
7604 ASSERT_TRUE(server_ctx);
7605
David Benjaminf9e0cda2020-03-23 18:29:09 -04007606 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
7607 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
7608 SSL_CTX_set_early_data_enabled(client_ctx.get(), 1);
7609 SSL_CTX_set_early_data_enabled(server_ctx.get(), 1);
7610
7611 bssl::UniquePtr<SSL_SESSION> session =
7612 CreateClientSession(client_ctx.get(), server_ctx.get());
7613 ASSERT_TRUE(session);
7614
7615 // The client should attempt early data with |session|.
David Benjaminf9e0cda2020-03-23 18:29:09 -04007616 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04007617 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7618 server_ctx.get()));
7619 SSL_set_session(client.get(), session.get());
7620 SSL_set_early_data_enabled(client.get(), 1);
David Benjaminf9e0cda2020-03-23 18:29:09 -04007621 ASSERT_EQ(1, SSL_do_handshake(client.get()));
7622 EXPECT_TRUE(SSL_in_early_data(client.get()));
7623
7624 // |SSL_SESSION_copy_without_early_data| should disable early data but
7625 // still resume the session.
7626 bssl::UniquePtr<SSL_SESSION> session2(
7627 SSL_SESSION_copy_without_early_data(session.get()));
7628 ASSERT_TRUE(session2);
7629 EXPECT_NE(session.get(), session2.get());
David Benjamin9b2cdb72021-04-01 23:21:53 -04007630 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7631 server_ctx.get()));
7632 SSL_set_session(client.get(), session2.get());
7633 SSL_set_early_data_enabled(client.get(), 1);
7634 EXPECT_TRUE(CompleteHandshakes(client.get(), server.get()));
David Benjaminf9e0cda2020-03-23 18:29:09 -04007635 EXPECT_TRUE(SSL_session_reused(client.get()));
7636 EXPECT_EQ(ssl_early_data_unsupported_for_session,
7637 SSL_get_early_data_reason(client.get()));
7638
7639 // |SSL_SESSION_copy_without_early_data| should be a reference count increase
7640 // when passed an early-data-incapable session.
7641 bssl::UniquePtr<SSL_SESSION> session3(
7642 SSL_SESSION_copy_without_early_data(session2.get()));
7643 EXPECT_EQ(session2.get(), session3.get());
7644}
7645
Adam Langley53a17f52020-05-26 14:44:07 -07007646TEST(SSLTest, ProcessTLS13NewSessionTicket) {
7647 // Configure client and server to negotiate TLS 1.3 only.
Adam Langley53a17f52020-05-26 14:44:07 -07007648 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04007649 bssl::UniquePtr<SSL_CTX> server_ctx(
7650 CreateContextWithTestCertificate(TLS_method()));
Adam Langley53a17f52020-05-26 14:44:07 -07007651 ASSERT_TRUE(client_ctx);
7652 ASSERT_TRUE(server_ctx);
7653 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
7654 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
7655 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
7656 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
Adam Langley53a17f52020-05-26 14:44:07 -07007657
7658 bssl::UniquePtr<SSL> client, server;
7659 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
7660 server_ctx.get()));
7661 EXPECT_EQ(TLS1_3_VERSION, SSL_version(client.get()));
7662
7663 // Process a TLS 1.3 NewSessionTicket.
7664 static const uint8_t kTicket[] = {
7665 0x04, 0x00, 0x00, 0xb2, 0x00, 0x02, 0xa3, 0x00, 0x04, 0x03, 0x02, 0x01,
7666 0x01, 0x00, 0x00, 0xa0, 0x01, 0x06, 0x09, 0x11, 0x16, 0x19, 0x21, 0x26,
7667 0x29, 0x31, 0x36, 0x39, 0x41, 0x46, 0x49, 0x51, 0x03, 0x06, 0x09, 0x13,
7668 0x16, 0x19, 0x23, 0x26, 0x29, 0x33, 0x36, 0x39, 0x43, 0x46, 0x49, 0x53,
7669 0xf7, 0x00, 0x29, 0xec, 0xf2, 0xc4, 0xa4, 0x41, 0xfc, 0x30, 0x17, 0x2e,
7670 0x9f, 0x7c, 0xa8, 0xaf, 0x75, 0x70, 0xf0, 0x1f, 0xc7, 0x98, 0xf7, 0xcf,
7671 0x5a, 0x5a, 0x6b, 0x5b, 0xfe, 0xf1, 0xe7, 0x3a, 0xe8, 0xf7, 0x6c, 0xd2,
7672 0xa8, 0xa6, 0x92, 0x5b, 0x96, 0x8d, 0xde, 0xdb, 0xd3, 0x20, 0x6a, 0xcb,
7673 0x69, 0x06, 0xf4, 0x91, 0x85, 0x2e, 0xe6, 0x5e, 0x0c, 0x59, 0xf2, 0x9e,
7674 0x9b, 0x79, 0x91, 0x24, 0x7e, 0x4a, 0x32, 0x3d, 0xbe, 0x4b, 0x80, 0x70,
7675 0xaf, 0xd0, 0x1d, 0xe2, 0xca, 0x05, 0x35, 0x09, 0x09, 0x05, 0x0f, 0xbb,
7676 0xc4, 0xae, 0xd7, 0xc4, 0xed, 0xd7, 0xae, 0x35, 0xc8, 0x73, 0x63, 0x78,
7677 0x64, 0xc9, 0x7a, 0x1f, 0xed, 0x7a, 0x9a, 0x47, 0x44, 0xfd, 0x50, 0xf7,
7678 0xb7, 0xe0, 0x64, 0xa9, 0x02, 0xc1, 0x5c, 0x23, 0x18, 0x3f, 0xc4, 0xcf,
7679 0x72, 0x02, 0x59, 0x2d, 0xe1, 0xaa, 0x61, 0x72, 0x00, 0x04, 0x5a, 0x5a,
7680 0x00, 0x00,
7681 };
7682 bssl::UniquePtr<SSL_SESSION> session(SSL_process_tls13_new_session_ticket(
7683 client.get(), kTicket, sizeof(kTicket)));
7684 ASSERT_TRUE(session);
7685 ASSERT_TRUE(SSL_SESSION_has_ticket(session.get()));
7686
7687 uint8_t *session_buf = nullptr;
7688 size_t session_length = 0;
7689 ASSERT_TRUE(
7690 SSL_SESSION_to_bytes(session.get(), &session_buf, &session_length));
7691 bssl::UniquePtr<uint8_t> session_buf_free(session_buf);
7692 ASSERT_TRUE(session_buf);
7693 ASSERT_GT(session_length, 0u);
7694
7695 // Servers cannot call |SSL_process_tls13_new_session_ticket|.
7696 ASSERT_FALSE(SSL_process_tls13_new_session_ticket(server.get(), kTicket,
7697 sizeof(kTicket)));
7698
7699 // Clients cannot call |SSL_process_tls13_new_session_ticket| before the
7700 // handshake completes.
7701 bssl::UniquePtr<SSL> client2(SSL_new(client_ctx.get()));
7702 ASSERT_TRUE(client2);
7703 SSL_set_connect_state(client2.get());
7704 ASSERT_FALSE(SSL_process_tls13_new_session_ticket(client2.get(), kTicket,
7705 sizeof(kTicket)));
7706}
7707
David Benjamin3989c992020-10-09 14:12:06 -04007708TEST(SSLTest, BIO) {
7709 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04007710 bssl::UniquePtr<SSL_CTX> server_ctx(
7711 CreateContextWithTestCertificate(TLS_method()));
David Benjamin3989c992020-10-09 14:12:06 -04007712 ASSERT_TRUE(client_ctx);
7713 ASSERT_TRUE(server_ctx);
7714
David Benjamin3989c992020-10-09 14:12:06 -04007715 for (bool take_ownership : {true, false}) {
7716 // For simplicity, get the handshake out of the way first.
7717 bssl::UniquePtr<SSL> client, server;
7718 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
7719 server_ctx.get()));
7720
7721 // Wrap |client| in an SSL BIO.
7722 bssl::UniquePtr<BIO> client_bio(BIO_new(BIO_f_ssl()));
7723 ASSERT_TRUE(client_bio);
7724 ASSERT_EQ(1, BIO_set_ssl(client_bio.get(), client.get(), take_ownership));
7725 if (take_ownership) {
7726 client.release();
7727 }
7728
7729 // Flushing the BIO should not crash.
7730 EXPECT_EQ(1, BIO_flush(client_bio.get()));
7731
7732 // Exchange some data.
7733 EXPECT_EQ(5, BIO_write(client_bio.get(), "hello", 5));
7734 uint8_t buf[5];
7735 ASSERT_EQ(5, SSL_read(server.get(), buf, sizeof(buf)));
7736 EXPECT_EQ(Bytes("hello"), Bytes(buf));
7737
7738 EXPECT_EQ(5, SSL_write(server.get(), "world", 5));
7739 ASSERT_EQ(5, BIO_read(client_bio.get(), buf, sizeof(buf)));
7740 EXPECT_EQ(Bytes("world"), Bytes(buf));
7741
7742 // |BIO_should_read| should work.
7743 EXPECT_EQ(-1, BIO_read(client_bio.get(), buf, sizeof(buf)));
7744 EXPECT_TRUE(BIO_should_read(client_bio.get()));
7745
7746 // Writing data should eventually exceed the buffer size and fail, reporting
7747 // |BIO_should_write|.
7748 int ret;
7749 for (int i = 0; i < 1024; i++) {
7750 std::vector<uint8_t> buffer(1024);
7751 ret = BIO_write(client_bio.get(), buffer.data(), buffer.size());
7752 if (ret <= 0) {
7753 break;
7754 }
7755 }
7756 EXPECT_EQ(-1, ret);
7757 EXPECT_TRUE(BIO_should_write(client_bio.get()));
7758 }
7759}
7760
David Benjamin12a3e7e2021-04-13 11:47:36 -04007761TEST(SSLTest, ALPNConfig) {
7762 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
7763 ASSERT_TRUE(ctx);
7764 bssl::UniquePtr<X509> cert = GetTestCertificate();
7765 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
7766 ASSERT_TRUE(cert);
7767 ASSERT_TRUE(key);
7768 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
7769 ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
7770
7771 // Set up some machinery to check the configured ALPN against what is actually
7772 // sent over the wire. Note that the ALPN callback is only called when the
7773 // client offers ALPN.
7774 std::vector<uint8_t> observed_alpn;
7775 SSL_CTX_set_alpn_select_cb(
7776 ctx.get(),
7777 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
7778 unsigned in_len, void *arg) -> int {
7779 std::vector<uint8_t> *observed_alpn_ptr =
7780 static_cast<std::vector<uint8_t> *>(arg);
7781 observed_alpn_ptr->assign(in, in + in_len);
7782 return SSL_TLSEXT_ERR_NOACK;
7783 },
7784 &observed_alpn);
7785 auto check_alpn_proto = [&](Span<const uint8_t> expected) {
7786 observed_alpn.clear();
7787 bssl::UniquePtr<SSL> client, server;
7788 EXPECT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
7789 EXPECT_EQ(Bytes(expected), Bytes(observed_alpn));
7790 };
7791
7792 // Note that |SSL_CTX_set_alpn_protos|'s return value is reversed.
7793 static const uint8_t kValidList[] = {0x03, 'f', 'o', 'o',
7794 0x03, 'b', 'a', 'r'};
7795 EXPECT_EQ(0,
7796 SSL_CTX_set_alpn_protos(ctx.get(), kValidList, sizeof(kValidList)));
7797 check_alpn_proto(kValidList);
7798
7799 // Invalid lists are rejected.
7800 static const uint8_t kInvalidList[] = {0x04, 'f', 'o', 'o'};
7801 EXPECT_EQ(1, SSL_CTX_set_alpn_protos(ctx.get(), kInvalidList,
7802 sizeof(kInvalidList)));
7803
7804 // Empty lists are valid and are interpreted as disabling ALPN.
7805 EXPECT_EQ(0, SSL_CTX_set_alpn_protos(ctx.get(), nullptr, 0));
7806 check_alpn_proto({});
7807}
7808
David Benjamin2f3958a2021-04-16 11:55:23 -04007809// Test that the key usage checker can correctly handle issuerUID and
7810// subjectUID. See https://crbug.com/1199744.
7811TEST(SSLTest, KeyUsageWithUIDs) {
7812 static const char kGoodKeyUsage[] = R"(
7813-----BEGIN CERTIFICATE-----
7814MIIB7DCCAZOgAwIBAgIJANlMBNpJfb/rMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYT
7815AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn
7816aXRzIFB0eSBMdGQwHhcNMTQwNDIzMjMyMTU3WhcNMTQwNTIzMjMyMTU3WjBFMQsw
7817CQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJu
7818ZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp
78194r9ln5e+Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsW
7820Ghz1HX7xlC1Lz3IiwYEEABI0VoIEABI0VqNgMF4wHQYDVR0OBBYEFKuE0qyrlfCC
7821ThZ4B1VXX+QmjYLRMB8GA1UdIwQYMBaAFKuE0qyrlfCCThZ4B1VXX+QmjYLRMA4G
7822A1UdDwEB/wQEAwIHgDAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0cAMEQCIEWJ
782334EcqW5MHwLIA1hZ2Tj/jV2QjN02KLxis9mFsqDKAiAMlMTkzsM51vVs9Ohqa+Rc
78244Z7qDhjIhiF4dM0uEDYRVA==
7825-----END CERTIFICATE-----
7826)";
7827 static const char kBadKeyUsage[] = R"(
7828-----BEGIN CERTIFICATE-----
7829MIIB7jCCAZOgAwIBAgIJANlMBNpJfb/rMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYT
7830AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn
7831aXRzIFB0eSBMdGQwHhcNMTQwNDIzMjMyMTU3WhcNMTQwNTIzMjMyMTU3WjBFMQsw
7832CQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJu
7833ZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp
78344r9ln5e+Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsW
7835Ghz1HX7xlC1Lz3IiwYEEABI0VoIEABI0VqNgMF4wHQYDVR0OBBYEFKuE0qyrlfCC
7836ThZ4B1VXX+QmjYLRMB8GA1UdIwQYMBaAFKuE0qyrlfCCThZ4B1VXX+QmjYLRMA4G
7837A1UdDwEB/wQEAwIDCDAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0kAMEYCIQC6
7838taYBUDu2gcZC6EMk79FBHArYI0ucF+kzvETegZCbBAIhANtObFec5gtso/47moPD
7839RHrQbWsFUakETXL9QMlegh5t
7840-----END CERTIFICATE-----
7841)";
7842
7843 bssl::UniquePtr<X509> good = CertFromPEM(kGoodKeyUsage);
7844 ASSERT_TRUE(good);
7845 bssl::UniquePtr<X509> bad = CertFromPEM(kBadKeyUsage);
7846 ASSERT_TRUE(bad);
7847
7848 // We check key usage when configuring EC certificates to distinguish ECDSA
7849 // and ECDH.
7850 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
7851 ASSERT_TRUE(ctx);
7852 EXPECT_TRUE(SSL_CTX_use_certificate(ctx.get(), good.get()));
7853 EXPECT_FALSE(SSL_CTX_use_certificate(ctx.get(), bad.get()));
7854}
7855
David Benjamin9b2cdb72021-04-01 23:21:53 -04007856// Test that |SSL_can_release_private_key| reports true as early as expected.
7857// The internal asserts in the library check we do not report true too early.
7858TEST(SSLTest, CanReleasePrivateKey) {
7859 bssl::UniquePtr<SSL_CTX> client_ctx =
7860 CreateContextWithTestCertificate(TLS_method());
7861 ASSERT_TRUE(client_ctx);
7862 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
7863
7864 // Note this assumes the transport buffer is large enough to fit the client
7865 // and server first flights. We check this with |SSL_ERROR_WANT_READ|. If the
7866 // transport buffer was too small it would return |SSL_ERROR_WANT_WRITE|.
7867 auto check_first_server_round_trip = [&](SSL *client, SSL *server) {
7868 // Write the ClientHello.
7869 ASSERT_EQ(-1, SSL_do_handshake(client));
7870 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client, -1));
7871
7872 // Consume the ClientHello and write the server flight.
7873 ASSERT_EQ(-1, SSL_do_handshake(server));
7874 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server, -1));
7875
7876 EXPECT_TRUE(SSL_can_release_private_key(server));
7877 };
7878
7879 {
7880 SCOPED_TRACE("TLS 1.2 ECDHE");
7881 bssl::UniquePtr<SSL_CTX> server_ctx(
7882 CreateContextWithTestCertificate(TLS_method()));
7883 ASSERT_TRUE(server_ctx);
7884 ASSERT_TRUE(
7885 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
7886 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
7887 server_ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
7888 // Configure the server to request client certificates, so we can also test
7889 // the client half.
7890 SSL_CTX_set_custom_verify(
7891 server_ctx.get(), SSL_VERIFY_PEER,
7892 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
7893 bssl::UniquePtr<SSL> client, server;
7894 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7895 server_ctx.get()));
7896 check_first_server_round_trip(client.get(), server.get());
7897
7898 // Consume the server flight and write the client response. The client still
7899 // has a Finished message to consume but can also release its key early.
7900 ASSERT_EQ(-1, SSL_do_handshake(client.get()));
7901 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
7902 EXPECT_TRUE(SSL_can_release_private_key(client.get()));
7903
7904 // However, a client that has not disabled renegotiation can never release
7905 // the key.
7906 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7907 server_ctx.get()));
7908 SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_freely);
7909 check_first_server_round_trip(client.get(), server.get());
7910 ASSERT_EQ(-1, SSL_do_handshake(client.get()));
7911 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
7912 EXPECT_FALSE(SSL_can_release_private_key(client.get()));
7913 }
7914
7915 {
7916 SCOPED_TRACE("TLS 1.2 resumption");
7917 bssl::UniquePtr<SSL_CTX> server_ctx(
7918 CreateContextWithTestCertificate(TLS_method()));
7919 ASSERT_TRUE(server_ctx);
7920 ASSERT_TRUE(
7921 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
7922 bssl::UniquePtr<SSL_SESSION> session =
7923 CreateClientSession(client_ctx.get(), server_ctx.get());
7924 ASSERT_TRUE(session);
7925 bssl::UniquePtr<SSL> client, server;
7926 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7927 server_ctx.get()));
7928 SSL_set_session(client.get(), session.get());
7929 check_first_server_round_trip(client.get(), server.get());
7930 }
7931
7932 {
7933 SCOPED_TRACE("TLS 1.3 1-RTT");
7934 bssl::UniquePtr<SSL_CTX> server_ctx(
7935 CreateContextWithTestCertificate(TLS_method()));
7936 ASSERT_TRUE(server_ctx);
7937 ASSERT_TRUE(
7938 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
7939 bssl::UniquePtr<SSL> client, server;
7940 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7941 server_ctx.get()));
7942 check_first_server_round_trip(client.get(), server.get());
7943 }
7944
7945 {
7946 SCOPED_TRACE("TLS 1.3 resumption");
7947 bssl::UniquePtr<SSL_CTX> server_ctx(
7948 CreateContextWithTestCertificate(TLS_method()));
7949 ASSERT_TRUE(server_ctx);
7950 ASSERT_TRUE(
7951 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
7952 bssl::UniquePtr<SSL_SESSION> session =
7953 CreateClientSession(client_ctx.get(), server_ctx.get());
7954 ASSERT_TRUE(session);
7955 bssl::UniquePtr<SSL> client, server;
7956 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7957 server_ctx.get()));
7958 SSL_set_session(client.get(), session.get());
7959 check_first_server_round_trip(client.get(), server.get());
7960 }
7961}
7962
David Benjamine9c5d722021-06-09 17:43:16 -04007963// GetExtensionOrder sets |*out| to the list of extensions a client attached to
7964// |ctx| will send in the ClientHello. If |ech_keys| is non-null, the client
7965// will offer ECH with the public component. If |decrypt_ech| is true, |*out|
7966// will be set to the ClientHelloInner's extensions, rather than
7967// ClientHelloOuter.
7968static bool GetExtensionOrder(SSL_CTX *client_ctx, std::vector<uint16_t> *out,
7969 SSL_ECH_KEYS *ech_keys, bool decrypt_ech) {
7970 struct AppData {
7971 std::vector<uint16_t> *out;
7972 bool decrypt_ech;
7973 bool callback_done = false;
7974 };
7975 AppData app_data;
7976 app_data.out = out;
7977 app_data.decrypt_ech = decrypt_ech;
7978
7979 bssl::UniquePtr<SSL_CTX> server_ctx =
7980 CreateContextWithTestCertificate(TLS_method());
7981 if (!server_ctx || //
7982 !SSL_CTX_set_app_data(server_ctx.get(), &app_data) ||
7983 (decrypt_ech && !SSL_CTX_set1_ech_keys(server_ctx.get(), ech_keys))) {
7984 return false;
7985 }
7986
7987 // Configure the server to record the ClientHello extension order. We use a
7988 // server rather than |GetClientHello| so it can decrypt ClientHelloInner.
7989 SSL_CTX_set_select_certificate_cb(
7990 server_ctx.get(),
7991 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
7992 AppData *app_data_ptr = static_cast<AppData *>(
7993 SSL_CTX_get_app_data(SSL_get_SSL_CTX(client_hello->ssl)));
7994 EXPECT_EQ(app_data_ptr->decrypt_ech ? 1 : 0,
7995 SSL_ech_accepted(client_hello->ssl));
7996
7997 app_data_ptr->out->clear();
7998 CBS extensions;
7999 CBS_init(&extensions, client_hello->extensions,
8000 client_hello->extensions_len);
8001 while (CBS_len(&extensions)) {
8002 uint16_t type;
8003 CBS body;
8004 if (!CBS_get_u16(&extensions, &type) ||
8005 !CBS_get_u16_length_prefixed(&extensions, &body)) {
8006 return ssl_select_cert_error;
8007 }
8008 app_data_ptr->out->push_back(type);
8009 }
8010
8011 // Don't bother completing the handshake.
8012 app_data_ptr->callback_done = true;
8013 return ssl_select_cert_error;
8014 });
8015
8016 bssl::UniquePtr<SSL> client, server;
8017 if (!CreateClientAndServer(&client, &server, client_ctx, server_ctx.get()) ||
8018 (ech_keys != nullptr && !InstallECHConfigList(client.get(), ech_keys))) {
8019 return false;
8020 }
8021
8022 // Run the handshake far enough to process the ClientHello.
8023 SSL_do_handshake(client.get());
8024 SSL_do_handshake(server.get());
8025 return app_data.callback_done;
8026}
8027
8028// Test that, when extension permutation is enabled, the ClientHello extension
8029// order changes, both with and without ECH, and in both ClientHelloInner and
8030// ClientHelloOuter.
8031TEST(SSLTest, PermuteExtensions) {
8032 bssl::UniquePtr<SSL_ECH_KEYS> keys = MakeTestECHKeys();
8033 ASSERT_TRUE(keys);
8034 for (bool offer_ech : {false, true}) {
8035 SCOPED_TRACE(offer_ech);
8036 SSL_ECH_KEYS *maybe_keys = offer_ech ? keys.get() : nullptr;
8037 for (bool decrypt_ech : {false, true}) {
8038 SCOPED_TRACE(decrypt_ech);
8039 if (!offer_ech && decrypt_ech) {
8040 continue;
8041 }
8042
8043 // When extension permutation is disabled, the order should be consistent.
8044 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
8045 ASSERT_TRUE(ctx);
8046 std::vector<uint16_t> order1, order2;
8047 ASSERT_TRUE(
8048 GetExtensionOrder(ctx.get(), &order1, maybe_keys, decrypt_ech));
8049 ASSERT_TRUE(
8050 GetExtensionOrder(ctx.get(), &order2, maybe_keys, decrypt_ech));
8051 EXPECT_EQ(order1, order2);
8052
8053 ctx.reset(SSL_CTX_new(TLS_method()));
8054 ASSERT_TRUE(ctx);
8055 SSL_CTX_set_permute_extensions(ctx.get(), 1);
8056
8057 // When extension permutation is enabled, each ClientHello should have a
8058 // different order.
8059 //
8060 // This test is inherently flaky, so we run it multiple times. We send at
8061 // least five extensions by default from TLS 1.3: supported_versions,
8062 // key_share, supported_groups, psk_key_exchange_modes, and
8063 // signature_algorithms. That means the probability of a false negative is
8064 // at most 1/120. Repeating the test 14 times lowers false negative rate
8065 // to under 2^-96.
8066 ASSERT_TRUE(
8067 GetExtensionOrder(ctx.get(), &order1, maybe_keys, decrypt_ech));
8068 EXPECT_GE(order1.size(), 5u);
8069 static const int kNumIterations = 14;
8070 bool passed = false;
8071 for (int i = 0; i < kNumIterations; i++) {
8072 ASSERT_TRUE(
8073 GetExtensionOrder(ctx.get(), &order2, maybe_keys, decrypt_ech));
8074 if (order1 != order2) {
8075 passed = true;
8076 break;
8077 }
8078 }
8079 EXPECT_TRUE(passed) << "Extensions were not permuted";
8080 }
8081 }
8082}
8083
Adam Langley7e7e6b62021-12-06 13:04:07 -08008084TEST(SSLTest, HostMatching) {
David Benjaminc3c540b2021-12-08 15:12:51 -05008085 static const char kCertPEM[] = R"(
8086-----BEGIN CERTIFICATE-----
8087MIIB9jCCAZ2gAwIBAgIQeudG9R61BOxUvWkeVhU5DTAKBggqhkjOPQQDAjApMRAw
8088DgYDVQQKEwdBY21lIENvMRUwEwYDVQQDEwxleGFtcGxlMy5jb20wHhcNMjExMjA2
8089MjA1NjU2WhcNMjIxMjA2MjA1NjU2WjApMRAwDgYDVQQKEwdBY21lIENvMRUwEwYD
8090VQQDEwxleGFtcGxlMy5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS7l2VO
8091Bl2TjVm9WfGk24+hMbVFUNB+RVHWbCvFvNZAoWiIJ2z34RLGInyZvCZ8xLAvsuaW
8092ULDDaoeDl1M0t4Hmo4GmMIGjMA4GA1UdDwEB/wQEAwIChDATBgNVHSUEDDAKBggr
8093BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTTJWurcc1t+VPQBko3
8094Gsw6cbcWSTBMBgNVHREERTBDggxleGFtcGxlMS5jb22CDGV4YW1wbGUyLmNvbYIP
8095YSouZXhhbXBsZTQuY29tgg4qLmV4YW1wbGU1LmNvbYcEAQIDBDAKBggqhkjOPQQD
8096AgNHADBEAiAAv0ljHJGrgyzZDkG6XvNZ5ewxRfnXcZuD0Y7E4giCZgIgNK1qjilu
80975DyVbfKeeJhOCtGxqE1dWLXyJBnoRomSYBY=
8098-----END CERTIFICATE-----
8099)";
Adam Langley7e7e6b62021-12-06 13:04:07 -08008100 bssl::UniquePtr<X509> cert(CertFromPEM(kCertPEM));
8101 ASSERT_TRUE(cert);
David Benjaminc3c540b2021-12-08 15:12:51 -05008102 static const char kCertNoSANsPEM[] = R"(
8103-----BEGIN CERTIFICATE-----
8104MIIBqzCCAVGgAwIBAgIQeudG9R61BOxUvWkeVhU5DTAKBggqhkjOPQQDAjArMRIw
8105EAYDVQQKEwlBY21lIENvIDIxFTATBgNVBAMTDGV4YW1wbGUzLmNvbTAeFw0yMTEy
8106MDYyMDU2NTZaFw0yMjEyMDYyMDU2NTZaMCsxEjAQBgNVBAoTCUFjbWUgQ28gMjEV
8107MBMGA1UEAxMMZXhhbXBsZTMuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE
8108u5dlTgZdk41ZvVnxpNuPoTG1RVDQfkVR1mwrxbzWQKFoiCds9+ESxiJ8mbwmfMSw
8109L7LmllCww2qHg5dTNLeB5qNXMFUwDgYDVR0PAQH/BAQDAgKEMBMGA1UdJQQMMAoG
8110CCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNMla6txzW35U9AG
8111SjcazDpxtxZJMAoGCCqGSM49BAMCA0gAMEUCIG3YWGWtpVhbcGV7wFKQwTfmvwHW
8112pw4qCFZlool4hCwsAiEA+2fc6NfSbNpFEtQkDOMJW2ANiScAVEmImNqPfb2klz4=
8113-----END CERTIFICATE-----
8114)";
8115 bssl::UniquePtr<X509> cert_no_sans(CertFromPEM(kCertNoSANsPEM));
8116 ASSERT_TRUE(cert_no_sans);
Adam Langley7e7e6b62021-12-06 13:04:07 -08008117
David Benjaminc3c540b2021-12-08 15:12:51 -05008118 static const char kKeyPEM[] = R"(
8119-----BEGIN PRIVATE KEY-----
8120MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQghsaSZhUzZAcQlLyJ
8121MDuy7WPdyqNsAX9rmEP650LF/q2hRANCAAS7l2VOBl2TjVm9WfGk24+hMbVFUNB+
8122RVHWbCvFvNZAoWiIJ2z34RLGInyZvCZ8xLAvsuaWULDDaoeDl1M0t4Hm
8123-----END PRIVATE KEY-----
8124)";
Adam Langley7e7e6b62021-12-06 13:04:07 -08008125 bssl::UniquePtr<EVP_PKEY> key(KeyFromPEM(kKeyPEM));
8126 ASSERT_TRUE(key);
8127
Adam Langley7e7e6b62021-12-06 13:04:07 -08008128 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
8129 ASSERT_TRUE(client_ctx);
8130 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx.get()),
8131 cert.get()));
David Benjaminc3c540b2021-12-08 15:12:51 -05008132 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx.get()),
8133 cert_no_sans.get()));
Adam Langley7e7e6b62021-12-06 13:04:07 -08008134 SSL_CTX_set_verify(client_ctx.get(),
8135 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
8136 nullptr);
8137
8138 struct TestCase {
David Benjaminc3c540b2021-12-08 15:12:51 -05008139 X509 *cert;
Adam Langley7e7e6b62021-12-06 13:04:07 -08008140 std::string hostname;
8141 unsigned flags;
8142 bool should_match;
8143 };
8144 std::vector<TestCase> kTests = {
8145 // These two names are present as SANs in the certificate.
David Benjaminc3c540b2021-12-08 15:12:51 -05008146 {cert.get(), "example1.com", 0, true},
8147 {cert.get(), "example2.com", 0, true},
Adam Langley7e7e6b62021-12-06 13:04:07 -08008148 // This is the CN of the certificate, but that shouldn't matter if a SAN
8149 // extension is present.
David Benjaminc3c540b2021-12-08 15:12:51 -05008150 {cert.get(), "example3.com", 0, false},
8151 // If the SAN is not present, we, for now, look for DNS names in the CN.
8152 {cert_no_sans.get(), "example3.com", 0, true},
8153 // ... but this can be turned off.
8154 {cert_no_sans.get(), "example3.com", X509_CHECK_FLAG_NEVER_CHECK_SUBJECT,
8155 false},
8156 // a*.example4.com is a SAN, but is invalid.
8157 {cert.get(), "abc.example4.com", 0, false},
Adam Langley7e7e6b62021-12-06 13:04:07 -08008158 // *.example5.com is a SAN in the certificate, which is a normal and valid
8159 // wildcard.
David Benjaminc3c540b2021-12-08 15:12:51 -05008160 {cert.get(), "abc.example5.com", 0, true},
Adam Langley7e7e6b62021-12-06 13:04:07 -08008161 // This name is not present.
David Benjaminc3c540b2021-12-08 15:12:51 -05008162 {cert.get(), "notexample1.com", 0, false},
Adam Langley7e7e6b62021-12-06 13:04:07 -08008163 // The IPv4 address 1.2.3.4 is a SAN, but that shouldn't match against a
8164 // hostname that happens to be its textual representation.
David Benjaminc3c540b2021-12-08 15:12:51 -05008165 {cert.get(), "1.2.3.4", 0, false},
Adam Langley7e7e6b62021-12-06 13:04:07 -08008166 };
8167
Adam Langley7e7e6b62021-12-06 13:04:07 -08008168 for (const TestCase &test : kTests) {
8169 SCOPED_TRACE(test.hostname);
David Benjaminc3c540b2021-12-08 15:12:51 -05008170
8171 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
8172 ASSERT_TRUE(server_ctx);
8173 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), test.cert));
8174 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
8175
8176 ClientConfig config;
8177 bssl::UniquePtr<SSL> client, server;
Adam Langley7e7e6b62021-12-06 13:04:07 -08008178 config.verify_hostname = test.hostname;
8179 config.hostflags = test.flags;
8180 EXPECT_EQ(test.should_match,
8181 ConnectClientAndServer(&client, &server, client_ctx.get(),
8182 server_ctx.get(), config));
8183 }
8184}
8185
David Benjamin3f180b82022-05-09 17:45:18 -04008186TEST(SSLTest, NumTickets) {
8187 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
8188 ASSERT_TRUE(server_ctx);
8189 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
8190 ASSERT_TRUE(client_ctx);
8191 bssl::UniquePtr<X509> cert = GetTestCertificate();
8192 ASSERT_TRUE(cert);
8193 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
8194 ASSERT_TRUE(key);
8195 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
8196 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
8197 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
8198
8199 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
8200 static size_t ticket_count;
8201 SSL_CTX_sess_set_new_cb(client_ctx.get(), [](SSL *, SSL_SESSION *) -> int {
8202 ticket_count++;
8203 return 0;
8204 });
8205
8206 auto count_tickets = [&]() -> size_t {
8207 ticket_count = 0;
8208 bssl::UniquePtr<SSL> client, server;
8209 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
8210 server_ctx.get()) ||
8211 !FlushNewSessionTickets(client.get(), server.get())) {
8212 ADD_FAILURE() << "Could not run handshake";
8213 return 0;
8214 }
8215 return ticket_count;
8216 };
8217
8218 // By default, we should send two tickets.
8219 EXPECT_EQ(count_tickets(), 2u);
8220
8221 for (size_t num_tickets : {0, 1, 2, 3, 4, 5}) {
8222 SCOPED_TRACE(num_tickets);
8223 ASSERT_TRUE(SSL_CTX_set_num_tickets(server_ctx.get(), num_tickets));
David Benjamin5697a922022-07-21 10:35:59 -07008224 EXPECT_EQ(SSL_CTX_get_num_tickets(server_ctx.get()), num_tickets);
David Benjamin3f180b82022-05-09 17:45:18 -04008225 EXPECT_EQ(count_tickets(), num_tickets);
8226 }
8227
8228 // Configuring too many tickets causes us to stop at some point.
8229 ASSERT_TRUE(SSL_CTX_set_num_tickets(server_ctx.get(), 100000));
David Benjamin5697a922022-07-21 10:35:59 -07008230 EXPECT_EQ(SSL_CTX_get_num_tickets(server_ctx.get()), 16u);
David Benjamin3f180b82022-05-09 17:45:18 -04008231 EXPECT_EQ(count_tickets(), 16u);
8232}
8233
David Benjamin955ef792022-06-13 13:16:43 -04008234TEST(SSLTest, CertSubjectsToStack) {
8235 const std::string kCert1 = R"(
8236-----BEGIN CERTIFICATE-----
8237MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC
8238QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp
8239dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ
8240BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l
8241dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni
8242v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa
8243HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw
8244HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ
8245BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E
8246BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=
8247-----END CERTIFICATE-----
8248)";
8249 const std::vector<uint8_t> kName1 = {
8250 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
8251 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
8252 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
8253 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
8254 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
8255 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64};
8256 const std::string kCert2 = R"(
8257-----BEGIN CERTIFICATE-----
8258MIICXjCCAcegAwIBAgIIWjO48ufpunYwDQYJKoZIhvcNAQELBQAwNjEaMBgGA1UE
8259ChMRQm9yaW5nU1NMIFRFU1RJTkcxGDAWBgNVBAMTD0ludGVybWVkaWF0ZSBDQTAg
8260Fw0xNTAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowMjEaMBgGA1UEChMRQm9y
8261aW5nU1NMIFRFU1RJTkcxFDASBgNVBAMTC2V4YW1wbGUuY29tMIGfMA0GCSqGSIb3
8262DQEBAQUAA4GNADCBiQKBgQDD0U0ZYgqShJ7oOjsyNKyVXEHqeafmk/bAoPqY/h1c
8263oPw2E8KmeqiUSoTPjG5IXSblOxcqpbAXgnjPzo8DI3GNMhAf8SYNYsoH7gc7Uy7j
82645x8bUrisGnuTHqkqH6d4/e7ETJ7i3CpR8bvK16DggEvQTudLipz8FBHtYhFakfdh
8265TwIDAQABo3cwdTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEG
8266CCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwGQYDVR0OBBIEEKN5pvbur7mlXjeMEYA0
82674nUwGwYDVR0jBBQwEoAQjBpoqLV2211Xex+NFLIGozANBgkqhkiG9w0BAQsFAAOB
8268gQBj/p+JChp//LnXWC1k121LM/ii7hFzQzMrt70bny406SGz9jAjaPOX4S3gt38y
8269rhjpPukBlSzgQXFg66y6q5qp1nQTD1Cw6NkKBe9WuBlY3iYfmsf7WT8nhlT1CttU
8270xNCwyMX9mtdXdQicOfNjIGUCD5OLV5PgHFPRKiHHioBAhg==
8271-----END CERTIFICATE-----
8272)";
8273 const std::vector<uint8_t> kName2 = {
8274 0x30, 0x32, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a,
8275 0x13, 0x11, 0x42, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x53, 0x4c,
8276 0x20, 0x54, 0x45, 0x53, 0x54, 0x49, 0x4e, 0x47, 0x31, 0x14, 0x30,
8277 0x12, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0b, 0x65, 0x78, 0x61,
8278 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d};
8279
8280 const struct {
8281 std::vector<std::vector<uint8_t>> existing;
8282 std::string pem;
8283 std::vector<std::vector<uint8_t>> expected;
8284 } kTests[] = {
8285 // Do nothing.
8286 {{}, "", {}},
8287 // Append to an empty list, skipping duplicates.
8288 {{}, kCert1 + kCert2 + kCert1, {kName1, kName2}},
8289 // One of the names was already present.
8290 {{kName1}, kCert1 + kCert2, {kName1, kName2}},
8291 // Both names were already present.
8292 {{kName1, kName2}, kCert1 + kCert2, {kName1, kName2}},
8293 // Preserve existing duplicates.
8294 {{kName1, kName2, kName2}, kCert1 + kCert2, {kName1, kName2, kName2}},
8295 };
8296 for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kTests); i++) {
8297 SCOPED_TRACE(i);
8298 const auto &t = kTests[i];
8299
8300 bssl::UniquePtr<STACK_OF(X509_NAME)> stack(sk_X509_NAME_new_null());
8301 ASSERT_TRUE(stack);
8302 for (const auto& name : t.existing) {
8303 const uint8_t *inp = name.data();
8304 bssl::UniquePtr<X509_NAME> name_obj(
8305 d2i_X509_NAME(nullptr, &inp, name.size()));
8306 ASSERT_TRUE(name_obj);
8307 EXPECT_EQ(inp, name.data() + name.size());
8308 ASSERT_TRUE(bssl::PushToStack(stack.get(), std::move(name_obj)));
8309 }
8310
8311 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(t.pem.data(), t.pem.size()));
8312 ASSERT_TRUE(bio);
8313 ASSERT_TRUE(SSL_add_bio_cert_subjects_to_stack(stack.get(), bio.get()));
8314
8315 // The function should have left |stack|'s comparison function alone.
8316 EXPECT_EQ(nullptr, sk_X509_NAME_set_cmp_func(stack.get(), nullptr));
8317
8318 std::vector<std::vector<uint8_t>> expected = t.expected, result;
8319 for (X509_NAME *name : stack.get()) {
8320 uint8_t *der = nullptr;
8321 int der_len = i2d_X509_NAME(name, &der);
8322 ASSERT_GE(der_len, 0);
8323 result.push_back(std::vector<uint8_t>(der, der + der_len));
8324 OPENSSL_free(der);
8325 }
8326
8327 // |SSL_add_bio_cert_subjects_to_stack| does not return the output in a
8328 // well-defined order.
8329 std::sort(expected.begin(), expected.end());
8330 std::sort(result.begin(), result.end());
8331 EXPECT_EQ(result, expected);
8332 }
8333}
8334
David Benjaminb95c7e52022-07-22 16:28:22 -07008335TEST(SSLTest, EmptyWriteBlockedOnHandshakeData) {
8336 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
8337 bssl::UniquePtr<SSL_CTX> server_ctx =
8338 CreateContextWithTestCertificate(TLS_method());
8339 ASSERT_TRUE(client_ctx);
8340 ASSERT_TRUE(server_ctx);
8341 // Configure only TLS 1.3. This test requires post-handshake NewSessionTicket.
8342 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
8343 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
8344
8345 // Connect a client and server with tiny buffer between the two.
8346 bssl::UniquePtr<SSL> client(SSL_new(client_ctx.get())),
8347 server(SSL_new(server_ctx.get()));
8348 ASSERT_TRUE(client);
8349 ASSERT_TRUE(server);
8350 SSL_set_connect_state(client.get());
8351 SSL_set_accept_state(server.get());
8352 BIO *bio1, *bio2;
8353 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 1, &bio2, 1));
8354 SSL_set_bio(client.get(), bio1, bio1);
8355 SSL_set_bio(server.get(), bio2, bio2);
8356 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
8357
8358 // We defer NewSessionTicket to the first write, so the server has a pending
8359 // NewSessionTicket. See https://boringssl-review.googlesource.com/34948. This
8360 // means an empty write will flush the ticket. However, the transport only
8361 // allows one byte through, so this will fail with |SSL_ERROR_WANT_WRITE|.
8362 int ret = SSL_write(server.get(), nullptr, 0);
8363 ASSERT_EQ(ret, -1);
8364 ASSERT_EQ(SSL_get_error(server.get(), ret), SSL_ERROR_WANT_WRITE);
8365
8366 // Attempting to write non-zero data should not trip |SSL_R_BAD_WRITE_RETRY|.
8367 const uint8_t kData[] = {'h', 'e', 'l', 'l', 'o'};
8368 ret = SSL_write(server.get(), kData, sizeof(kData));
8369 ASSERT_EQ(ret, -1);
8370 ASSERT_EQ(SSL_get_error(server.get(), ret), SSL_ERROR_WANT_WRITE);
8371
8372 // Byte by byte, the data should eventually get through.
8373 uint8_t buf[sizeof(kData)];
8374 for (;;) {
8375 ret = SSL_read(client.get(), buf, sizeof(buf));
8376 ASSERT_EQ(ret, -1);
8377 ASSERT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_WANT_READ);
8378
8379 ret = SSL_write(server.get(), kData, sizeof(kData));
8380 if (ret > 0) {
8381 ASSERT_EQ(ret, 5);
8382 break;
8383 }
8384 ASSERT_EQ(ret, -1);
8385 ASSERT_EQ(SSL_get_error(server.get(), ret), SSL_ERROR_WANT_WRITE);
8386 }
8387
8388 ret = SSL_read(client.get(), buf, sizeof(buf));
8389 ASSERT_EQ(ret, static_cast<int>(sizeof(kData)));
8390 ASSERT_EQ(Bytes(buf, ret), Bytes(kData));
8391}
8392
David Benjamin5cb597e2022-07-27 18:34:39 -07008393// Test that |SSL_ERROR_SYSCALL| continues to work after a close_notify.
8394TEST(SSLTest, ErrorSyscallAfterCloseNotify) {
8395 // Make a custom |BIO| where writes fail, but without pushing to the error
8396 // queue.
8397 bssl::UniquePtr<BIO_METHOD> method(BIO_meth_new(0, nullptr));
8398 ASSERT_TRUE(method);
8399 BIO_meth_set_create(method.get(), [](BIO *b) -> int {
8400 BIO_set_init(b, 1);
8401 return 1;
8402 });
8403 static bool write_failed = false;
8404 BIO_meth_set_write(method.get(), [](BIO *, const char *, int) -> int {
8405 // Fail the operation and don't add to the error queue.
8406 write_failed = true;
8407 return -1;
8408 });
8409 bssl::UniquePtr<BIO> wbio_silent_error(BIO_new(method.get()));
8410 ASSERT_TRUE(wbio_silent_error);
8411
8412 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
8413 bssl::UniquePtr<SSL_CTX> server_ctx =
8414 CreateContextWithTestCertificate(TLS_method());
8415 ASSERT_TRUE(client_ctx);
8416 ASSERT_TRUE(server_ctx);
8417 bssl::UniquePtr<SSL> client, server;
8418 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
8419 server_ctx.get()));
8420
8421 // Replace the write |BIO| with |wbio_silent_error|.
8422 SSL_set0_wbio(client.get(), wbio_silent_error.release());
8423
8424 // Writes should fail. There is nothing in the error queue, so
8425 // |SSL_ERROR_SYSCALL| indicates the caller needs to check out-of-band.
8426 const uint8_t data[1] = {0};
8427 int ret = SSL_write(client.get(), data, sizeof(data));
8428 EXPECT_EQ(ret, -1);
8429 EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_SYSCALL);
8430 EXPECT_TRUE(write_failed);
8431 write_failed = false;
8432
8433 // Send a close_notify from the server. It should return 0 because
8434 // close_notify was sent, but not received. Confusingly, this is a success
8435 // output for |SSL_shutdown|'s API.
8436 EXPECT_EQ(SSL_shutdown(server.get()), 0);
8437
8438 // Read the close_notify on the client.
8439 uint8_t buf[1];
8440 ret = SSL_read(client.get(), buf, sizeof(buf));
8441 EXPECT_EQ(ret, 0);
8442 EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_ZERO_RETURN);
8443
8444 // Although the client has seen close_notify, it should continue to report
8445 // |SSL_ERROR_SYSCALL| when its writes fail.
8446 ret = SSL_write(client.get(), data, sizeof(data));
8447 EXPECT_EQ(ret, -1);
8448 EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_SYSCALL);
8449 EXPECT_TRUE(write_failed);
8450 write_failed = false;
8451}
8452
Martin Kreichgauer72912d22017-08-04 12:06:43 -07008453} // namespace
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -07008454BSSL_NAMESPACE_END