blob: 0c6bf5019163d9b24a258cf7105297c69edc1a2d [file] [log] [blame]
David Benjamin2e521212014-07-16 14:37:51 -04001/* Copyright (c) 2014, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15#include <stdio.h>
David Benjamin751e8892014-10-19 00:59:36 -040016#include <string.h>
David Benjamin1269ddd2015-10-18 15:18:55 -040017#include <time.h>
David Benjamin2e521212014-07-16 14:37:51 -040018
David Benjamin0f653952015-10-18 14:28:01 -040019#include <algorithm>
Steven Valdezc8e0f902018-07-14 11:23:01 -040020#include <limits>
David Benjamin1d77e562015-03-22 17:22:08 -040021#include <string>
David Benjamin4f6acaf2015-11-21 03:00:50 -050022#include <utility>
David Benjamin1d77e562015-03-22 17:22:08 -040023#include <vector>
24
David Benjamin96628432017-01-19 19:05:47 -050025#include <gtest/gtest.h>
26
David Benjamin0e7dbd52019-05-15 16:01:18 -040027#include <openssl/aead.h>
David Benjamin751e8892014-10-19 00:59:36 -040028#include <openssl/base64.h>
29#include <openssl/bio.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040030#include <openssl/cipher.h>
David Benjamin7a1eefd2015-10-17 23:39:22 -040031#include <openssl/crypto.h>
Daniel McArdle00e434d2021-02-18 11:47:18 -050032#include <openssl/curve25519.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040033#include <openssl/err.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040034#include <openssl/hmac.h>
David Benjaminde942382016-02-11 12:02:01 -050035#include <openssl/pem.h>
David Benjamin25490f22016-07-14 00:22:54 -040036#include <openssl/sha.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040037#include <openssl/ssl.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040038#include <openssl/rand.h>
David Benjaminde942382016-02-11 12:02:01 -050039#include <openssl/x509.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040040
Steven Valdez87eab492016-06-27 16:34:59 -040041#include "internal.h"
Steven Valdezcb966542016-08-17 16:56:14 -040042#include "../crypto/internal.h"
Sigbjorn Vik2b23d242015-06-29 15:07:26 +020043#include "../crypto/test/test_util.h"
44
David Benjamin721e8b72016-08-03 13:13:17 -040045#if defined(OPENSSL_WINDOWS)
David Benjaminc11ea9422017-08-29 16:33:21 -040046// Windows defines struct timeval in winsock2.h.
David Benjamin721e8b72016-08-03 13:13:17 -040047OPENSSL_MSVC_PRAGMA(warning(push, 3))
48#include <winsock2.h>
49OPENSSL_MSVC_PRAGMA(warning(pop))
50#else
51#include <sys/time.h>
52#endif
53
David Benjamin5b33eff2018-09-22 16:52:48 -070054#if defined(OPENSSL_THREADS)
David Benjamin6c04bd12018-07-19 18:13:09 -040055#include <thread>
56#endif
57
David Benjamin1d77e562015-03-22 17:22:08 -040058
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -070059BSSL_NAMESPACE_BEGIN
Martin Kreichgauer72912d22017-08-04 12:06:43 -070060
61namespace {
62
Martin Kreichgauer1a663262017-08-16 14:54:04 -070063#define TRACED_CALL(code) \
64 do { \
65 SCOPED_TRACE("<- called from here"); \
66 code; \
67 if (::testing::Test::HasFatalFailure()) { \
68 return; \
69 } \
70 } while (false)
71
Martin Kreichgauer72912d22017-08-04 12:06:43 -070072struct VersionParam {
73 uint16_t version;
74 enum { is_tls, is_dtls } ssl_method;
75 const char name[8];
76};
77
78static const size_t kTicketKeyLen = 48;
79
80static const VersionParam kAllVersions[] = {
Martin Kreichgauer72912d22017-08-04 12:06:43 -070081 {TLS1_VERSION, VersionParam::is_tls, "TLS1"},
82 {TLS1_1_VERSION, VersionParam::is_tls, "TLS1_1"},
83 {TLS1_2_VERSION, VersionParam::is_tls, "TLS1_2"},
Martin Kreichgauer72912d22017-08-04 12:06:43 -070084 {TLS1_3_VERSION, VersionParam::is_tls, "TLS1_3"},
Martin Kreichgauer72912d22017-08-04 12:06:43 -070085 {DTLS1_VERSION, VersionParam::is_dtls, "DTLS1"},
86 {DTLS1_2_VERSION, VersionParam::is_dtls, "DTLS1_2"},
87};
88
David Benjamin1d77e562015-03-22 17:22:08 -040089struct ExpectedCipher {
90 unsigned long id;
David Benjaminbb0a17c2014-09-20 15:35:39 -040091 int in_group_flag;
David Benjamin1d77e562015-03-22 17:22:08 -040092};
David Benjaminbb0a17c2014-09-20 15:35:39 -040093
David Benjamin1d77e562015-03-22 17:22:08 -040094struct CipherTest {
95 // The rule string to apply.
David Benjaminbb0a17c2014-09-20 15:35:39 -040096 const char *rule;
David Benjaminfb974e62015-12-16 19:34:22 -050097 // The list of expected ciphers, in order.
98 std::vector<ExpectedCipher> expected;
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -080099 // True if this cipher list should fail in strict mode.
100 bool strict_fail;
David Benjamin1d77e562015-03-22 17:22:08 -0400101};
David Benjaminbb0a17c2014-09-20 15:35:39 -0400102
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100103struct CurveTest {
104 // The rule string to apply.
105 const char *rule;
106 // The list of expected curves, in order.
107 std::vector<uint16_t> expected;
108};
109
Steven Valdezc8e0f902018-07-14 11:23:01 -0400110template <typename T>
111class UnownedSSLExData {
112 public:
113 UnownedSSLExData() {
114 index_ = SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
115 }
116
117 T *Get(const SSL *ssl) {
118 return index_ < 0 ? nullptr
119 : static_cast<T *>(SSL_get_ex_data(ssl, index_));
120 }
121
122 bool Set(SSL *ssl, T *t) {
123 return index_ >= 0 && SSL_set_ex_data(ssl, index_, t);
124 }
125
126 private:
127 int index_;
128};
129
David Benjaminfb974e62015-12-16 19:34:22 -0500130static const CipherTest kCipherTests[] = {
131 // Selecting individual ciphers should work.
132 {
133 "ECDHE-ECDSA-CHACHA20-POLY1305:"
134 "ECDHE-RSA-CHACHA20-POLY1305:"
135 "ECDHE-ECDSA-AES128-GCM-SHA256:"
136 "ECDHE-RSA-AES128-GCM-SHA256",
137 {
138 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500139 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500140 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
141 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
142 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800143 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500144 },
145 // + reorders selected ciphers to the end, keeping their relative order.
146 {
147 "ECDHE-ECDSA-CHACHA20-POLY1305:"
148 "ECDHE-RSA-CHACHA20-POLY1305:"
149 "ECDHE-ECDSA-AES128-GCM-SHA256:"
150 "ECDHE-RSA-AES128-GCM-SHA256:"
151 "+aRSA",
152 {
153 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500154 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
155 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500156 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
157 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800158 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500159 },
160 // ! banishes ciphers from future selections.
161 {
162 "!aRSA:"
163 "ECDHE-ECDSA-CHACHA20-POLY1305:"
164 "ECDHE-RSA-CHACHA20-POLY1305:"
165 "ECDHE-ECDSA-AES128-GCM-SHA256:"
166 "ECDHE-RSA-AES128-GCM-SHA256",
167 {
168 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500169 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
170 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800171 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500172 },
173 // Multiple masks can be ANDed in a single rule.
174 {
175 "kRSA+AESGCM+AES128",
176 {
177 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
178 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800179 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500180 },
181 // - removes selected ciphers, but preserves their order for future
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700182 // selections. Select AES_128_GCM, but order the key exchanges RSA,
David Benjaminfb974e62015-12-16 19:34:22 -0500183 // ECDHE_RSA.
184 {
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700185 "ALL:-kECDHE:"
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700186 "-kRSA:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500187 "AESGCM+AES128+aRSA",
188 {
189 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500190 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
191 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800192 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500193 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800194 // Unknown selectors are no-ops, except in strict mode.
David Benjaminfb974e62015-12-16 19:34:22 -0500195 {
196 "ECDHE-ECDSA-CHACHA20-POLY1305:"
197 "ECDHE-RSA-CHACHA20-POLY1305:"
198 "ECDHE-ECDSA-AES128-GCM-SHA256:"
199 "ECDHE-RSA-AES128-GCM-SHA256:"
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800200 "BOGUS1",
David Benjaminfb974e62015-12-16 19:34:22 -0500201 {
202 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500203 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500204 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
205 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
206 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800207 true,
208 },
209 // Unknown selectors are no-ops, except in strict mode.
210 {
211 "ECDHE-ECDSA-CHACHA20-POLY1305:"
212 "ECDHE-RSA-CHACHA20-POLY1305:"
213 "ECDHE-ECDSA-AES128-GCM-SHA256:"
214 "ECDHE-RSA-AES128-GCM-SHA256:"
215 "-BOGUS2:+BOGUS3:!BOGUS4",
216 {
217 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
218 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
219 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
220 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
221 },
222 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500223 },
224 // Square brackets specify equi-preference groups.
225 {
226 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
227 "[ECDHE-RSA-CHACHA20-POLY1305]:"
228 "ECDHE-RSA-AES128-GCM-SHA256",
229 {
230 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
David Benjaminfb974e62015-12-16 19:34:22 -0500231 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley2e839242017-01-19 15:12:44 -0800232 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500233 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
234 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800235 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500236 },
David Benjamin6fff3862017-06-21 21:07:04 -0400237 // Standard names may be used instead of OpenSSL names.
238 {
239 "[TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256|"
David Benjaminbf5f1922017-07-01 11:13:53 -0400240 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256]:"
David Benjamin6fff3862017-06-21 21:07:04 -0400241 "[TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256]:"
242 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
243 {
244 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
245 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
246 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
247 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
248 },
249 false,
250 },
David Benjaminfb974e62015-12-16 19:34:22 -0500251 // @STRENGTH performs a stable strength-sort of the selected ciphers and
252 // only the selected ciphers.
253 {
254 // To simplify things, banish all but {ECDHE_RSA,RSA} x
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700255 // {CHACHA20,AES_256_CBC,AES_128_CBC} x SHA1.
David Benjamin6e678ee2018-04-16 19:54:42 -0400256 "!AESGCM:!3DES:"
David Benjaminfb974e62015-12-16 19:34:22 -0500257 // Order some ciphers backwards by strength.
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700258 "ALL:-CHACHA20:-AES256:-AES128:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500259 // Select ECDHE ones and sort them by strength. Ties should resolve
260 // based on the order above.
261 "kECDHE:@STRENGTH:-ALL:"
262 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
263 // by strength. Then RSA, backwards by strength.
264 "aRSA",
265 {
266 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
267 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500268 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500269 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
270 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
271 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800272 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500273 },
David Benjaminbf5f1922017-07-01 11:13:53 -0400274 // Additional masks after @STRENGTH get silently discarded.
275 //
276 // TODO(davidben): Make this an error. If not silently discarded, they get
277 // interpreted as + opcodes which are very different.
278 {
279 "ECDHE-RSA-AES128-GCM-SHA256:"
280 "ECDHE-RSA-AES256-GCM-SHA384:"
281 "@STRENGTH+AES256",
282 {
283 {TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
284 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
285 },
286 false,
287 },
288 {
289 "ECDHE-RSA-AES128-GCM-SHA256:"
290 "ECDHE-RSA-AES256-GCM-SHA384:"
291 "@STRENGTH+AES256:"
292 "ECDHE-RSA-CHACHA20-POLY1305",
293 {
294 {TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
295 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
296 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
297 },
298 false,
299 },
David Benjaminfb974e62015-12-16 19:34:22 -0500300 // Exact ciphers may not be used in multi-part rules; they are treated
301 // as unknown aliases.
302 {
303 "ECDHE-ECDSA-AES128-GCM-SHA256:"
304 "ECDHE-RSA-AES128-GCM-SHA256:"
305 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
306 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
307 {
308 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
309 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
310 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800311 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500312 },
313 // SSLv3 matches everything that existed before TLS 1.2.
314 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400315 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!SSLv3",
David Benjaminfb974e62015-12-16 19:34:22 -0500316 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400317 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500318 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800319 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500320 },
321 // TLSv1.2 matches everything added in TLS 1.2.
322 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400323 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!TLSv1.2",
David Benjaminfb974e62015-12-16 19:34:22 -0500324 {
325 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
326 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800327 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500328 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800329 // The two directives have no intersection. But each component is valid, so
330 // even in strict mode it is accepted.
David Benjaminfb974e62015-12-16 19:34:22 -0500331 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400332 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!TLSv1.2+SSLv3",
David Benjaminfb974e62015-12-16 19:34:22 -0500333 {
334 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400335 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500336 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800337 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500338 },
Adam Langley22df6912017-07-25 12:27:37 -0700339 // Spaces, semi-colons and commas are separators.
340 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400341 "AES128-SHA: ECDHE-RSA-AES128-GCM-SHA256 AES256-SHA ,ECDHE-ECDSA-AES128-GCM-SHA256 ; AES128-GCM-SHA256",
Adam Langley22df6912017-07-25 12:27:37 -0700342 {
343 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400344 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley22df6912017-07-25 12:27:37 -0700345 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400346 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley22df6912017-07-25 12:27:37 -0700347 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
348 },
349 // …but not in strict mode.
350 true,
351 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400352};
353
354static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400355 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400356 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
357 "RSA]",
358 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400359 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400360 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400361 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400362 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400363 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400364 "",
365 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400366 // COMPLEMENTOFDEFAULT is empty.
367 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400368 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400369 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400370 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400371 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
372 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
373 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
374 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
Adam Langleyf99f2442016-10-02 09:53:38 -0700375 // Opcode supplied, but missing selector.
376 "+",
Adam Langley22df6912017-07-25 12:27:37 -0700377 // Spaces are forbidden in equal-preference groups.
378 "[AES128-SHA | AES128-SHA256]",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400379};
380
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700381static const char *kMustNotIncludeNull[] = {
382 "ALL",
383 "DEFAULT",
David Benjamind6e9eec2015-11-18 09:48:55 -0500384 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700385 "FIPS",
386 "SHA",
387 "SHA1",
388 "RSA",
389 "SSLv3",
390 "TLSv1",
391 "TLSv1.2",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700392};
393
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100394static const CurveTest kCurveTests[] = {
395 {
396 "P-256",
397 { SSL_CURVE_SECP256R1 },
398 },
399 {
Adam Langley7b935932018-11-12 13:53:42 -0800400 "P-256:CECPQ2",
401 { SSL_CURVE_SECP256R1, SSL_CURVE_CECPQ2 },
402 },
403
404 {
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100405 "P-256:P-384:P-521:X25519",
406 {
407 SSL_CURVE_SECP256R1,
408 SSL_CURVE_SECP384R1,
409 SSL_CURVE_SECP521R1,
410 SSL_CURVE_X25519,
411 },
412 },
David Benjamin6dda1662017-11-02 20:44:26 -0400413 {
414 "prime256v1:secp384r1:secp521r1:x25519",
415 {
416 SSL_CURVE_SECP256R1,
417 SSL_CURVE_SECP384R1,
418 SSL_CURVE_SECP521R1,
419 SSL_CURVE_X25519,
420 },
421 },
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100422};
423
424static const char *kBadCurvesLists[] = {
425 "",
426 ":",
427 "::",
428 "P-256::X25519",
429 "RSA:P-256",
430 "P-256:RSA",
431 "X25519:P-256:",
432 ":X25519:P-256",
433};
434
David Benjamin70dbf042017-08-08 18:51:37 -0400435static std::string CipherListToString(SSL_CTX *ctx) {
David Benjamin1d77e562015-03-22 17:22:08 -0400436 bool in_group = false;
David Benjamine11726a2017-04-23 12:14:28 -0400437 std::string ret;
David Benjamin70dbf042017-08-08 18:51:37 -0400438 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
439 for (size_t i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
440 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
441 if (!in_group && SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400442 ret += "\t[\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400443 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400444 }
David Benjamine11726a2017-04-23 12:14:28 -0400445 ret += "\t";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400446 if (in_group) {
David Benjamine11726a2017-04-23 12:14:28 -0400447 ret += " ";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400448 }
David Benjamine11726a2017-04-23 12:14:28 -0400449 ret += SSL_CIPHER_get_name(cipher);
450 ret += "\n";
David Benjamin70dbf042017-08-08 18:51:37 -0400451 if (in_group && !SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400452 ret += "\t]\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400453 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400454 }
455 }
David Benjamine11726a2017-04-23 12:14:28 -0400456 return ret;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400457}
458
David Benjamin70dbf042017-08-08 18:51:37 -0400459static bool CipherListsEqual(SSL_CTX *ctx,
David Benjamine11726a2017-04-23 12:14:28 -0400460 const std::vector<ExpectedCipher> &expected) {
David Benjamin70dbf042017-08-08 18:51:37 -0400461 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
462 if (sk_SSL_CIPHER_num(ciphers) != expected.size()) {
David Benjamin1d77e562015-03-22 17:22:08 -0400463 return false;
David Benjamin65226252015-02-05 16:49:47 -0500464 }
465
David Benjamine11726a2017-04-23 12:14:28 -0400466 for (size_t i = 0; i < expected.size(); i++) {
David Benjamin70dbf042017-08-08 18:51:37 -0400467 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
David Benjamine11726a2017-04-23 12:14:28 -0400468 if (expected[i].id != SSL_CIPHER_get_id(cipher) ||
David Benjamin70dbf042017-08-08 18:51:37 -0400469 expected[i].in_group_flag != !!SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400470 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400471 }
472 }
473
David Benjamin1d77e562015-03-22 17:22:08 -0400474 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400475}
476
Daniel McArdleff746c12019-09-16 12:35:05 -0400477TEST(GrowableArrayTest, Resize) {
478 GrowableArray<size_t> array;
479 ASSERT_TRUE(array.empty());
480 EXPECT_EQ(array.size(), 0u);
481
482 ASSERT_TRUE(array.Push(42));
483 ASSERT_TRUE(!array.empty());
484 EXPECT_EQ(array.size(), 1u);
485
486 // Force a resize operation to occur
487 for (size_t i = 0; i < 16; i++) {
488 ASSERT_TRUE(array.Push(i + 1));
489 }
490
491 EXPECT_EQ(array.size(), 17u);
492
493 // Verify that expected values are still contained in array
494 for (size_t i = 0; i < array.size(); i++) {
495 EXPECT_EQ(array[i], i == 0 ? 42 : i);
496 }
497}
498
499TEST(GrowableArrayTest, MoveConstructor) {
500 GrowableArray<size_t> array;
501 for (size_t i = 0; i < 100; i++) {
502 ASSERT_TRUE(array.Push(i));
503 }
504
505 GrowableArray<size_t> array_moved(std::move(array));
506 for (size_t i = 0; i < 100; i++) {
507 EXPECT_EQ(array_moved[i], i);
508 }
509}
510
511TEST(GrowableArrayTest, GrowableArrayContainingGrowableArrays) {
512 // Representative example of a struct that contains a GrowableArray.
513 struct TagAndArray {
514 size_t tag;
515 GrowableArray<size_t> array;
516 };
517
518 GrowableArray<TagAndArray> array;
519 for (size_t i = 0; i < 100; i++) {
520 TagAndArray elem;
521 elem.tag = i;
522 for (size_t j = 0; j < i; j++) {
523 ASSERT_TRUE(elem.array.Push(j));
524 }
525 ASSERT_TRUE(array.Push(std::move(elem)));
526 }
527 EXPECT_EQ(array.size(), static_cast<size_t>(100));
528
529 GrowableArray<TagAndArray> array_moved(std::move(array));
530 EXPECT_EQ(array_moved.size(), static_cast<size_t>(100));
531 size_t count = 0;
532 for (const TagAndArray &elem : array_moved) {
533 // Test the square bracket operator returns the same value as iteration.
534 EXPECT_EQ(&elem, &array_moved[count]);
535
536 EXPECT_EQ(elem.tag, count);
537 EXPECT_EQ(elem.array.size(), count);
538 for (size_t j = 0; j < count; j++) {
539 EXPECT_EQ(elem.array[j], j);
540 }
541 count++;
542 }
543}
544
David Benjamine11726a2017-04-23 12:14:28 -0400545TEST(SSLTest, CipherRules) {
546 for (const CipherTest &t : kCipherTests) {
547 SCOPED_TRACE(t.rule);
548 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
549 ASSERT_TRUE(ctx);
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700550
David Benjamine11726a2017-04-23 12:14:28 -0400551 // Test lax mode.
552 ASSERT_TRUE(SSL_CTX_set_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400553 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400554 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400555 << CipherListToString(ctx.get());
David Benjamine11726a2017-04-23 12:14:28 -0400556
557 // Test strict mode.
558 if (t.strict_fail) {
559 EXPECT_FALSE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
560 } else {
561 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400562 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400563 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400564 << CipherListToString(ctx.get());
David Benjaminbb0a17c2014-09-20 15:35:39 -0400565 }
566 }
567
David Benjaminfb974e62015-12-16 19:34:22 -0500568 for (const char *rule : kBadRules) {
David Benjamine11726a2017-04-23 12:14:28 -0400569 SCOPED_TRACE(rule);
570 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
571 ASSERT_TRUE(ctx);
572
573 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), rule));
David Benjaminbb0a17c2014-09-20 15:35:39 -0400574 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400575 }
576
David Benjaminfb974e62015-12-16 19:34:22 -0500577 for (const char *rule : kMustNotIncludeNull) {
David Benjamine11726a2017-04-23 12:14:28 -0400578 SCOPED_TRACE(rule);
579 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
580 ASSERT_TRUE(ctx);
581
582 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400583 for (const SSL_CIPHER *cipher : SSL_CTX_get_ciphers(ctx.get())) {
David Benjamine3bb51c2017-08-22 23:16:02 -0700584 EXPECT_NE(NID_undef, SSL_CIPHER_get_cipher_nid(cipher));
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700585 }
586 }
David Benjaminbb0a17c2014-09-20 15:35:39 -0400587}
David Benjamin2e521212014-07-16 14:37:51 -0400588
David Benjamine11726a2017-04-23 12:14:28 -0400589TEST(SSLTest, CurveRules) {
590 for (const CurveTest &t : kCurveTests) {
591 SCOPED_TRACE(t.rule);
592 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
593 ASSERT_TRUE(ctx);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100594
David Benjamine11726a2017-04-23 12:14:28 -0400595 ASSERT_TRUE(SSL_CTX_set1_curves_list(ctx.get(), t.rule));
David Benjamin0ce090a2018-07-02 20:24:40 -0400596 ASSERT_EQ(t.expected.size(), ctx->supported_group_list.size());
David Benjamine11726a2017-04-23 12:14:28 -0400597 for (size_t i = 0; i < t.expected.size(); i++) {
598 EXPECT_EQ(t.expected[i], ctx->supported_group_list[i]);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100599 }
600 }
601
602 for (const char *rule : kBadCurvesLists) {
David Benjamine11726a2017-04-23 12:14:28 -0400603 SCOPED_TRACE(rule);
604 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
605 ASSERT_TRUE(ctx);
606
607 EXPECT_FALSE(SSL_CTX_set1_curves_list(ctx.get(), rule));
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100608 ERR_clear_error();
609 }
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100610}
611
Adam Langley364f7a62016-12-12 10:51:00 -0800612// kOpenSSLSession is a serialized SSL_SESSION.
Adam Langley10f97f32016-07-12 08:09:33 -0700613static const char kOpenSSLSession[] =
Adam Langley364f7a62016-12-12 10:51:00 -0800614 "MIIFqgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700615 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
616 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
617 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
618 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
619 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
620 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
621 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
622 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
623 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
624 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
625 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
626 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
627 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
628 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
629 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
630 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
631 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
632 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
633 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
634 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
635 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
636 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
637 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
638 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
639 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
640 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
641 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
642 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
643 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
Adam Langley364f7a62016-12-12 10:51:00 -0800644 "i4gv7Y5oliyntgMBAQA=";
Adam Langley10f97f32016-07-12 08:09:33 -0700645
646// kCustomSession is a custom serialized SSL_SESSION generated by
647// filling in missing fields from |kOpenSSLSession|. This includes
648// providing |peer_sha256|, so |peer| is not serialized.
649static const char kCustomSession[] =
David Benjamina8614602017-09-06 15:40:19 -0400650 "MIIBZAIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700651 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
David Benjamina8614602017-09-06 15:40:19 -0400652 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUqAcEBXdvcmxkqQUCAwGJwKqBpwSB"
653 "pBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38"
654 "VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd"
655 "3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hg"
656 "b+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYGBgYGBgYGBgYGBgYGBgYGBgYG"
657 "BgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
Adam Langley10f97f32016-07-12 08:09:33 -0700658
659// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
660static const char kBoringSSLSession[] =
661 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
662 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
663 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
664 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
665 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
666 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
667 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
668 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
669 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
670 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
671 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
672 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
673 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
674 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
675 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
676 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
677 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
678 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
679 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
680 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
681 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
682 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
683 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
684 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
685 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
686 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
687 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
688 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
689 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
690 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
691 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
692 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
693 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
694 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
695 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
696 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
697 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
698 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
699 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
700 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
701 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
702 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
703 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
704 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
705 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
706 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
707 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
708 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
709 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
710 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
711 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
712 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
713 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
714 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
715 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
716 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
717 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
718 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
719 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
720 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
721 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
722 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
723 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
724 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
725 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
726 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
727 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
728 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
729 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
730 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
731 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
732 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
733 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
734 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
735 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
736 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
737 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
738 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
739 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
740 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
741 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
742 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
743 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
744 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
745 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
746 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
747 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
748 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
749 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
750 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
751 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
752 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
753 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
754 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
755 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
756
757// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
Steven Valdez51607f12020-08-05 10:46:05 -0400758// the final (optional) element of |kCustomSession| with tag number 99.
Adam Langley10f97f32016-07-12 08:09:33 -0700759static const char kBadSessionExtraField[] =
760 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
761 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
762 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
763 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
764 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
765 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
766 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
Steven Valdez51607f12020-08-05 10:46:05 -0400767 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBOMDBAEF";
Adam Langley10f97f32016-07-12 08:09:33 -0700768
769// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
770// the version of |kCustomSession| with 2.
771static const char kBadSessionVersion[] =
772 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
773 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
774 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
775 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
776 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
777 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
778 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
779 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
780
781// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
782// appended.
783static const char kBadSessionTrailingData[] =
784 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
785 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
786 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
787 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
788 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
789 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
790 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
791 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
792
David Benjamin1d77e562015-03-22 17:22:08 -0400793static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400794 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400795 if (!EVP_DecodedLength(&len, strlen(in))) {
796 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400797 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400798 }
799
David Benjamin1d77e562015-03-22 17:22:08 -0400800 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800801 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400802 strlen(in))) {
803 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400804 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400805 }
David Benjamin1d77e562015-03-22 17:22:08 -0400806 out->resize(len);
807 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400808}
809
David Benjamina486c6c2019-03-28 18:32:38 -0500810TEST(SSLTest, SessionEncoding) {
811 for (const char *input_b64 : {
812 kOpenSSLSession,
813 kCustomSession,
814 kBoringSSLSession,
815 }) {
816 SCOPED_TRACE(std::string(input_b64));
817 // Decode the input.
818 std::vector<uint8_t> input;
819 ASSERT_TRUE(DecodeBase64(&input, input_b64));
David Benjamin751e8892014-10-19 00:59:36 -0400820
David Benjamina486c6c2019-03-28 18:32:38 -0500821 // Verify the SSL_SESSION decodes.
822 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
823 ASSERT_TRUE(ssl_ctx);
824 bssl::UniquePtr<SSL_SESSION> session(
825 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
826 ASSERT_TRUE(session) << "SSL_SESSION_from_bytes failed";
827
828 // Verify the SSL_SESSION encoding round-trips.
829 size_t encoded_len;
830 bssl::UniquePtr<uint8_t> encoded;
831 uint8_t *encoded_raw;
832 ASSERT_TRUE(SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len))
833 << "SSL_SESSION_to_bytes failed";
834 encoded.reset(encoded_raw);
835 EXPECT_EQ(Bytes(encoded.get(), encoded_len), Bytes(input))
836 << "SSL_SESSION_to_bytes did not round-trip";
837
838 // Verify the SSL_SESSION also decodes with the legacy API.
839 const uint8_t *cptr = input.data();
840 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
841 ASSERT_TRUE(session) << "d2i_SSL_SESSION failed";
842 EXPECT_EQ(cptr, input.data() + input.size());
843
844 // Verify the SSL_SESSION encoding round-trips via the legacy API.
845 int len = i2d_SSL_SESSION(session.get(), NULL);
846 ASSERT_GT(len, 0) << "i2d_SSL_SESSION failed";
847 ASSERT_EQ(static_cast<size_t>(len), input.size())
848 << "i2d_SSL_SESSION(NULL) returned invalid length";
849
850 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
851 ASSERT_TRUE(encoded);
852
853 uint8_t *ptr = encoded.get();
854 len = i2d_SSL_SESSION(session.get(), &ptr);
855 ASSERT_GT(len, 0) << "i2d_SSL_SESSION failed";
856 ASSERT_EQ(static_cast<size_t>(len), input.size())
857 << "i2d_SSL_SESSION(NULL) returned invalid length";
858 ASSERT_EQ(ptr, encoded.get() + input.size())
859 << "i2d_SSL_SESSION did not advance ptr correctly";
860 EXPECT_EQ(Bytes(encoded.get(), encoded_len), Bytes(input))
861 << "SSL_SESSION_to_bytes did not round-trip";
David Benjamin751e8892014-10-19 00:59:36 -0400862 }
863
David Benjamina486c6c2019-03-28 18:32:38 -0500864 for (const char *input_b64 : {
865 kBadSessionExtraField,
866 kBadSessionVersion,
867 kBadSessionTrailingData,
868 }) {
869 SCOPED_TRACE(std::string(input_b64));
870 std::vector<uint8_t> input;
871 ASSERT_TRUE(DecodeBase64(&input, input_b64));
David Benjamin751e8892014-10-19 00:59:36 -0400872
David Benjamina486c6c2019-03-28 18:32:38 -0500873 // Verify that the SSL_SESSION fails to decode.
874 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
875 ASSERT_TRUE(ssl_ctx);
876 bssl::UniquePtr<SSL_SESSION> session(
877 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
878 EXPECT_FALSE(session) << "SSL_SESSION_from_bytes unexpectedly succeeded";
879 ERR_clear_error();
David Benjamin3cac4502014-10-21 01:46:30 -0400880 }
David Benjaminf297e022015-05-28 19:55:29 -0400881}
882
David Benjamin321fcdc2017-04-24 11:42:42 -0400883static void ExpectDefaultVersion(uint16_t min_version, uint16_t max_version,
884 const SSL_METHOD *(*method)(void)) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700885 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
David Benjamin321fcdc2017-04-24 11:42:42 -0400886 ASSERT_TRUE(ctx);
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -0700887 EXPECT_EQ(min_version, SSL_CTX_get_min_proto_version(ctx.get()));
888 EXPECT_EQ(max_version, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjamin321fcdc2017-04-24 11:42:42 -0400889}
890
891TEST(SSLTest, DefaultVersion) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -0800892 ExpectDefaultVersion(TLS1_VERSION, TLS1_3_VERSION, &TLS_method);
David Benjamin321fcdc2017-04-24 11:42:42 -0400893 ExpectDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method);
894 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method);
895 ExpectDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method);
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -0700896 ExpectDefaultVersion(DTLS1_VERSION, DTLS1_2_VERSION, &DTLS_method);
897 ExpectDefaultVersion(DTLS1_VERSION, DTLS1_VERSION, &DTLSv1_method);
898 ExpectDefaultVersion(DTLS1_2_VERSION, DTLS1_2_VERSION, &DTLSv1_2_method);
David Benjamin82c9e902014-12-12 15:55:27 -0500899}
900
David Benjamin348f0d82017-08-10 16:06:27 -0400901TEST(SSLTest, CipherProperties) {
David Benjamin6fff3862017-06-21 21:07:04 -0400902 static const struct {
903 int id;
904 const char *standard_name;
David Benjamin348f0d82017-08-10 16:06:27 -0400905 int cipher_nid;
906 int digest_nid;
907 int kx_nid;
908 int auth_nid;
David Benjaminb1b76ae2017-09-21 17:03:34 -0400909 int prf_nid;
David Benjamin6fff3862017-06-21 21:07:04 -0400910 } kTests[] = {
David Benjamin348f0d82017-08-10 16:06:27 -0400911 {
912 SSL3_CK_RSA_DES_192_CBC3_SHA,
913 "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
914 NID_des_ede3_cbc,
915 NID_sha1,
916 NID_kx_rsa,
917 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400918 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400919 },
920 {
921 TLS1_CK_RSA_WITH_AES_128_SHA,
922 "TLS_RSA_WITH_AES_128_CBC_SHA",
923 NID_aes_128_cbc,
924 NID_sha1,
925 NID_kx_rsa,
926 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400927 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400928 },
929 {
930 TLS1_CK_PSK_WITH_AES_256_CBC_SHA,
931 "TLS_PSK_WITH_AES_256_CBC_SHA",
932 NID_aes_256_cbc,
933 NID_sha1,
934 NID_kx_psk,
935 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400936 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400937 },
938 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400939 TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA,
940 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
David Benjamin348f0d82017-08-10 16:06:27 -0400941 NID_aes_128_cbc,
David Benjamin6e678ee2018-04-16 19:54:42 -0400942 NID_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400943 NID_kx_ecdhe,
944 NID_auth_rsa,
David Benjamin6e678ee2018-04-16 19:54:42 -0400945 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400946 },
947 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400948 TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA,
949 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
David Benjamin348f0d82017-08-10 16:06:27 -0400950 NID_aes_256_cbc,
David Benjamin6e678ee2018-04-16 19:54:42 -0400951 NID_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400952 NID_kx_ecdhe,
953 NID_auth_rsa,
David Benjamin6e678ee2018-04-16 19:54:42 -0400954 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400955 },
956 {
957 TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
958 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
959 NID_aes_128_gcm,
960 NID_undef,
961 NID_kx_ecdhe,
962 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400963 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400964 },
965 {
966 TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
967 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
968 NID_aes_128_gcm,
969 NID_undef,
970 NID_kx_ecdhe,
971 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400972 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400973 },
974 {
975 TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
976 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
977 NID_aes_256_gcm,
978 NID_undef,
979 NID_kx_ecdhe,
980 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400981 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -0400982 },
983 {
984 TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
985 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
986 NID_aes_128_cbc,
987 NID_sha1,
988 NID_kx_ecdhe,
989 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400990 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400991 },
992 {
993 TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
994 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
995 NID_chacha20_poly1305,
996 NID_undef,
997 NID_kx_ecdhe,
998 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400999 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -04001000 },
1001 {
1002 TLS1_CK_AES_256_GCM_SHA384,
1003 "TLS_AES_256_GCM_SHA384",
1004 NID_aes_256_gcm,
1005 NID_undef,
1006 NID_kx_any,
1007 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001008 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -04001009 },
1010 {
1011 TLS1_CK_AES_128_GCM_SHA256,
1012 "TLS_AES_128_GCM_SHA256",
1013 NID_aes_128_gcm,
1014 NID_undef,
1015 NID_kx_any,
1016 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001017 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -04001018 },
1019 {
1020 TLS1_CK_CHACHA20_POLY1305_SHA256,
1021 "TLS_CHACHA20_POLY1305_SHA256",
1022 NID_chacha20_poly1305,
1023 NID_undef,
1024 NID_kx_any,
1025 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001026 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -04001027 },
David Benjamin6fff3862017-06-21 21:07:04 -04001028 };
David Benjamin65226252015-02-05 16:49:47 -05001029
David Benjamin6fff3862017-06-21 21:07:04 -04001030 for (const auto &t : kTests) {
1031 SCOPED_TRACE(t.standard_name);
David Benjamine11726a2017-04-23 12:14:28 -04001032
1033 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(t.id & 0xffff);
1034 ASSERT_TRUE(cipher);
David Benjamin6fff3862017-06-21 21:07:04 -04001035 EXPECT_STREQ(t.standard_name, SSL_CIPHER_standard_name(cipher));
1036
David Benjamine11726a2017-04-23 12:14:28 -04001037 bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
1038 ASSERT_TRUE(rfc_name);
David Benjamin6fff3862017-06-21 21:07:04 -04001039 EXPECT_STREQ(t.standard_name, rfc_name.get());
David Benjamin348f0d82017-08-10 16:06:27 -04001040
1041 EXPECT_EQ(t.cipher_nid, SSL_CIPHER_get_cipher_nid(cipher));
1042 EXPECT_EQ(t.digest_nid, SSL_CIPHER_get_digest_nid(cipher));
1043 EXPECT_EQ(t.kx_nid, SSL_CIPHER_get_kx_nid(cipher));
1044 EXPECT_EQ(t.auth_nid, SSL_CIPHER_get_auth_nid(cipher));
David Benjaminb1b76ae2017-09-21 17:03:34 -04001045 EXPECT_EQ(t.prf_nid, SSL_CIPHER_get_prf_nid(cipher));
David Benjamin65226252015-02-05 16:49:47 -05001046 }
David Benjamin65226252015-02-05 16:49:47 -05001047}
1048
Steven Valdeza833c352016-11-01 13:39:36 -04001049// CreateSessionWithTicket returns a sample |SSL_SESSION| with the specified
1050// version and ticket length or nullptr on failure.
1051static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(uint16_t version,
1052 size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -04001053 std::vector<uint8_t> der;
1054 if (!DecodeBase64(&der, kOpenSSLSession)) {
1055 return nullptr;
1056 }
Adam Langley46db7af2017-02-01 15:49:37 -08001057
1058 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
1059 if (!ssl_ctx) {
1060 return nullptr;
1061 }
David Benjaminaaef8332018-06-29 16:45:49 -04001062 // Use a garbage ticket.
1063 std::vector<uint8_t> ticket(ticket_len, 'a');
Steven Valdeza833c352016-11-01 13:39:36 -04001064 bssl::UniquePtr<SSL_SESSION> session(
Adam Langley46db7af2017-02-01 15:49:37 -08001065 SSL_SESSION_from_bytes(der.data(), der.size(), ssl_ctx.get()));
David Benjaminaaef8332018-06-29 16:45:49 -04001066 if (!session ||
1067 !SSL_SESSION_set_protocol_version(session.get(), version) ||
1068 !SSL_SESSION_set_ticket(session.get(), ticket.data(), ticket.size())) {
David Benjamin422fe082015-07-21 22:03:43 -04001069 return nullptr;
1070 }
David Benjamin1269ddd2015-10-18 15:18:55 -04001071 // Fix up the timeout.
David Benjamin9b63f292016-11-15 00:44:05 -05001072#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
David Benjaminaaef8332018-06-29 16:45:49 -04001073 SSL_SESSION_set_time(session.get(), 1234);
David Benjamin9b63f292016-11-15 00:44:05 -05001074#else
David Benjaminaaef8332018-06-29 16:45:49 -04001075 SSL_SESSION_set_time(session.get(), time(nullptr));
David Benjamin9b63f292016-11-15 00:44:05 -05001076#endif
David Benjamin422fe082015-07-21 22:03:43 -04001077 return session;
1078}
1079
David Benjaminafc64de2016-07-19 17:12:41 +02001080static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001081 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +02001082 if (!bio) {
1083 return false;
1084 }
1085 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -04001086 BIO_up_ref(bio.get());
1087 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +02001088 int ret = SSL_connect(ssl);
1089 if (ret > 0) {
1090 // SSL_connect should fail without a BIO to write to.
1091 return false;
1092 }
1093 ERR_clear_error();
1094
1095 const uint8_t *client_hello;
1096 size_t client_hello_len;
1097 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
1098 return false;
1099 }
1100 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
1101 return true;
1102}
1103
Steven Valdeza833c352016-11-01 13:39:36 -04001104// GetClientHelloLen creates a client SSL connection with the specified version
1105// and ticket length. It returns the length of the ClientHello, not including
1106// the record header, on success and zero on error.
1107static size_t GetClientHelloLen(uint16_t max_version, uint16_t session_version,
1108 size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001109 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Steven Valdeza833c352016-11-01 13:39:36 -04001110 bssl::UniquePtr<SSL_SESSION> session =
1111 CreateSessionWithTicket(session_version, ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -04001112 if (!ctx || !session) {
1113 return 0;
1114 }
Steven Valdeza833c352016-11-01 13:39:36 -04001115
1116 // Set a one-element cipher list so the baseline ClientHello is unpadded.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001117 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
Steven Valdez2c62fe92016-10-14 12:08:12 -04001118 if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -08001119 !SSL_set_strict_cipher_list(ssl.get(), "ECDHE-RSA-AES128-GCM-SHA256") ||
Steven Valdeza833c352016-11-01 13:39:36 -04001120 !SSL_set_max_proto_version(ssl.get(), max_version)) {
David Benjamin422fe082015-07-21 22:03:43 -04001121 return 0;
1122 }
Steven Valdeza833c352016-11-01 13:39:36 -04001123
David Benjaminafc64de2016-07-19 17:12:41 +02001124 std::vector<uint8_t> client_hello;
1125 if (!GetClientHello(ssl.get(), &client_hello) ||
1126 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -04001127 return 0;
1128 }
Steven Valdeza833c352016-11-01 13:39:36 -04001129
David Benjaminafc64de2016-07-19 17:12:41 +02001130 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -04001131}
1132
David Benjamina486c6c2019-03-28 18:32:38 -05001133TEST(SSLTest, Padding) {
1134 struct PaddingVersions {
1135 uint16_t max_version, session_version;
1136 };
1137 static const PaddingVersions kPaddingVersions[] = {
1138 // Test the padding extension at TLS 1.2.
1139 {TLS1_2_VERSION, TLS1_2_VERSION},
1140 // Test the padding extension at TLS 1.3 with a TLS 1.2 session, so there
1141 // will be no PSK binder after the padding extension.
1142 {TLS1_3_VERSION, TLS1_2_VERSION},
1143 // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
1144 // will be a PSK binder after the padding extension.
1145 {TLS1_3_VERSION, TLS1_3_VERSION},
David Benjamin422fe082015-07-21 22:03:43 -04001146
David Benjamina486c6c2019-03-28 18:32:38 -05001147 };
David Benjamin422fe082015-07-21 22:03:43 -04001148
David Benjamina486c6c2019-03-28 18:32:38 -05001149 struct PaddingTest {
1150 size_t input_len, padded_len;
1151 };
1152 static const PaddingTest kPaddingTests[] = {
1153 // ClientHellos of length below 0x100 do not require padding.
1154 {0xfe, 0xfe},
1155 {0xff, 0xff},
1156 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
1157 {0x100, 0x200},
1158 {0x123, 0x200},
1159 {0x1fb, 0x200},
1160 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
1161 // padding extension takes a minimum of four bytes plus one required
1162 // content
1163 // byte. (To work around yet more server bugs, we avoid empty final
1164 // extensions.)
1165 {0x1fc, 0x201},
1166 {0x1fd, 0x202},
1167 {0x1fe, 0x203},
1168 {0x1ff, 0x204},
1169 // Finally, larger ClientHellos need no padding.
1170 {0x200, 0x200},
1171 {0x201, 0x201},
1172 };
David Benjamin422fe082015-07-21 22:03:43 -04001173
David Benjamina486c6c2019-03-28 18:32:38 -05001174 for (const PaddingVersions &versions : kPaddingVersions) {
1175 SCOPED_TRACE(versions.max_version);
1176 SCOPED_TRACE(versions.session_version);
David Benjamin422fe082015-07-21 22:03:43 -04001177
David Benjamina486c6c2019-03-28 18:32:38 -05001178 // Sample a baseline length.
1179 size_t base_len =
1180 GetClientHelloLen(versions.max_version, versions.session_version, 1);
1181 ASSERT_NE(base_len, 0u) << "Baseline length could not be sampled";
1182
1183 for (const PaddingTest &test : kPaddingTests) {
1184 SCOPED_TRACE(test.input_len);
1185 ASSERT_LE(base_len, test.input_len) << "Baseline ClientHello too long";
1186
1187 size_t padded_len =
1188 GetClientHelloLen(versions.max_version, versions.session_version,
1189 1 + test.input_len - base_len);
1190 EXPECT_EQ(padded_len, test.padded_len)
1191 << "ClientHello was not padded to expected length";
David Benjamin422fe082015-07-21 22:03:43 -04001192 }
1193 }
David Benjamin422fe082015-07-21 22:03:43 -04001194}
1195
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001196static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001197 static const char kCertPEM[] =
1198 "-----BEGIN CERTIFICATE-----\n"
1199 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1200 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1201 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1202 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1203 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1204 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1205 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1206 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1207 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1208 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1209 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1210 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1211 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1212 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001213 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
David Benjamin1444c3a2016-12-20 17:23:11 -05001214 return bssl::UniquePtr<X509>(
1215 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjaminde942382016-02-11 12:02:01 -05001216}
1217
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001218static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001219 static const char kKeyPEM[] =
1220 "-----BEGIN RSA PRIVATE KEY-----\n"
1221 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1222 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1223 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1224 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1225 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1226 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1227 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1228 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1229 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1230 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1231 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1232 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1233 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1234 "-----END RSA PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001235 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1236 return bssl::UniquePtr<EVP_PKEY>(
David Benjaminde942382016-02-11 12:02:01 -05001237 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1238}
1239
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001240static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001241 static const char kCertPEM[] =
1242 "-----BEGIN CERTIFICATE-----\n"
1243 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1244 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1245 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1246 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1247 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1248 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1249 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1250 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1251 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1252 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1253 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001254 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1255 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjamin0fc37ef2016-08-17 15:29:46 -04001256}
1257
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001258static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001259 static const char kKeyPEM[] =
1260 "-----BEGIN PRIVATE KEY-----\n"
1261 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1262 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1263 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1264 "-----END PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001265 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1266 return bssl::UniquePtr<EVP_PKEY>(
David Benjamin0fc37ef2016-08-17 15:29:46 -04001267 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1268}
1269
Adam Langleyd04ca952017-02-28 11:26:51 -08001270static bssl::UniquePtr<CRYPTO_BUFFER> BufferFromPEM(const char *pem) {
1271 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1272 char *name, *header;
1273 uint8_t *data;
1274 long data_len;
1275 if (!PEM_read_bio(bio.get(), &name, &header, &data,
1276 &data_len)) {
1277 return nullptr;
1278 }
1279 OPENSSL_free(name);
1280 OPENSSL_free(header);
1281
1282 auto ret = bssl::UniquePtr<CRYPTO_BUFFER>(
1283 CRYPTO_BUFFER_new(data, data_len, nullptr));
1284 OPENSSL_free(data);
1285 return ret;
1286}
1287
1288static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestCertificateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001289 static const char kCertPEM[] =
1290 "-----BEGIN CERTIFICATE-----\n"
1291 "MIIC0jCCAbqgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQiBD\n"
1292 "QTAeFw0xNjAyMjgyMDI3MDNaFw0yNjAyMjUyMDI3MDNaMBgxFjAUBgNVBAMMDUNs\n"
1293 "aWVudCBDZXJ0IEEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRvaz8\n"
1294 "CC/cshpCafJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/\n"
1295 "kLRcH89M/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3\n"
1296 "tHb+xs2PSs8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+c\n"
1297 "IDs2rQ+lP7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1\n"
1298 "z7C8jU50Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9V\n"
1299 "iLeXANgZi+Xx9KgfAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI\n"
1300 "KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBFEVbmYl+2RtNw\n"
1301 "rDftRDF1v2QUbcN2ouSnQDHxeDQdSgasLzT3ui8iYu0Rw2WWcZ0DV5e0ztGPhWq7\n"
1302 "AO0B120aFRMOY+4+bzu9Q2FFkQqc7/fKTvTDzIJI5wrMnFvUfzzvxh3OHWMYSs/w\n"
1303 "giq33hTKeHEq6Jyk3btCny0Ycecyc3yGXH10sizUfiHlhviCkDuESk8mFDwDDzqW\n"
1304 "ZF0IipzFbEDHoIxLlm3GQxpiLoEV4k8KYJp3R5KBLFyxM6UGPz8h72mIPCJp2RuK\n"
1305 "MYgF91UDvVzvnYm6TfseM2+ewKirC00GOrZ7rEcFvtxnKSqYf4ckqfNdSU1Y+RRC\n"
1306 "1ngWZ7Ih\n"
1307 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001308 return BufferFromPEM(kCertPEM);
David Benjamin1444c3a2016-12-20 17:23:11 -05001309}
1310
Adam Langleyd04ca952017-02-28 11:26:51 -08001311static bssl::UniquePtr<X509> X509FromBuffer(
1312 bssl::UniquePtr<CRYPTO_BUFFER> buffer) {
1313 if (!buffer) {
1314 return nullptr;
1315 }
1316 const uint8_t *derp = CRYPTO_BUFFER_data(buffer.get());
1317 return bssl::UniquePtr<X509>(
1318 d2i_X509(NULL, &derp, CRYPTO_BUFFER_len(buffer.get())));
1319}
1320
1321static bssl::UniquePtr<X509> GetChainTestCertificate() {
1322 return X509FromBuffer(GetChainTestCertificateBuffer());
1323}
1324
1325static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestIntermediateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001326 static const char kCertPEM[] =
1327 "-----BEGIN CERTIFICATE-----\n"
1328 "MIICwjCCAaqgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS\n"
1329 "b290IENBMB4XDTE2MDIyODIwMjcwM1oXDTI2MDIyNTIwMjcwM1owDzENMAsGA1UE\n"
1330 "AwwEQiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALsSCYmDip2D\n"
1331 "GkjFxw7ykz26JSjELkl6ArlYjFJ3aT/SCh8qbS4gln7RH8CPBd78oFdfhIKQrwtZ\n"
1332 "3/q21ykD9BAS3qHe2YdcJfm8/kWAy5DvXk6NXU4qX334KofBAEpgdA/igEFq1P1l\n"
1333 "HAuIfZCpMRfT+i5WohVsGi8f/NgpRvVaMONLNfgw57mz1lbtFeBEISmX0kbsuJxF\n"
1334 "Qj/Bwhi5/0HAEXG8e7zN4cEx0yPRvmOATRdVb/8dW2pwOHRJq9R5M0NUkIsTSnL7\n"
1335 "6N/z8hRAHMsV3IudC5Yd7GXW1AGu9a+iKU+Q4xcZCoj0DC99tL4VKujrV1kAeqsM\n"
1336 "cz5/dKzi6+cCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
1337 "AQYwDQYJKoZIhvcNAQELBQADggEBAIIeZiEeNhWWQ8Y4D+AGDwqUUeG8NjCbKrXQ\n"
1338 "BlHg5wZ8xftFaiP1Dp/UAezmx2LNazdmuwrYB8lm3FVTyaPDTKEGIPS4wJKHgqH1\n"
1339 "QPDhqNm85ey7TEtI9oYjsNim/Rb+iGkIAMXaxt58SzxbjvP0kMr1JfJIZbic9vye\n"
1340 "NwIspMFIpP3FB8ywyu0T0hWtCQgL4J47nigCHpOu58deP88fS/Nyz/fyGVWOZ76b\n"
1341 "WhWwgM3P3X95fQ3d7oFPR/bVh0YV+Cf861INwplokXgXQ3/TCQ+HNXeAMWn3JLWv\n"
1342 "XFwk8owk9dq/kQGdndGgy3KTEW4ctPX5GNhf3LJ9Q7dLji4ReQ4=\n"
1343 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001344 return BufferFromPEM(kCertPEM);
1345}
1346
1347static bssl::UniquePtr<X509> GetChainTestIntermediate() {
1348 return X509FromBuffer(GetChainTestIntermediateBuffer());
David Benjamin1444c3a2016-12-20 17:23:11 -05001349}
1350
1351static bssl::UniquePtr<EVP_PKEY> GetChainTestKey() {
1352 static const char kKeyPEM[] =
1353 "-----BEGIN PRIVATE KEY-----\n"
1354 "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRvaz8CC/cshpC\n"
1355 "afJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/kLRcH89M\n"
1356 "/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3tHb+xs2P\n"
1357 "Ss8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+cIDs2rQ+l\n"
1358 "P7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1z7C8jU50\n"
1359 "Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9ViLeXANgZ\n"
1360 "i+Xx9KgfAgMBAAECggEBAK0VjSJzkyPaamcyTVSWjo7GdaBGcK60lk657RjR+lK0\n"
1361 "YJ7pkej4oM2hdsVZFsP8Cs4E33nXLa/0pDsRov/qrp0WQm2skwqGMC1I/bZ0WRPk\n"
1362 "wHaDrBBfESWnJDX/AGpVtlyOjPmgmK6J2usMPihQUDkKdAYrVWJePrMIxt1q6BMe\n"
1363 "iczs3qriMmtY3bUc4UyUwJ5fhDLjshHvfuIpYQyI6EXZM6dZksn9LylXJnigY6QJ\n"
1364 "HxOYO0BDwOsZ8yQ8J8afLk88i0GizEkgE1z3REtQUwgWfxr1WV/ud+T6/ZhSAgH9\n"
1365 "042mQvSFZnIUSEsmCvjhWuAunfxHKCTcAoYISWfzWpkCgYEA7gpf3HHU5Tn+CgUn\n"
1366 "1X5uGpG3DmcMgfeGgs2r2f/IIg/5Ac1dfYILiybL1tN9zbyLCJfcbFpWBc9hJL6f\n"
1367 "CPc5hUiwWFJqBJewxQkC1Ae/HakHbip+IZ+Jr0842O4BAArvixk4Lb7/N2Ct9sTE\n"
1368 "NJO6RtK9lbEZ5uK61DglHy8CS2UCgYEA4ZC1o36kPAMQBggajgnucb2yuUEelk0f\n"
1369 "AEr+GI32MGE+93xMr7rAhBoqLg4AITyIfEnOSQ5HwagnIHonBbv1LV/Gf9ursx8Z\n"
1370 "YOGbvT8zzzC+SU1bkDzdjAYnFQVGIjMtKOBJ3K07++ypwX1fr4QsQ8uKL8WSOWwt\n"
1371 "Z3Bym6XiZzMCgYADnhy+2OwHX85AkLt+PyGlPbmuelpyTzS4IDAQbBa6jcuW/2wA\n"
1372 "UE2km75VUXmD+u2R/9zVuLm99NzhFhSMqlUxdV1YukfqMfP5yp1EY6m/5aW7QuIP\n"
1373 "2MDa7TVL9rIFMiVZ09RKvbBbQxjhuzPQKL6X/PPspnhiTefQ+dl2k9xREQKBgHDS\n"
1374 "fMfGNEeAEKezrfSVqxphE9/tXms3L+ZpnCaT+yu/uEr5dTIAawKoQ6i9f/sf1/Sy\n"
1375 "xedsqR+IB+oKrzIDDWMgoJybN4pkZ8E5lzhVQIjFjKgFdWLzzqyW9z1gYfABQPlN\n"
1376 "FiS20WX0vgP1vcKAjdNrHzc9zyHBpgQzDmAj3NZZAoGBAI8vKCKdH7w3aL5CNkZQ\n"
1377 "2buIeWNA2HZazVwAGG5F2TU/LmXfRKnG6dX5bkU+AkBZh56jNZy//hfFSewJB4Kk\n"
1378 "buB7ERSdaNbO21zXt9FEA3+z0RfMd/Zv2vlIWOSB5nzl/7UKti3sribK6s9ZVLfi\n"
1379 "SxpiPQ8d/hmSGwn4ksrWUsJD\n"
1380 "-----END PRIVATE KEY-----\n";
1381 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1382 return bssl::UniquePtr<EVP_PKEY>(
1383 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1384}
1385
David Benjaminc79ae7a2017-08-29 16:09:44 -04001386// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
1387// before configuring as a server.
1388TEST(SSLTest, ClientCAList) {
1389 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1390 ASSERT_TRUE(ctx);
1391 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1392 ASSERT_TRUE(ssl);
1393
1394 bssl::UniquePtr<X509_NAME> name(X509_NAME_new());
1395 ASSERT_TRUE(name);
1396
1397 bssl::UniquePtr<X509_NAME> name_dup(X509_NAME_dup(name.get()));
1398 ASSERT_TRUE(name_dup);
1399
1400 bssl::UniquePtr<STACK_OF(X509_NAME)> stack(sk_X509_NAME_new_null());
1401 ASSERT_TRUE(stack);
David Benjamin2908dd12018-06-29 17:46:42 -04001402 ASSERT_TRUE(PushToStack(stack.get(), std::move(name_dup)));
David Benjaminc79ae7a2017-08-29 16:09:44 -04001403
1404 // |SSL_set_client_CA_list| takes ownership.
1405 SSL_set_client_CA_list(ssl.get(), stack.release());
1406
1407 STACK_OF(X509_NAME) *result = SSL_get_client_CA_list(ssl.get());
1408 ASSERT_TRUE(result);
1409 ASSERT_EQ(1u, sk_X509_NAME_num(result));
1410 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(result, 0), name.get()));
1411}
1412
1413TEST(SSLTest, AddClientCA) {
1414 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1415 ASSERT_TRUE(ctx);
1416 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1417 ASSERT_TRUE(ssl);
1418
1419 bssl::UniquePtr<X509> cert1 = GetTestCertificate();
1420 bssl::UniquePtr<X509> cert2 = GetChainTestCertificate();
1421 ASSERT_TRUE(cert1 && cert2);
1422 X509_NAME *name1 = X509_get_subject_name(cert1.get());
1423 X509_NAME *name2 = X509_get_subject_name(cert2.get());
1424
1425 EXPECT_EQ(0u, sk_X509_NAME_num(SSL_get_client_CA_list(ssl.get())));
1426
1427 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1428 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert2.get()));
1429
1430 STACK_OF(X509_NAME) *list = SSL_get_client_CA_list(ssl.get());
1431 ASSERT_EQ(2u, sk_X509_NAME_num(list));
1432 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1433 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1434
1435 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1436
1437 list = SSL_get_client_CA_list(ssl.get());
1438 ASSERT_EQ(3u, sk_X509_NAME_num(list));
1439 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1440 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1441 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 2), name1));
1442}
1443
Daniel McArdle00e434d2021-02-18 11:47:18 -05001444// kECHConfig contains a serialized ECHConfig value.
1445static const uint8_t kECHConfig[] = {
1446 // version
1447 0xfe, 0x09,
1448 // length
1449 0x00, 0x42,
1450 // contents.public_name
1451 0x00, 0x0e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2e, 0x65, 0x78, 0x61,
1452 0x6d, 0x70, 0x6c, 0x65,
1453 // contents.public_key
1454 0x00, 0x20, 0xa6, 0x9a, 0x41, 0x48, 0x5d, 0x32, 0x96, 0xa4, 0xe0, 0xc3,
1455 0x6a, 0xee, 0xf6, 0x63, 0x0f, 0x59, 0x32, 0x6f, 0xdc, 0xff, 0x81, 0x29,
1456 0x59, 0xa5, 0x85, 0xd3, 0x9b, 0x3b, 0xde, 0x98, 0x55, 0x5c,
1457 // contents.kem_id
1458 0x00, 0x20,
1459 // contents.cipher_suites
1460 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x03,
1461 // contents.maximum_name_length
1462 0x00, 0x10,
1463 // contents.extensions
1464 0x00, 0x00};
1465
1466// kECHConfigPublicKey is the public key encoded in |kECHConfig|.
1467static const uint8_t kECHConfigPublicKey[X25519_PUBLIC_VALUE_LEN] = {
1468 0xa6, 0x9a, 0x41, 0x48, 0x5d, 0x32, 0x96, 0xa4, 0xe0, 0xc3, 0x6a,
1469 0xee, 0xf6, 0x63, 0x0f, 0x59, 0x32, 0x6f, 0xdc, 0xff, 0x81, 0x29,
1470 0x59, 0xa5, 0x85, 0xd3, 0x9b, 0x3b, 0xde, 0x98, 0x55, 0x5c};
1471
1472// kECHConfigPrivateKey is the X25519 private key corresponding to
1473// |kECHConfigPublicKey|.
1474static const uint8_t kECHConfigPrivateKey[X25519_PRIVATE_KEY_LEN] = {
1475 0xbc, 0xb5, 0x51, 0x29, 0x31, 0x10, 0x30, 0xc9, 0xed, 0x26, 0xde,
1476 0xd4, 0xb3, 0xdf, 0x3a, 0xce, 0x06, 0x8a, 0xee, 0x17, 0xab, 0xce,
1477 0xd7, 0xdb, 0xf3, 0x11, 0xe5, 0xa8, 0xf3, 0xb1, 0x8e, 0x24};
1478
1479// MakeECHConfig serializes an ECHConfig and writes it to |*out| with the
1480// specified parameters. |cipher_suites| is a list of code points which should
1481// contain pairs of KDF and AEAD IDs.
1482bool MakeECHConfig(std::vector<uint8_t> *out, uint16_t kem_id,
1483 Span<const uint8_t> public_key,
1484 Span<const uint16_t> cipher_suites,
1485 Span<const uint8_t> extensions) {
1486 bssl::ScopedCBB cbb;
1487 CBB contents, child;
1488 static const char kPublicName[] = "example.com";
1489 if (!CBB_init(cbb.get(), 64) ||
1490 !CBB_add_u16(cbb.get(), TLSEXT_TYPE_encrypted_client_hello) ||
1491 !CBB_add_u16_length_prefixed(cbb.get(), &contents) ||
1492 !CBB_add_u16_length_prefixed(&contents, &child) ||
1493 !CBB_add_bytes(&child, reinterpret_cast<const uint8_t *>(kPublicName),
1494 strlen(kPublicName)) ||
1495 !CBB_add_u16_length_prefixed(&contents, &child) ||
1496 !CBB_add_bytes(&child, public_key.data(), public_key.size()) ||
1497 !CBB_add_u16(&contents, kem_id) ||
1498 !CBB_add_u16_length_prefixed(&contents, &child)) {
1499 return false;
1500 }
1501 for (uint16_t cipher_suite : cipher_suites) {
1502 if (!CBB_add_u16(&child, cipher_suite)) {
1503 return false;
1504 }
1505 }
1506 if (!CBB_add_u16(&contents, strlen(kPublicName)) || // maximum_name_length
1507 !CBB_add_u16_length_prefixed(&contents, &child) ||
1508 !CBB_add_bytes(&child, extensions.data(), extensions.size()) ||
1509 !CBB_flush(cbb.get())) {
1510 return false;
1511 }
1512
1513 out->assign(CBB_data(cbb.get()), CBB_data(cbb.get()) + CBB_len(cbb.get()));
1514 return true;
1515}
1516
1517TEST(SSLTest, ECHServerConfigList) {
1518 // kWrongPrivateKey is an unrelated, but valid X25519 private key.
1519 const uint8_t kWrongPrivateKey[X25519_PRIVATE_KEY_LEN] = {
1520 0xbb, 0xfe, 0x08, 0xf7, 0x31, 0xde, 0x9c, 0x8a, 0xf2, 0x06, 0x4a,
1521 0x18, 0xd7, 0x8b, 0x79, 0x31, 0xe2, 0x53, 0xdd, 0x63, 0x8f, 0x58,
1522 0x42, 0xda, 0x21, 0x0e, 0x61, 0x97, 0x29, 0xcc, 0x17, 0x71};
1523
1524 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1525 ASSERT_TRUE(ctx);
1526
1527 bssl::UniquePtr<SSL_ECH_SERVER_CONFIG_LIST> config_list(
1528 SSL_ECH_SERVER_CONFIG_LIST_new());
1529 ASSERT_TRUE(config_list);
1530
1531 // Adding an ECHConfig with the wrong private key is an error.
1532 ASSERT_FALSE(SSL_ECH_SERVER_CONFIG_LIST_add(
1533 config_list.get(), /*is_retry_config=*/1, kECHConfig, sizeof(kECHConfig),
1534 kWrongPrivateKey, sizeof(kWrongPrivateKey)));
1535 uint32_t err = ERR_get_error();
1536 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
1537 EXPECT_EQ(SSL_R_ECH_SERVER_CONFIG_AND_PRIVATE_KEY_MISMATCH,
1538 ERR_GET_REASON(err));
1539 ERR_clear_error();
1540
1541 // Adding an ECHConfig with the matching private key succeeds.
1542 ASSERT_TRUE(SSL_ECH_SERVER_CONFIG_LIST_add(
1543 config_list.get(), /*is_retry_config=*/1, kECHConfig, sizeof(kECHConfig),
1544 kECHConfigPrivateKey, sizeof(kECHConfigPrivateKey)));
1545
1546 ASSERT_TRUE(
1547 SSL_CTX_set1_ech_server_config_list(ctx.get(), config_list.get()));
1548
1549 // Build a new config list and replace the old one on |ctx|.
1550 bssl::UniquePtr<SSL_ECH_SERVER_CONFIG_LIST> next_config_list(
1551 SSL_ECH_SERVER_CONFIG_LIST_new());
1552 ASSERT_TRUE(SSL_ECH_SERVER_CONFIG_LIST_add(
1553 next_config_list.get(), /*is_retry_config=*/1, kECHConfig,
1554 sizeof(kECHConfig), kECHConfigPrivateKey, sizeof(kECHConfigPrivateKey)));
1555 ASSERT_TRUE(
1556 SSL_CTX_set1_ech_server_config_list(ctx.get(), next_config_list.get()));
1557}
1558
1559TEST(SSLTest, ECHServerConfigListTruncatedPublicKey) {
1560 std::vector<uint8_t> ech_config;
1561 ASSERT_TRUE(MakeECHConfig(
1562 &ech_config, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
1563 MakeConstSpan(kECHConfigPublicKey, sizeof(kECHConfigPublicKey) - 1),
1564 std::vector<uint16_t>{EVP_HPKE_HKDF_SHA256, EVP_HPKE_AEAD_AES_128_GCM},
1565 /*extensions=*/{}));
1566
1567 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1568 ASSERT_TRUE(ctx);
1569
1570 bssl::UniquePtr<SSL_ECH_SERVER_CONFIG_LIST> config_list(
1571 SSL_ECH_SERVER_CONFIG_LIST_new());
1572 ASSERT_TRUE(config_list);
1573 ASSERT_FALSE(SSL_ECH_SERVER_CONFIG_LIST_add(
1574 config_list.get(), /*is_retry_config=*/1, ech_config.data(),
1575 ech_config.size(), kECHConfigPrivateKey, sizeof(kECHConfigPrivateKey)));
1576
1577 uint32_t err = ERR_peek_error();
1578 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
1579 EXPECT_EQ(SSL_R_UNSUPPORTED_ECH_SERVER_CONFIG, ERR_GET_REASON(err));
1580 ERR_clear_error();
1581}
1582
1583// Test that |SSL_CTX_set1_ech_server_config_list| fails when the config list
1584// has no retry configs.
1585TEST(SSLTest, ECHServerConfigsWithoutRetryConfigs) {
1586 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1587 ASSERT_TRUE(ctx);
1588
1589 bssl::UniquePtr<SSL_ECH_SERVER_CONFIG_LIST> config_list(
1590 SSL_ECH_SERVER_CONFIG_LIST_new());
1591 ASSERT_TRUE(config_list);
1592
1593 // Adding an ECHConfig with the matching private key succeeds.
1594 ASSERT_TRUE(SSL_ECH_SERVER_CONFIG_LIST_add(
1595 config_list.get(), /*is_retry_config=*/0, kECHConfig, sizeof(kECHConfig),
1596 kECHConfigPrivateKey, sizeof(kECHConfigPrivateKey)));
1597
1598 ASSERT_FALSE(
1599 SSL_CTX_set1_ech_server_config_list(ctx.get(), config_list.get()));
1600 uint32_t err = ERR_peek_error();
1601 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
1602 EXPECT_EQ(SSL_R_ECH_SERVER_WOULD_HAVE_NO_RETRY_CONFIGS, ERR_GET_REASON(err));
1603 ERR_clear_error();
1604
1605 // Add the same ECHConfig to the list, but this time mark it as a retry
1606 // config.
1607 ASSERT_TRUE(SSL_ECH_SERVER_CONFIG_LIST_add(
1608 config_list.get(), /*is_retry_config=*/1, kECHConfig, sizeof(kECHConfig),
1609 kECHConfigPrivateKey, sizeof(kECHConfigPrivateKey)));
1610 ASSERT_TRUE(
1611 SSL_CTX_set1_ech_server_config_list(ctx.get(), config_list.get()));
1612}
1613
1614// Test that the server APIs reject ECHConfigs with unsupported features.
1615TEST(SSLTest, UnsupportedECHConfig) {
1616 bssl::UniquePtr<SSL_ECH_SERVER_CONFIG_LIST> config_list(
1617 SSL_ECH_SERVER_CONFIG_LIST_new());
1618 ASSERT_TRUE(config_list);
1619
1620 // Unsupported versions are rejected.
1621 static const uint8_t kUnsupportedVersion[] = {0xff, 0xff, 0x00, 0x00};
1622 EXPECT_FALSE(SSL_ECH_SERVER_CONFIG_LIST_add(
1623 config_list.get(), /*is_retry_config=*/1, kUnsupportedVersion,
1624 sizeof(kUnsupportedVersion), kECHConfigPrivateKey,
1625 sizeof(kECHConfigPrivateKey)));
1626
1627 // Unsupported cipher suites are rejected. (We only support HKDF-SHA256.)
1628 std::vector<uint8_t> ech_config;
1629 ASSERT_TRUE(MakeECHConfig(
1630 &ech_config, EVP_HPKE_DHKEM_X25519_HKDF_SHA256, kECHConfigPublicKey,
1631 std::vector<uint16_t>{EVP_HPKE_HKDF_SHA384, EVP_HPKE_AEAD_AES_128_GCM},
1632 /*extensions=*/{}));
1633 EXPECT_FALSE(SSL_ECH_SERVER_CONFIG_LIST_add(
1634 config_list.get(), /*is_retry_config=*/1, ech_config.data(),
1635 ech_config.size(), kECHConfigPrivateKey, sizeof(kECHConfigPrivateKey)));
1636
1637 // Unsupported KEMs are rejected.
1638 static const uint8_t kP256PublicKey[] = {
1639 0x04, 0xe6, 0x2b, 0x69, 0xe2, 0xbf, 0x65, 0x9f, 0x97, 0xbe, 0x2f,
1640 0x1e, 0x0d, 0x94, 0x8a, 0x4c, 0xd5, 0x97, 0x6b, 0xb7, 0xa9, 0x1e,
1641 0x0d, 0x46, 0xfb, 0xdd, 0xa9, 0xa9, 0x1e, 0x9d, 0xdc, 0xba, 0x5a,
1642 0x01, 0xe7, 0xd6, 0x97, 0xa8, 0x0a, 0x18, 0xf9, 0xc3, 0xc4, 0xa3,
1643 0x1e, 0x56, 0xe2, 0x7c, 0x83, 0x48, 0xdb, 0x16, 0x1a, 0x1c, 0xf5,
1644 0x1d, 0x7e, 0xf1, 0x94, 0x2d, 0x4b, 0xcf, 0x72, 0x22, 0xc1};
1645 static const uint8_t kP256PrivateKey[] = {
1646 0x07, 0x0f, 0x08, 0x72, 0x7a, 0xd4, 0xa0, 0x4a, 0x9c, 0xdd, 0x59,
1647 0xc9, 0x4d, 0x89, 0x68, 0x77, 0x08, 0xb5, 0x6f, 0xc9, 0x5d, 0x30,
1648 0x77, 0x0e, 0xe8, 0xd1, 0xc9, 0xce, 0x0a, 0x8b, 0xb4, 0x6a};
1649 ASSERT_TRUE(MakeECHConfig(
1650 &ech_config, 0x0010 /* DHKEM(P-256, HKDF-SHA256) */, kP256PublicKey,
1651 std::vector<uint16_t>{EVP_HPKE_HKDF_SHA256, EVP_HPKE_AEAD_AES_128_GCM},
1652 /*extensions=*/{}));
1653 EXPECT_FALSE(SSL_ECH_SERVER_CONFIG_LIST_add(
1654 config_list.get(), /*is_retry_config=*/1, ech_config.data(),
1655 ech_config.size(), kP256PrivateKey, sizeof(kP256PrivateKey)));
1656
1657 // Unsupported extensions are rejected.
1658 static const uint8_t kExtensions[] = {0x00, 0x01, 0x00, 0x00};
1659 ASSERT_TRUE(MakeECHConfig(
1660 &ech_config, EVP_HPKE_DHKEM_X25519_HKDF_SHA256, kECHConfigPublicKey,
1661 std::vector<uint16_t>{EVP_HPKE_HKDF_SHA256, EVP_HPKE_AEAD_AES_128_GCM},
1662 kExtensions));
1663 EXPECT_FALSE(SSL_ECH_SERVER_CONFIG_LIST_add(
1664 config_list.get(), /*is_retry_config=*/1, ech_config.data(),
1665 ech_config.size(), kECHConfigPrivateKey, sizeof(kECHConfigPrivateKey)));
1666}
1667
David Benjaminc79ae7a2017-08-29 16:09:44 -04001668static void AppendSession(SSL_SESSION *session, void *arg) {
1669 std::vector<SSL_SESSION*> *out =
1670 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
1671 out->push_back(session);
1672}
1673
1674// CacheEquals returns true if |ctx|'s session cache consists of |expected|, in
1675// order.
1676static bool CacheEquals(SSL_CTX *ctx,
1677 const std::vector<SSL_SESSION*> &expected) {
1678 // Check the linked list.
1679 SSL_SESSION *ptr = ctx->session_cache_head;
1680 for (SSL_SESSION *session : expected) {
1681 if (ptr != session) {
1682 return false;
1683 }
1684 // TODO(davidben): This is an absurd way to denote the end of the list.
1685 if (ptr->next ==
1686 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
1687 ptr = nullptr;
1688 } else {
1689 ptr = ptr->next;
1690 }
1691 }
1692 if (ptr != nullptr) {
1693 return false;
1694 }
1695
1696 // Check the hash table.
1697 std::vector<SSL_SESSION*> actual, expected_copy;
David Benjamin9eaa3bd2017-09-27 17:03:54 -04001698 lh_SSL_SESSION_doall_arg(ctx->sessions, AppendSession, &actual);
David Benjaminc79ae7a2017-08-29 16:09:44 -04001699 expected_copy = expected;
1700
1701 std::sort(actual.begin(), actual.end());
1702 std::sort(expected_copy.begin(), expected_copy.end());
1703
1704 return actual == expected_copy;
1705}
1706
1707static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
1708 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
1709 if (!ssl_ctx) {
1710 return nullptr;
1711 }
1712 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new(ssl_ctx.get()));
1713 if (!ret) {
1714 return nullptr;
1715 }
1716
David Benjaminaaef8332018-06-29 16:45:49 -04001717 uint8_t id[SSL3_SSL_SESSION_ID_LENGTH] = {0};
1718 OPENSSL_memcpy(id, &number, sizeof(number));
1719 if (!SSL_SESSION_set1_id(ret.get(), id, sizeof(id))) {
1720 return nullptr;
1721 }
David Benjaminc79ae7a2017-08-29 16:09:44 -04001722 return ret;
1723}
1724
1725// Test that the internal session cache behaves as expected.
1726TEST(SSLTest, InternalSessionCache) {
1727 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1728 ASSERT_TRUE(ctx);
1729
1730 // Prepare 10 test sessions.
1731 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
1732 for (int i = 0; i < 10; i++) {
1733 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
1734 ASSERT_TRUE(session);
1735 sessions.push_back(std::move(session));
1736 }
1737
1738 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1739
1740 // Insert all the test sessions.
1741 for (const auto &session : sessions) {
1742 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), session.get()));
1743 }
1744
1745 // Only the last five should be in the list.
1746 ASSERT_TRUE(CacheEquals(
1747 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
1748 sessions[6].get(), sessions[5].get()}));
1749
1750 // Inserting an element already in the cache should fail and leave the cache
1751 // unchanged.
1752 ASSERT_FALSE(SSL_CTX_add_session(ctx.get(), sessions[7].get()));
1753 ASSERT_TRUE(CacheEquals(
1754 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
1755 sessions[6].get(), sessions[5].get()}));
1756
1757 // Although collisions should be impossible (256-bit session IDs), the cache
1758 // must handle them gracefully.
1759 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
1760 ASSERT_TRUE(collision);
1761 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), collision.get()));
1762 ASSERT_TRUE(CacheEquals(
1763 ctx.get(), {collision.get(), sessions[9].get(), sessions[8].get(),
1764 sessions[6].get(), sessions[5].get()}));
1765
1766 // Removing sessions behaves correctly.
1767 ASSERT_TRUE(SSL_CTX_remove_session(ctx.get(), sessions[6].get()));
1768 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
1769 sessions[8].get(), sessions[5].get()}));
1770
1771 // Removing sessions requires an exact match.
1772 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[0].get()));
1773 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[7].get()));
1774
1775 // The cache remains unchanged.
1776 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
1777 sessions[8].get(), sessions[5].get()}));
1778}
1779
1780static uint16_t EpochFromSequence(uint64_t seq) {
1781 return static_cast<uint16_t>(seq >> 48);
1782}
1783
David Benjamin71dfad42017-07-16 17:27:39 -04001784static const uint8_t kTestName[] = {
1785 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
1786 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
1787 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
1788 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
1789 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
1790 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64,
1791};
1792
David Benjaminb79cc842016-12-07 15:57:14 -05001793static bool CompleteHandshakes(SSL *client, SSL *server) {
1794 // Drive both their handshakes to completion.
1795 for (;;) {
1796 int client_ret = SSL_do_handshake(client);
1797 int client_err = SSL_get_error(client, client_ret);
1798 if (client_err != SSL_ERROR_NONE &&
1799 client_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001800 client_err != SSL_ERROR_WANT_WRITE &&
1801 client_err != SSL_ERROR_PENDING_TICKET) {
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08001802 fprintf(stderr, "Client error: %s\n", SSL_error_description(client_err));
David Benjaminb79cc842016-12-07 15:57:14 -05001803 return false;
1804 }
1805
1806 int server_ret = SSL_do_handshake(server);
1807 int server_err = SSL_get_error(server, server_ret);
1808 if (server_err != SSL_ERROR_NONE &&
1809 server_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001810 server_err != SSL_ERROR_WANT_WRITE &&
1811 server_err != SSL_ERROR_PENDING_TICKET) {
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08001812 fprintf(stderr, "Server error: %s\n", SSL_error_description(server_err));
David Benjaminb79cc842016-12-07 15:57:14 -05001813 return false;
1814 }
1815
1816 if (client_ret == 1 && server_ret == 1) {
1817 break;
1818 }
1819 }
1820
1821 return true;
1822}
1823
Steven Valdez777a2392019-02-21 11:30:47 -05001824static bool FlushNewSessionTickets(SSL *client, SSL *server) {
1825 // NewSessionTickets are deferred on the server to |SSL_write|, and clients do
1826 // not pick them up until |SSL_read|.
1827 for (;;) {
1828 int server_ret = SSL_write(server, nullptr, 0);
1829 int server_err = SSL_get_error(server, server_ret);
1830 // The server may either succeed (|server_ret| is zero) or block on write
1831 // (|server_ret| is -1 and |server_err| is |SSL_ERROR_WANT_WRITE|).
1832 if (server_ret > 0 ||
1833 (server_ret < 0 && server_err != SSL_ERROR_WANT_WRITE)) {
1834 fprintf(stderr, "Unexpected server result: %d %d\n", server_ret,
1835 server_err);
1836 return false;
1837 }
1838
1839 int client_ret = SSL_read(client, nullptr, 0);
1840 int client_err = SSL_get_error(client, client_ret);
1841 // The client must always block on read.
1842 if (client_ret != -1 || client_err != SSL_ERROR_WANT_READ) {
1843 fprintf(stderr, "Unexpected client result: %d %d\n", client_ret,
1844 client_err);
1845 return false;
1846 }
1847
1848 // The server flushed everything it had to write.
1849 if (server_ret == 0) {
1850 return true;
1851 }
1852 }
1853}
1854
David Benjamina8614602017-09-06 15:40:19 -04001855struct ClientConfig {
1856 SSL_SESSION *session = nullptr;
1857 std::string servername;
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08001858 bool early_data = false;
David Benjamina8614602017-09-06 15:40:19 -04001859};
1860
David Benjaminb79cc842016-12-07 15:57:14 -05001861static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client,
1862 bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001863 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
Adam Langleyddb57cf2018-01-26 09:17:53 -08001864 const ClientConfig &config = ClientConfig(),
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001865 bool do_handshake = true,
1866 bool shed_handshake_config = true) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001867 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001868 if (!client || !server) {
1869 return false;
1870 }
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08001871 if (config.early_data) {
1872 SSL_set_early_data_enabled(client.get(), 1);
1873 }
David Benjaminde942382016-02-11 12:02:01 -05001874 SSL_set_connect_state(client.get());
1875 SSL_set_accept_state(server.get());
1876
David Benjamina8614602017-09-06 15:40:19 -04001877 if (config.session) {
1878 SSL_set_session(client.get(), config.session);
1879 }
1880 if (!config.servername.empty() &&
1881 !SSL_set_tlsext_host_name(client.get(), config.servername.c_str())) {
1882 return false;
1883 }
David Benjamina20e5352016-08-02 19:09:41 -04001884
David Benjaminde942382016-02-11 12:02:01 -05001885 BIO *bio1, *bio2;
1886 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1887 return false;
1888 }
1889 // SSL_set_bio takes ownership.
1890 SSL_set_bio(client.get(), bio1, bio1);
1891 SSL_set_bio(server.get(), bio2, bio2);
1892
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001893 SSL_set_shed_handshake_config(client.get(), shed_handshake_config);
1894 SSL_set_shed_handshake_config(server.get(), shed_handshake_config);
1895
Adam Langleyddb57cf2018-01-26 09:17:53 -08001896 if (do_handshake && !CompleteHandshakes(client.get(), server.get())) {
David Benjaminb79cc842016-12-07 15:57:14 -05001897 return false;
David Benjaminde942382016-02-11 12:02:01 -05001898 }
1899
David Benjamin686bb192016-05-10 15:15:41 -04001900 *out_client = std::move(client);
1901 *out_server = std::move(server);
1902 return true;
1903}
1904
David Benjaminc11ea9422017-08-29 16:33:21 -04001905// SSLVersionTest executes its test cases under all available protocol versions.
1906// Test cases call |Connect| to create a connection using context objects with
1907// the protocol version fixed to the current version under test.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001908class SSLVersionTest : public ::testing::TestWithParam<VersionParam> {
1909 protected:
1910 SSLVersionTest() : cert_(GetTestCertificate()), key_(GetTestKey()) {}
1911
1912 void SetUp() { ResetContexts(); }
1913
1914 bssl::UniquePtr<SSL_CTX> CreateContext() const {
1915 const SSL_METHOD *method = is_dtls() ? DTLS_method() : TLS_method();
1916 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
1917 if (!ctx || !SSL_CTX_set_min_proto_version(ctx.get(), version()) ||
1918 !SSL_CTX_set_max_proto_version(ctx.get(), version())) {
1919 return nullptr;
1920 }
1921 return ctx;
David Benjamin0fef3052016-11-18 15:11:10 +09001922 }
David Benjamin686bb192016-05-10 15:15:41 -04001923
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001924 void ResetContexts() {
1925 ASSERT_TRUE(cert_);
1926 ASSERT_TRUE(key_);
1927 client_ctx_ = CreateContext();
1928 ASSERT_TRUE(client_ctx_);
1929 server_ctx_ = CreateContext();
1930 ASSERT_TRUE(server_ctx_);
1931 // Set up a server cert. Client certs can be set up explicitly.
1932 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09001933 }
David Benjamin686bb192016-05-10 15:15:41 -04001934
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001935 bool UseCertAndKey(SSL_CTX *ctx) const {
1936 return SSL_CTX_use_certificate(ctx, cert_.get()) &&
1937 SSL_CTX_use_PrivateKey(ctx, key_.get());
David Benjamin0fef3052016-11-18 15:11:10 +09001938 }
David Benjamin686bb192016-05-10 15:15:41 -04001939
David Benjamina8614602017-09-06 15:40:19 -04001940 bool Connect(const ClientConfig &config = ClientConfig()) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001941 return ConnectClientAndServer(&client_, &server_, client_ctx_.get(),
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001942 server_ctx_.get(), config, true,
1943 shed_handshake_config_);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001944 }
1945
1946 uint16_t version() const { return GetParam().version; }
1947
1948 bool is_dtls() const {
1949 return GetParam().ssl_method == VersionParam::is_dtls;
1950 }
1951
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001952 bool shed_handshake_config_ = true;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001953 bssl::UniquePtr<SSL> client_, server_;
1954 bssl::UniquePtr<SSL_CTX> server_ctx_, client_ctx_;
1955 bssl::UniquePtr<X509> cert_;
1956 bssl::UniquePtr<EVP_PKEY> key_;
1957};
1958
David Benjaminbe7006a2019-04-09 18:05:02 -05001959INSTANTIATE_TEST_SUITE_P(WithVersion, SSLVersionTest,
1960 testing::ValuesIn(kAllVersions),
1961 [](const testing::TestParamInfo<VersionParam> &i) {
1962 return i.param.name;
1963 });
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001964
1965TEST_P(SSLVersionTest, SequenceNumber) {
1966 ASSERT_TRUE(Connect());
1967
David Benjamin0fef3052016-11-18 15:11:10 +09001968 // Drain any post-handshake messages to ensure there are no unread records
1969 // on either end.
Steven Valdez777a2392019-02-21 11:30:47 -05001970 ASSERT_TRUE(FlushNewSessionTickets(client_.get(), server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05001971
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001972 uint64_t client_read_seq = SSL_get_read_sequence(client_.get());
1973 uint64_t client_write_seq = SSL_get_write_sequence(client_.get());
1974 uint64_t server_read_seq = SSL_get_read_sequence(server_.get());
1975 uint64_t server_write_seq = SSL_get_write_sequence(server_.get());
Steven Valdez2c62fe92016-10-14 12:08:12 -04001976
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001977 if (is_dtls()) {
David Benjamin0fef3052016-11-18 15:11:10 +09001978 // Both client and server must be at epoch 1.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001979 EXPECT_EQ(EpochFromSequence(client_read_seq), 1);
1980 EXPECT_EQ(EpochFromSequence(client_write_seq), 1);
1981 EXPECT_EQ(EpochFromSequence(server_read_seq), 1);
1982 EXPECT_EQ(EpochFromSequence(server_write_seq), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09001983
1984 // The next record to be written should exceed the largest received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001985 EXPECT_GT(client_write_seq, server_read_seq);
1986 EXPECT_GT(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09001987 } else {
1988 // The next record to be written should equal the next to be received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001989 EXPECT_EQ(client_write_seq, server_read_seq);
1990 EXPECT_EQ(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09001991 }
1992
1993 // Send a record from client to server.
Steven Valdez777a2392019-02-21 11:30:47 -05001994 uint8_t byte = 0;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001995 EXPECT_EQ(SSL_write(client_.get(), &byte, 1), 1);
1996 EXPECT_EQ(SSL_read(server_.get(), &byte, 1), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09001997
1998 // The client write and server read sequence numbers should have
1999 // incremented.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002000 EXPECT_EQ(client_write_seq + 1, SSL_get_write_sequence(client_.get()));
2001 EXPECT_EQ(server_read_seq + 1, SSL_get_read_sequence(server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05002002}
2003
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002004TEST_P(SSLVersionTest, OneSidedShutdown) {
David Benjamin68f37b72016-11-18 15:14:42 +09002005 // SSL_shutdown is a no-op in DTLS.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002006 if (is_dtls()) {
2007 return;
David Benjamin686bb192016-05-10 15:15:41 -04002008 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002009 ASSERT_TRUE(Connect());
David Benjamin686bb192016-05-10 15:15:41 -04002010
2011 // Shut down half the connection. SSL_shutdown will return 0 to signal only
2012 // one side has shut down.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002013 ASSERT_EQ(SSL_shutdown(client_.get()), 0);
David Benjamin686bb192016-05-10 15:15:41 -04002014
2015 // Reading from the server should consume the EOF.
2016 uint8_t byte;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002017 ASSERT_EQ(SSL_read(server_.get(), &byte, 1), 0);
2018 ASSERT_EQ(SSL_get_error(server_.get(), 0), SSL_ERROR_ZERO_RETURN);
David Benjamin686bb192016-05-10 15:15:41 -04002019
2020 // However, the server may continue to write data and then shut down the
2021 // connection.
2022 byte = 42;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002023 ASSERT_EQ(SSL_write(server_.get(), &byte, 1), 1);
2024 ASSERT_EQ(SSL_read(client_.get(), &byte, 1), 1);
2025 ASSERT_EQ(byte, 42);
David Benjamin686bb192016-05-10 15:15:41 -04002026
2027 // The server may then shutdown the connection.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002028 EXPECT_EQ(SSL_shutdown(server_.get()), 1);
2029 EXPECT_EQ(SSL_shutdown(client_.get()), 1);
David Benjamin686bb192016-05-10 15:15:41 -04002030}
David Benjamin68f37b72016-11-18 15:14:42 +09002031
David Benjaminf0d8e222017-02-04 10:58:26 -05002032TEST(SSLTest, SessionDuplication) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002033 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
2034 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002035 ASSERT_TRUE(client_ctx);
2036 ASSERT_TRUE(server_ctx);
Steven Valdez87eab492016-06-27 16:34:59 -04002037
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002038 bssl::UniquePtr<X509> cert = GetTestCertificate();
2039 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminf0d8e222017-02-04 10:58:26 -05002040 ASSERT_TRUE(cert);
2041 ASSERT_TRUE(key);
2042 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
2043 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04002044
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002045 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05002046 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04002047 server_ctx.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04002048
2049 SSL_SESSION *session0 = SSL_get_session(client.get());
David Benjamin31b0c9b2017-07-20 14:49:15 -04002050 bssl::UniquePtr<SSL_SESSION> session1 =
2051 bssl::SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL);
David Benjaminf0d8e222017-02-04 10:58:26 -05002052 ASSERT_TRUE(session1);
David Benjamin4501bd52016-08-01 13:39:41 -04002053
David Benjamina3a71e92018-06-29 13:24:45 -04002054 session1->not_resumable = false;
Steven Valdez84b5c002016-08-25 16:30:58 -04002055
Steven Valdez87eab492016-06-27 16:34:59 -04002056 uint8_t *s0_bytes, *s1_bytes;
2057 size_t s0_len, s1_len;
2058
David Benjaminf0d8e222017-02-04 10:58:26 -05002059 ASSERT_TRUE(SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002060 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04002061
David Benjaminf0d8e222017-02-04 10:58:26 -05002062 ASSERT_TRUE(SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002063 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04002064
David Benjamin7d7554b2017-02-04 11:48:59 -05002065 EXPECT_EQ(Bytes(s0_bytes, s0_len), Bytes(s1_bytes, s1_len));
Steven Valdez87eab492016-06-27 16:34:59 -04002066}
David Benjamin686bb192016-05-10 15:15:41 -04002067
David Benjaminf0d8e222017-02-04 10:58:26 -05002068static void ExpectFDs(const SSL *ssl, int rfd, int wfd) {
David Benjaminca743582017-06-15 17:51:35 -04002069 EXPECT_EQ(rfd, SSL_get_fd(ssl));
David Benjaminf0d8e222017-02-04 10:58:26 -05002070 EXPECT_EQ(rfd, SSL_get_rfd(ssl));
2071 EXPECT_EQ(wfd, SSL_get_wfd(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04002072
2073 // The wrapper BIOs are always equal when fds are equal, even if set
2074 // individually.
David Benjaminf0d8e222017-02-04 10:58:26 -05002075 if (rfd == wfd) {
2076 EXPECT_EQ(SSL_get_rbio(ssl), SSL_get_wbio(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04002077 }
David Benjamin5c0fb882016-06-14 14:03:51 -04002078}
2079
David Benjaminf0d8e222017-02-04 10:58:26 -05002080TEST(SSLTest, SetFD) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002081 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002082 ASSERT_TRUE(ctx);
David Benjamin5c0fb882016-06-14 14:03:51 -04002083
2084 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002085 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002086 ASSERT_TRUE(ssl);
2087 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2088 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
2089 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04002090
2091 // Test setting the same FD.
2092 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002093 ASSERT_TRUE(ssl);
2094 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2095 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002096
2097 // Test setting the same FD one side at a time.
2098 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002099 ASSERT_TRUE(ssl);
2100 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2101 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
2102 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002103
2104 // Test setting the same FD in the other order.
2105 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002106 ASSERT_TRUE(ssl);
2107 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
2108 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2109 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002110
David Benjamin5c0fb882016-06-14 14:03:51 -04002111 // Test changing the read FD partway through.
2112 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002113 ASSERT_TRUE(ssl);
2114 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2115 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 2));
2116 ExpectFDs(ssl.get(), 2, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002117
2118 // Test changing the write FD partway through.
2119 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002120 ASSERT_TRUE(ssl);
2121 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2122 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
2123 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04002124
2125 // Test a no-op change to the read FD partway through.
2126 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002127 ASSERT_TRUE(ssl);
2128 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2129 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2130 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002131
2132 // Test a no-op change to the write FD partway through.
2133 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002134 ASSERT_TRUE(ssl);
2135 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2136 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
2137 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002138
2139 // ASan builds will implicitly test that the internal |BIO| reference-counting
2140 // is correct.
David Benjamin5c0fb882016-06-14 14:03:51 -04002141}
2142
David Benjaminf0d8e222017-02-04 10:58:26 -05002143TEST(SSLTest, SetBIO) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002144 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002145 ASSERT_TRUE(ctx);
David Benjamin4501bd52016-08-01 13:39:41 -04002146
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002147 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
2148 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04002149 bio3(BIO_new(BIO_s_mem()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002150 ASSERT_TRUE(ssl);
2151 ASSERT_TRUE(bio1);
2152 ASSERT_TRUE(bio2);
2153 ASSERT_TRUE(bio3);
David Benjamin4501bd52016-08-01 13:39:41 -04002154
2155 // SSL_set_bio takes one reference when the parameters are the same.
2156 BIO_up_ref(bio1.get());
2157 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
2158
2159 // Repeating the call does nothing.
2160 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
2161
2162 // It takes one reference each when the parameters are different.
2163 BIO_up_ref(bio2.get());
2164 BIO_up_ref(bio3.get());
2165 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
2166
2167 // Repeating the call does nothing.
2168 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
2169
2170 // It takes one reference when changing only wbio.
2171 BIO_up_ref(bio1.get());
2172 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
2173
2174 // It takes one reference when changing only rbio and the two are different.
2175 BIO_up_ref(bio3.get());
2176 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
2177
2178 // If setting wbio to rbio, it takes no additional references.
2179 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
2180
2181 // From there, wbio may be switched to something else.
2182 BIO_up_ref(bio1.get());
2183 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
2184
2185 // If setting rbio to wbio, it takes no additional references.
2186 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
2187
2188 // From there, rbio may be switched to something else, but, for historical
2189 // reasons, it takes a reference to both parameters.
2190 BIO_up_ref(bio1.get());
2191 BIO_up_ref(bio2.get());
2192 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
2193
2194 // ASAN builds will implicitly test that the internal |BIO| reference-counting
2195 // is correct.
David Benjamin4501bd52016-08-01 13:39:41 -04002196}
2197
David Benjamin25490f22016-07-14 00:22:54 -04002198static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
2199
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002200TEST_P(SSLVersionTest, GetPeerCertificate) {
2201 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04002202
David Benjamin0fef3052016-11-18 15:11:10 +09002203 // Configure both client and server to accept any certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002204 SSL_CTX_set_verify(client_ctx_.get(),
2205 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2206 nullptr);
2207 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
2208 SSL_CTX_set_verify(server_ctx_.get(),
2209 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2210 nullptr);
2211 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjaminadd5e522016-07-14 00:33:24 -04002212
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002213 ASSERT_TRUE(Connect());
David Benjaminadd5e522016-07-14 00:33:24 -04002214
David Benjamin0fef3052016-11-18 15:11:10 +09002215 // Client and server should both see the leaf certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002216 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
2217 ASSERT_TRUE(peer);
2218 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04002219
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002220 peer.reset(SSL_get_peer_certificate(client_.get()));
2221 ASSERT_TRUE(peer);
2222 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04002223
David Benjamine664a532017-07-20 20:19:36 -04002224 // However, for historical reasons, the X509 chain includes the leaf on the
David Benjamin0fef3052016-11-18 15:11:10 +09002225 // client, but does not on the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002226 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(client_.get())), 1u);
2227 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(client_.get())),
2228 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04002229
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002230 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(server_.get())), 0u);
2231 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(server_.get())),
2232 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04002233}
2234
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002235TEST_P(SSLVersionTest, NoPeerCertificate) {
2236 SSL_CTX_set_verify(server_ctx_.get(), SSL_VERIFY_PEER, nullptr);
2237 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
2238 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
David Benjamine664a532017-07-20 20:19:36 -04002239
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002240 ASSERT_TRUE(Connect());
David Benjamine664a532017-07-20 20:19:36 -04002241
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002242 // Server should not see a peer certificate.
2243 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
2244 ASSERT_FALSE(peer);
2245 ASSERT_FALSE(SSL_get0_peer_certificates(server_.get()));
David Benjamine664a532017-07-20 20:19:36 -04002246}
2247
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002248TEST_P(SSLVersionTest, RetainOnlySHA256OfCerts) {
David Benjamin25490f22016-07-14 00:22:54 -04002249 uint8_t *cert_der = NULL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002250 int cert_der_len = i2d_X509(cert_.get(), &cert_der);
2251 ASSERT_GE(cert_der_len, 0);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002252 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04002253
2254 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
2255 SHA256(cert_der, cert_der_len, cert_sha256);
2256
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002257 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2258
David Benjamin0fef3052016-11-18 15:11:10 +09002259 // Configure both client and server to accept any certificate, but the
2260 // server must retain only the SHA-256 of the peer.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002261 SSL_CTX_set_verify(client_ctx_.get(),
2262 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2263 nullptr);
2264 SSL_CTX_set_verify(server_ctx_.get(),
2265 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2266 nullptr);
2267 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
2268 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
2269 SSL_CTX_set_retain_only_sha256_of_client_certs(server_ctx_.get(), 1);
David Benjamin25490f22016-07-14 00:22:54 -04002270
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002271 ASSERT_TRUE(Connect());
David Benjamin25490f22016-07-14 00:22:54 -04002272
David Benjamin0fef3052016-11-18 15:11:10 +09002273 // The peer certificate has been dropped.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002274 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
2275 EXPECT_FALSE(peer);
David Benjamin25490f22016-07-14 00:22:54 -04002276
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002277 SSL_SESSION *session = SSL_get_session(server_.get());
David Benjamin02de7bd2018-05-08 18:13:54 -04002278 EXPECT_TRUE(SSL_SESSION_has_peer_sha256(session));
David Benjamin25490f22016-07-14 00:22:54 -04002279
David Benjamin02de7bd2018-05-08 18:13:54 -04002280 const uint8_t *peer_sha256;
2281 size_t peer_sha256_len;
2282 SSL_SESSION_get0_peer_sha256(session, &peer_sha256, &peer_sha256_len);
2283 EXPECT_EQ(Bytes(cert_sha256), Bytes(peer_sha256, peer_sha256_len));
David Benjamin25490f22016-07-14 00:22:54 -04002284}
2285
David Benjamin737d2df2017-09-25 15:05:19 -04002286// Tests that our ClientHellos do not change unexpectedly. These are purely
2287// change detection tests. If they fail as part of an intentional ClientHello
2288// change, update the test vector.
2289TEST(SSLTest, ClientHello) {
2290 struct {
2291 uint16_t max_version;
2292 std::vector<uint8_t> expected;
2293 } kTests[] = {
David Benjamin737d2df2017-09-25 15:05:19 -04002294 {TLS1_VERSION,
2295 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x01, 0x00,
2296 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2297 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2298 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
2299 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
Adam Langleyd6680952018-08-23 08:01:23 -07002300 0x01, 0x00, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01,
2301 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
2302 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
David Benjamin737d2df2017-09-25 15:05:19 -04002303 {TLS1_1_VERSION,
2304 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x02, 0x00,
2305 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2306 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2307 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
2308 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
Adam Langleyd6680952018-08-23 08:01:23 -07002309 0x01, 0x00, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01,
2310 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
2311 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
David Benjamin737d2df2017-09-25 15:05:19 -04002312 {TLS1_2_VERSION,
David Benjamin6e678ee2018-04-16 19:54:42 -04002313 {0x16, 0x03, 0x01, 0x00, 0x82, 0x01, 0x00, 0x00, 0x7e, 0x03, 0x03, 0x00,
David Benjamin737d2df2017-09-25 15:05:19 -04002314 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2315 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
David Benjamin6e678ee2018-04-16 19:54:42 -04002316 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xcc, 0xa9,
David Benjamin737d2df2017-09-25 15:05:19 -04002317 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xc0, 0x09,
David Benjamin6e678ee2018-04-16 19:54:42 -04002318 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
Adam Langleyd6680952018-08-23 08:01:23 -07002319 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37, 0x00, 0x17, 0x00, 0x00,
2320 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00,
2321 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
2322 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04, 0x03, 0x08,
2323 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06,
2324 0x01, 0x02, 0x01}},
David Benjamin737d2df2017-09-25 15:05:19 -04002325 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
2326 // implementation has settled enough that it won't change.
David Benjaminafc64de2016-07-19 17:12:41 +02002327 };
David Benjamin737d2df2017-09-25 15:05:19 -04002328
2329 for (const auto &t : kTests) {
2330 SCOPED_TRACE(t.max_version);
2331
2332 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2333 ASSERT_TRUE(ctx);
2334 // Our default cipher list varies by CPU capabilities, so manually place the
2335 // ChaCha20 ciphers in front.
2336 const char *cipher_list = "CHACHA20:ALL";
David Benjamin737d2df2017-09-25 15:05:19 -04002337 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), t.max_version));
2338 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list));
2339
2340 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
2341 ASSERT_TRUE(ssl);
2342 std::vector<uint8_t> client_hello;
2343 ASSERT_TRUE(GetClientHello(ssl.get(), &client_hello));
2344
2345 // Zero the client_random.
2346 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
2347 1 + 3 + // handshake message header
2348 2; // client_version
2349 ASSERT_GE(client_hello.size(), kRandomOffset + SSL3_RANDOM_SIZE);
2350 OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
2351
2352 if (client_hello != t.expected) {
2353 ADD_FAILURE() << "ClientHellos did not match.";
2354 // Print the value manually so it is easier to update the test vector.
2355 for (size_t i = 0; i < client_hello.size(); i += 12) {
2356 printf(" %c", i == 0 ? '{' : ' ');
2357 for (size_t j = i; j < client_hello.size() && j < i + 12; j++) {
2358 if (j > i) {
2359 printf(" ");
2360 }
2361 printf("0x%02x", client_hello[j]);
2362 if (j < client_hello.size() - 1) {
2363 printf(",");
2364 }
2365 }
2366 if (i + 12 >= client_hello.size()) {
Adam Langleyd6680952018-08-23 08:01:23 -07002367 printf("}},");
David Benjamin737d2df2017-09-25 15:05:19 -04002368 }
2369 printf("\n");
2370 }
2371 }
David Benjaminafc64de2016-07-19 17:12:41 +02002372 }
David Benjaminafc64de2016-07-19 17:12:41 +02002373}
2374
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002375static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04002376
2377static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
2378 // Save the most recent session.
2379 g_last_session.reset(session);
2380 return 1;
2381}
2382
David Benjamina8614602017-09-06 15:40:19 -04002383static bssl::UniquePtr<SSL_SESSION> CreateClientSession(
2384 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2385 const ClientConfig &config = ClientConfig()) {
David Benjamina20e5352016-08-02 19:09:41 -04002386 g_last_session = nullptr;
2387 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2388
2389 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002390 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04002391 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
Steven Valdez777a2392019-02-21 11:30:47 -05002392 config) ||
2393 !FlushNewSessionTickets(client.get(), server.get())) {
David Benjamina20e5352016-08-02 19:09:41 -04002394 fprintf(stderr, "Failed to connect client and server.\n");
2395 return nullptr;
2396 }
2397
David Benjamina20e5352016-08-02 19:09:41 -04002398 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2399
2400 if (!g_last_session) {
2401 fprintf(stderr, "Client did not receive a session.\n");
2402 return nullptr;
2403 }
2404 return std::move(g_last_session);
2405}
2406
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002407static void ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2408 SSL_SESSION *session, bool want_reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002409 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002410 ClientConfig config;
2411 config.session = session;
2412 EXPECT_TRUE(
2413 ConnectClientAndServer(&client, &server, client_ctx, server_ctx, config));
David Benjamina20e5352016-08-02 19:09:41 -04002414
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002415 EXPECT_EQ(SSL_session_reused(client.get()), SSL_session_reused(server.get()));
David Benjamina20e5352016-08-02 19:09:41 -04002416
2417 bool was_reused = !!SSL_session_reused(client.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002418 EXPECT_EQ(was_reused, want_reused);
David Benjamina20e5352016-08-02 19:09:41 -04002419}
2420
David Benjamin3c51d9b2016-11-01 17:50:42 -04002421static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
2422 SSL_CTX *server_ctx,
2423 SSL_SESSION *session) {
2424 g_last_session = nullptr;
2425 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2426
2427 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002428 ClientConfig config;
2429 config.session = session;
2430 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
Steven Valdez777a2392019-02-21 11:30:47 -05002431 config) ||
2432 !FlushNewSessionTickets(client.get(), server.get())) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002433 fprintf(stderr, "Failed to connect client and server.\n");
2434 return nullptr;
2435 }
2436
2437 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2438 fprintf(stderr, "Client and server were inconsistent.\n");
2439 return nullptr;
2440 }
2441
2442 if (!SSL_session_reused(client.get())) {
2443 fprintf(stderr, "Session was not reused.\n");
2444 return nullptr;
2445 }
2446
David Benjamin3c51d9b2016-11-01 17:50:42 -04002447 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2448
2449 if (!g_last_session) {
2450 fprintf(stderr, "Client did not receive a renewed session.\n");
2451 return nullptr;
2452 }
2453 return std::move(g_last_session);
2454}
2455
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002456static void ExpectTicketKeyChanged(SSL_CTX *ctx, uint8_t *inout_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002457 bool changed) {
2458 uint8_t new_key[kTicketKeyLen];
David Benjaminc11ea9422017-08-29 16:33:21 -04002459 // May return 0, 1 or 48.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002460 ASSERT_EQ(SSL_CTX_get_tlsext_ticket_keys(ctx, new_key, kTicketKeyLen), 1);
2461 if (changed) {
2462 ASSERT_NE(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
2463 } else {
2464 ASSERT_EQ(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002465 }
2466 OPENSSL_memcpy(inout_key, new_key, kTicketKeyLen);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002467}
2468
David Benjamina933c382016-10-28 00:10:03 -04002469static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
2470 static const uint8_t kContext[] = {3};
2471
2472 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
2473 return SSL_TLSEXT_ERR_ALERT_FATAL;
2474 }
2475
2476 return SSL_TLSEXT_ERR_OK;
2477}
2478
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002479TEST_P(SSLVersionTest, SessionIDContext) {
David Benjamina20e5352016-08-02 19:09:41 -04002480 static const uint8_t kContext1[] = {1};
2481 static const uint8_t kContext2[] = {2};
2482
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002483 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2484 sizeof(kContext1)));
David Benjamina20e5352016-08-02 19:09:41 -04002485
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002486 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2487 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002488
David Benjamin0fef3052016-11-18 15:11:10 +09002489 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002490 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2491 ASSERT_TRUE(session);
David Benjamina20e5352016-08-02 19:09:41 -04002492
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002493 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2494 session.get(),
2495 true /* expect session reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002496
David Benjamin0fef3052016-11-18 15:11:10 +09002497 // Change the session ID context.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002498 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext2,
2499 sizeof(kContext2)));
David Benjamina20e5352016-08-02 19:09:41 -04002500
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002501 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2502 session.get(),
2503 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002504
David Benjamin0fef3052016-11-18 15:11:10 +09002505 // Change the session ID context back and install an SNI callback to switch
2506 // it.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002507 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2508 sizeof(kContext1)));
David Benjamina933c382016-10-28 00:10:03 -04002509
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002510 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09002511 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04002512
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002513 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2514 session.get(),
2515 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002516
David Benjamin0fef3052016-11-18 15:11:10 +09002517 // Switch the session ID context with the early callback instead.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002518 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), nullptr);
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002519 SSL_CTX_set_select_certificate_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002520 server_ctx_.get(),
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002521 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
2522 static const uint8_t kContext[] = {3};
2523
2524 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
2525 sizeof(kContext))) {
2526 return ssl_select_cert_error;
2527 }
2528
2529 return ssl_select_cert_success;
2530 });
David Benjamina933c382016-10-28 00:10:03 -04002531
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002532 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2533 session.get(),
2534 false /* expect session not reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002535}
2536
David Benjamin721e8b72016-08-03 13:13:17 -04002537static timeval g_current_time;
2538
2539static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2540 *out_clock = g_current_time;
2541}
2542
David Benjamin17b30832017-01-28 14:00:32 -05002543static void FrozenTimeCallback(const SSL *ssl, timeval *out_clock) {
2544 out_clock->tv_sec = 1000;
2545 out_clock->tv_usec = 0;
2546}
2547
David Benjamin3c51d9b2016-11-01 17:50:42 -04002548static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
2549 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
2550 int encrypt) {
2551 static const uint8_t kZeros[16] = {0};
2552
2553 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -05002554 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamin3c51d9b2016-11-01 17:50:42 -04002555 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -05002556 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002557 return 0;
2558 }
2559
2560 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
2561 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
2562 return -1;
2563 }
2564
2565 // Returning two from the callback in decrypt mode renews the
2566 // session in TLS 1.2 and below.
2567 return encrypt ? 1 : 2;
2568}
2569
David Benjamin123db572016-11-03 16:59:25 -04002570static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjaminaaef8332018-06-29 16:45:49 -04002571 const uint8_t *ticket;
2572 size_t ticket_len;
2573 SSL_SESSION_get0_ticket(session, &ticket, &ticket_len);
2574 if (ticket_len < 16 + 16 + SHA256_DIGEST_LENGTH) {
David Benjamin123db572016-11-03 16:59:25 -04002575 return false;
2576 }
2577
David Benjaminaaef8332018-06-29 16:45:49 -04002578 const uint8_t *ciphertext = ticket + 16 + 16;
2579 size_t len = ticket_len - 16 - 16 - SHA256_DIGEST_LENGTH;
David Benjamin123db572016-11-03 16:59:25 -04002580 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
2581
David Benjamin9b63f292016-11-15 00:44:05 -05002582#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
2583 // Fuzzer-mode tickets are unencrypted.
David Benjamin17cf2cb2016-12-13 01:07:13 -05002584 OPENSSL_memcpy(plaintext.get(), ciphertext, len);
David Benjamin9b63f292016-11-15 00:44:05 -05002585#else
2586 static const uint8_t kZeros[16] = {0};
David Benjaminaaef8332018-06-29 16:45:49 -04002587 const uint8_t *iv = ticket + 16;
David Benjamin123db572016-11-03 16:59:25 -04002588 bssl::ScopedEVP_CIPHER_CTX ctx;
2589 int len1, len2;
2590 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
2591 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
2592 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
2593 return false;
2594 }
2595
2596 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05002597#endif
David Benjamin123db572016-11-03 16:59:25 -04002598
Adam Langley46db7af2017-02-01 15:49:37 -08002599 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
2600 if (!ssl_ctx) {
2601 return false;
2602 }
David Benjamin123db572016-11-03 16:59:25 -04002603 bssl::UniquePtr<SSL_SESSION> server_session(
Adam Langley46db7af2017-02-01 15:49:37 -08002604 SSL_SESSION_from_bytes(plaintext.get(), len, ssl_ctx.get()));
David Benjamin123db572016-11-03 16:59:25 -04002605 if (!server_session) {
2606 return false;
2607 }
2608
David Benjaminaaef8332018-06-29 16:45:49 -04002609 *out = SSL_SESSION_get_time(server_session.get());
David Benjamin123db572016-11-03 16:59:25 -04002610 return true;
2611}
2612
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002613TEST_P(SSLVersionTest, SessionTimeout) {
2614 for (bool server_test : {false, true}) {
2615 SCOPED_TRACE(server_test);
David Benjamin721e8b72016-08-03 13:13:17 -04002616
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002617 ResetContexts();
2618 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2619 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
2620
David Benjamin17b30832017-01-28 14:00:32 -05002621 static const time_t kStartTime = 1000;
David Benjamin0fef3052016-11-18 15:11:10 +09002622 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002623
David Benjamin17b30832017-01-28 14:00:32 -05002624 // We are willing to use a longer lifetime for TLS 1.3 sessions as
2625 // resumptions still perform ECDHE.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002626 const time_t timeout = version() == TLS1_3_VERSION
David Benjamin17b30832017-01-28 14:00:32 -05002627 ? SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT
2628 : SSL_DEFAULT_SESSION_TIMEOUT;
2629
David Benjamin17b30832017-01-28 14:00:32 -05002630 // Both client and server must enforce session timeouts. We configure the
2631 // other side with a frozen clock so it never expires tickets.
David Benjamin0fef3052016-11-18 15:11:10 +09002632 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002633 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2634 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002635 } else {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002636 SSL_CTX_set_current_time_cb(client_ctx_.get(), CurrentTimeCallback);
2637 SSL_CTX_set_current_time_cb(server_ctx_.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002638 }
2639
2640 // Configure a ticket callback which renews tickets.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002641 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002642
2643 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002644 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2645 ASSERT_TRUE(session);
David Benjamin0fef3052016-11-18 15:11:10 +09002646
2647 // Advance the clock just behind the timeout.
David Benjamin17b30832017-01-28 14:00:32 -05002648 g_current_time.tv_sec += timeout - 1;
David Benjamin0fef3052016-11-18 15:11:10 +09002649
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002650 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2651 session.get(),
2652 true /* expect session reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002653
2654 // Advance the clock one more second.
2655 g_current_time.tv_sec++;
2656
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002657 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2658 session.get(),
2659 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002660
2661 // Rewind the clock to before the session was minted.
2662 g_current_time.tv_sec = kStartTime - 1;
2663
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002664 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2665 session.get(),
2666 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002667
David Benjamin0fef3052016-11-18 15:11:10 +09002668 // Renew the session 10 seconds before expiration.
David Benjamin17b30832017-01-28 14:00:32 -05002669 time_t new_start_time = kStartTime + timeout - 10;
2670 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002671 bssl::UniquePtr<SSL_SESSION> new_session = ExpectSessionRenewed(
2672 client_ctx_.get(), server_ctx_.get(), session.get());
2673 ASSERT_TRUE(new_session);
David Benjamin0fef3052016-11-18 15:11:10 +09002674
2675 // This new session is not the same object as before.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002676 EXPECT_NE(session.get(), new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002677
2678 // Check the sessions have timestamps measured from issuance.
2679 long session_time = 0;
2680 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002681 ASSERT_TRUE(GetServerTicketTime(&session_time, new_session.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09002682 } else {
David Benjaminaaef8332018-06-29 16:45:49 -04002683 session_time = SSL_SESSION_get_time(new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002684 }
David Benjamin721e8b72016-08-03 13:13:17 -04002685
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002686 ASSERT_EQ(session_time, g_current_time.tv_sec);
David Benjamin721e8b72016-08-03 13:13:17 -04002687
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002688 if (version() == TLS1_3_VERSION) {
David Benjamin17b30832017-01-28 14:00:32 -05002689 // Renewal incorporates fresh key material in TLS 1.3, so we extend the
2690 // lifetime TLS 1.3.
2691 g_current_time.tv_sec = new_start_time + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002692 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2693 new_session.get(),
2694 true /* expect session reused */));
David Benjamin721e8b72016-08-03 13:13:17 -04002695
David Benjamin17b30832017-01-28 14:00:32 -05002696 // The new session expires after the new timeout.
2697 g_current_time.tv_sec = new_start_time + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002698 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2699 new_session.get(),
2700 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002701
2702 // Renew the session until it begins just past the auth timeout.
2703 time_t auth_end_time = kStartTime + SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
2704 while (new_start_time < auth_end_time - 1000) {
2705 // Get as close as possible to target start time.
2706 new_start_time =
2707 std::min(auth_end_time - 1000, new_start_time + timeout - 1);
2708 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002709 new_session = ExpectSessionRenewed(client_ctx_.get(), server_ctx_.get(),
David Benjamin17b30832017-01-28 14:00:32 -05002710 new_session.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002711 ASSERT_TRUE(new_session);
David Benjamin17b30832017-01-28 14:00:32 -05002712 }
2713
2714 // Now the session's lifetime is bound by the auth timeout.
2715 g_current_time.tv_sec = auth_end_time - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002716 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2717 new_session.get(),
2718 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002719
2720 g_current_time.tv_sec = auth_end_time + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002721 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2722 new_session.get(),
2723 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002724 } else {
2725 // The new session is usable just before the old expiration.
2726 g_current_time.tv_sec = kStartTime + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002727 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2728 new_session.get(),
2729 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002730
2731 // Renewal does not extend the lifetime, so it is not usable beyond the
2732 // old expiration.
2733 g_current_time.tv_sec = kStartTime + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002734 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2735 new_session.get(),
2736 false /* expect session not reused */));
David Benjamin1b22f852016-10-27 16:36:32 -04002737 }
David Benjamin721e8b72016-08-03 13:13:17 -04002738 }
David Benjamin721e8b72016-08-03 13:13:17 -04002739}
2740
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002741TEST_P(SSLVersionTest, DefaultTicketKeyInitialization) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002742 static const uint8_t kZeroKey[kTicketKeyLen] = {};
2743 uint8_t ticket_key[kTicketKeyLen];
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002744 ASSERT_EQ(1, SSL_CTX_get_tlsext_ticket_keys(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002745 kTicketKeyLen));
2746 ASSERT_NE(0, OPENSSL_memcmp(ticket_key, kZeroKey, kTicketKeyLen));
2747}
2748
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002749TEST_P(SSLVersionTest, DefaultTicketKeyRotation) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002750 static const time_t kStartTime = 1001;
2751 g_current_time.tv_sec = kStartTime;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002752
David Benjaminc11ea9422017-08-29 16:33:21 -04002753 // We use session reuse as a proxy for ticket decryption success, hence
2754 // disable session timeouts.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002755 SSL_CTX_set_timeout(server_ctx_.get(), std::numeric_limits<uint32_t>::max());
2756 SSL_CTX_set_session_psk_dhe_timeout(server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002757 std::numeric_limits<uint32_t>::max());
2758
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002759 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2760 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002761
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002762 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2763 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_OFF);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002764
David Benjamin1f0d54b2018-08-09 16:19:13 -05002765 // Initialize ticket_key with the current key and check that it was
2766 // initialized to something, not all zeros.
2767 uint8_t ticket_key[kTicketKeyLen] = {0};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002768 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2769 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002770
David Benjaminc11ea9422017-08-29 16:33:21 -04002771 // Verify ticket resumption actually works.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002772 bssl::UniquePtr<SSL> client, server;
2773 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002774 CreateClientSession(client_ctx_.get(), server_ctx_.get());
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002775 ASSERT_TRUE(session);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002776 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002777 session.get(), true /* reused */));
2778
David Benjaminc11ea9422017-08-29 16:33:21 -04002779 // Advance time to just before key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002780 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002781 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002782 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002783 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002784 false /* NOT changed */));
2785
David Benjaminc11ea9422017-08-29 16:33:21 -04002786 // Force key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002787 g_current_time.tv_sec += 1;
2788 bssl::UniquePtr<SSL_SESSION> new_session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002789 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2790 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2791 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002792
David Benjaminc11ea9422017-08-29 16:33:21 -04002793 // Resumption with both old and new ticket should work.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002794 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002795 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002796 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002797 new_session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002798 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002799 false /* NOT changed */));
2800
David Benjaminc11ea9422017-08-29 16:33:21 -04002801 // Force key rotation again. Resumption with the old ticket now fails.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002802 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002803 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002804 session.get(), false /* NOT reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002805 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2806 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002807
David Benjaminc11ea9422017-08-29 16:33:21 -04002808 // But resumption with the newer session still works.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002809 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002810 new_session.get(), true /* reused */));
2811}
2812
David Benjamin0fc37ef2016-08-17 15:29:46 -04002813static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002814 SSL_CTX *ctx = reinterpret_cast<SSL_CTX *>(arg);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002815 SSL_set_SSL_CTX(ssl, ctx);
2816 return SSL_TLSEXT_ERR_OK;
2817}
2818
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002819TEST_P(SSLVersionTest, SNICallback) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002820 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002821 ASSERT_TRUE(cert2);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002822 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002823 ASSERT_TRUE(key2);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002824
David Benjamin0fef3052016-11-18 15:11:10 +09002825 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
2826 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002827
David Benjamin83a32122017-02-14 18:34:54 -05002828 static const uint8_t kSCTList[] = {0, 6, 0, 4, 5, 6, 7, 8};
2829 static const uint8_t kOCSPResponse[] = {1, 2, 3, 4};
2830
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002831 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
2832 ASSERT_TRUE(server_ctx2);
2833 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()));
2834 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()));
2835 ASSERT_TRUE(SSL_CTX_set_signed_cert_timestamp_list(
2836 server_ctx2.get(), kSCTList, sizeof(kSCTList)));
2837 ASSERT_TRUE(SSL_CTX_set_ocsp_response(server_ctx2.get(), kOCSPResponse,
2838 sizeof(kOCSPResponse)));
2839 // Historically signing preferences would be lost in some cases with the
2840 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2841 // this doesn't happen when |version| is TLS 1.2, configure the private
2842 // key to only sign SHA-256.
2843 ASSERT_TRUE(SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
2844 &kECDSAWithSHA256, 1));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002845
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002846 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), SwitchContext);
2847 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002848
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002849 SSL_CTX_enable_signed_cert_timestamps(client_ctx_.get());
2850 SSL_CTX_enable_ocsp_stapling(client_ctx_.get());
David Benjamin83a32122017-02-14 18:34:54 -05002851
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002852 ASSERT_TRUE(Connect());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002853
David Benjamin0fef3052016-11-18 15:11:10 +09002854 // The client should have received |cert2|.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002855 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client_.get()));
2856 ASSERT_TRUE(peer);
2857 EXPECT_EQ(X509_cmp(peer.get(), cert2.get()), 0);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002858
David Benjamin83a32122017-02-14 18:34:54 -05002859 // The client should have received |server_ctx2|'s SCT list.
2860 const uint8_t *data;
2861 size_t len;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002862 SSL_get0_signed_cert_timestamp_list(client_.get(), &data, &len);
2863 EXPECT_EQ(Bytes(kSCTList), Bytes(data, len));
David Benjamin83a32122017-02-14 18:34:54 -05002864
2865 // The client should have received |server_ctx2|'s OCSP response.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002866 SSL_get0_ocsp_response(client_.get(), &data, &len);
2867 EXPECT_EQ(Bytes(kOCSPResponse), Bytes(data, len));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002868}
2869
David Benjaminf0d8e222017-02-04 10:58:26 -05002870// Test that the early callback can swap the maximum version.
2871TEST(SSLTest, EarlyCallbackVersionSwitch) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002872 bssl::UniquePtr<X509> cert = GetTestCertificate();
2873 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2874 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2875 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002876 ASSERT_TRUE(cert);
2877 ASSERT_TRUE(key);
2878 ASSERT_TRUE(server_ctx);
2879 ASSERT_TRUE(client_ctx);
2880 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
2881 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
2882 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
2883 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
David Benjamin99620572016-08-30 00:35:36 -04002884
David Benjaminf0d8e222017-02-04 10:58:26 -05002885 SSL_CTX_set_select_certificate_cb(
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002886 server_ctx.get(),
2887 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
David Benjaminf0d8e222017-02-04 10:58:26 -05002888 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002889 return ssl_select_cert_error;
David Benjaminf0d8e222017-02-04 10:58:26 -05002890 }
2891
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002892 return ssl_select_cert_success;
David Benjaminf0d8e222017-02-04 10:58:26 -05002893 });
David Benjamin99620572016-08-30 00:35:36 -04002894
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002895 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05002896 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04002897 server_ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002898 EXPECT_EQ(TLS1_2_VERSION, SSL_version(client.get()));
David Benjamin99620572016-08-30 00:35:36 -04002899}
2900
David Benjaminf0d8e222017-02-04 10:58:26 -05002901TEST(SSLTest, SetVersion) {
David Benjamin2dc02042016-09-19 19:57:37 -04002902 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002903 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002904
David Benjaminf0d8e222017-02-04 10:58:26 -05002905 // Set valid TLS versions.
2906 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2907 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
2908 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2909 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002910
David Benjaminf0d8e222017-02-04 10:58:26 -05002911 // Invalid TLS versions are rejected.
2912 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2913 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x0200));
2914 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2915 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2916 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x0200));
2917 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002918
David Benjaminf0d8e222017-02-04 10:58:26 -05002919 // Zero is the default version.
2920 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08002921 EXPECT_EQ(TLS1_3_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002922 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07002923 EXPECT_EQ(TLS1_VERSION, SSL_CTX_get_min_proto_version(ctx.get()));
David Benjamin3cfeb952017-03-01 16:48:38 -05002924
David Benjamin9bb15f52018-06-26 00:07:40 -04002925 // TLS 1.3 is available, but not by default.
David Benjamin3cfeb952017-03-01 16:48:38 -05002926 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07002927 EXPECT_EQ(TLS1_3_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjamine34bcc92016-09-21 16:53:09 -04002928
David Benjamin9bb15f52018-06-26 00:07:40 -04002929 // SSL 3.0 is not available.
2930 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION));
2931
David Benjamin2dc02042016-09-19 19:57:37 -04002932 ctx.reset(SSL_CTX_new(DTLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002933 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002934
David Benjaminf0d8e222017-02-04 10:58:26 -05002935 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2936 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION));
2937 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2938 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002939
David Benjaminf0d8e222017-02-04 10:58:26 -05002940 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2941 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2942 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2943 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2944 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2945 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2946 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2947 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002948
David Benjaminf0d8e222017-02-04 10:58:26 -05002949 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07002950 EXPECT_EQ(DTLS1_2_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002951 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07002952 EXPECT_EQ(DTLS1_VERSION, SSL_CTX_get_min_proto_version(ctx.get()));
David Benjamin2dc02042016-09-19 19:57:37 -04002953}
2954
David Benjamin458334a2016-12-15 13:53:25 -05002955static const char *GetVersionName(uint16_t version) {
2956 switch (version) {
David Benjamin458334a2016-12-15 13:53:25 -05002957 case TLS1_VERSION:
2958 return "TLSv1";
2959 case TLS1_1_VERSION:
2960 return "TLSv1.1";
2961 case TLS1_2_VERSION:
2962 return "TLSv1.2";
2963 case TLS1_3_VERSION:
2964 return "TLSv1.3";
2965 case DTLS1_VERSION:
2966 return "DTLSv1";
2967 case DTLS1_2_VERSION:
2968 return "DTLSv1.2";
2969 default:
2970 return "???";
2971 }
2972}
2973
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002974TEST_P(SSLVersionTest, Version) {
2975 ASSERT_TRUE(Connect());
David Benjamincb18ac22016-09-27 14:09:15 -04002976
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002977 EXPECT_EQ(SSL_version(client_.get()), version());
2978 EXPECT_EQ(SSL_version(server_.get()), version());
David Benjamincb18ac22016-09-27 14:09:15 -04002979
David Benjamin458334a2016-12-15 13:53:25 -05002980 // Test the version name is reported as expected.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002981 const char *version_name = GetVersionName(version());
2982 EXPECT_EQ(strcmp(version_name, SSL_get_version(client_.get())), 0);
2983 EXPECT_EQ(strcmp(version_name, SSL_get_version(server_.get())), 0);
David Benjamin458334a2016-12-15 13:53:25 -05002984
2985 // Test SSL_SESSION reports the same name.
2986 const char *client_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002987 SSL_SESSION_get_version(SSL_get_session(client_.get()));
David Benjamin458334a2016-12-15 13:53:25 -05002988 const char *server_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002989 SSL_SESSION_get_version(SSL_get_session(server_.get()));
2990 EXPECT_EQ(strcmp(version_name, client_name), 0);
2991 EXPECT_EQ(strcmp(version_name, server_name), 0);
David Benjamincb18ac22016-09-27 14:09:15 -04002992}
2993
David Benjamin9ef31f02016-10-31 18:01:13 -04002994// Tests that that |SSL_get_pending_cipher| is available during the ALPN
2995// selection callback.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002996TEST_P(SSLVersionTest, ALPNCipherAvailable) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002997 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2998
David Benjamin9ef31f02016-10-31 18:01:13 -04002999 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003000 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
3001 sizeof(kALPNProtos)),
3002 0);
David Benjamin0fef3052016-11-18 15:11:10 +09003003
3004 // The ALPN callback does not fail the handshake on error, so have the
3005 // callback write a boolean.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003006 std::pair<uint16_t, bool> callback_state(version(), false);
David Benjamin0fef3052016-11-18 15:11:10 +09003007 SSL_CTX_set_alpn_select_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003008 server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09003009 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
3010 unsigned in_len, void *arg) -> int {
3011 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
3012 if (SSL_get_pending_cipher(ssl) != nullptr &&
3013 SSL_version(ssl) == state->first) {
3014 state->second = true;
3015 }
3016 return SSL_TLSEXT_ERR_NOACK;
3017 },
3018 &callback_state);
3019
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003020 ASSERT_TRUE(Connect());
David Benjamin0fef3052016-11-18 15:11:10 +09003021
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003022 ASSERT_TRUE(callback_state.second);
David Benjamin0fef3052016-11-18 15:11:10 +09003023}
3024
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003025TEST_P(SSLVersionTest, SSLClearSessionResumption) {
David Benjaminb79cc842016-12-07 15:57:14 -05003026 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
3027 // API pattern.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003028 if (version() == TLS1_3_VERSION) {
3029 return;
David Benjaminb79cc842016-12-07 15:57:14 -05003030 }
3031
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07003032 shed_handshake_config_ = false;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003033 ASSERT_TRUE(Connect());
David Benjaminb79cc842016-12-07 15:57:14 -05003034
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003035 EXPECT_FALSE(SSL_session_reused(client_.get()));
3036 EXPECT_FALSE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003037
3038 // Reset everything.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003039 ASSERT_TRUE(SSL_clear(client_.get()));
3040 ASSERT_TRUE(SSL_clear(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003041
3042 // Attempt to connect a second time.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003043 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003044
3045 // |SSL_clear| should implicitly offer the previous session to the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003046 EXPECT_TRUE(SSL_session_reused(client_.get()));
3047 EXPECT_TRUE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003048}
3049
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07003050TEST_P(SSLVersionTest, SSLClearFailsWithShedding) {
3051 shed_handshake_config_ = false;
3052 ASSERT_TRUE(Connect());
3053 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
3054
3055 // Reset everything.
3056 ASSERT_TRUE(SSL_clear(client_.get()));
3057 ASSERT_TRUE(SSL_clear(server_.get()));
3058
3059 // Now enable shedding, and connect a second time.
3060 shed_handshake_config_ = true;
3061 ASSERT_TRUE(Connect());
3062 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
3063
3064 // |SSL_clear| should now fail.
3065 ASSERT_FALSE(SSL_clear(client_.get()));
3066 ASSERT_FALSE(SSL_clear(server_.get()));
3067}
3068
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003069static bool ChainsEqual(STACK_OF(X509) * chain,
3070 const std::vector<X509 *> &expected) {
David Benjamin1444c3a2016-12-20 17:23:11 -05003071 if (sk_X509_num(chain) != expected.size()) {
3072 return false;
3073 }
3074
3075 for (size_t i = 0; i < expected.size(); i++) {
3076 if (X509_cmp(sk_X509_value(chain, i), expected[i]) != 0) {
3077 return false;
3078 }
3079 }
3080
3081 return true;
3082}
3083
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003084TEST_P(SSLVersionTest, AutoChain) {
3085 cert_ = GetChainTestCertificate();
3086 ASSERT_TRUE(cert_);
3087 key_ = GetChainTestKey();
3088 ASSERT_TRUE(key_);
David Benjamin1444c3a2016-12-20 17:23:11 -05003089 bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003090 ASSERT_TRUE(intermediate);
3091
3092 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
3093 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin1444c3a2016-12-20 17:23:11 -05003094
3095 // Configure both client and server to accept any certificate. Add
3096 // |intermediate| to the cert store.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003097 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx_.get()),
3098 intermediate.get()));
3099 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(server_ctx_.get()),
3100 intermediate.get()));
3101 SSL_CTX_set_verify(client_ctx_.get(),
3102 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3103 nullptr);
3104 SSL_CTX_set_verify(server_ctx_.get(),
3105 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3106 nullptr);
3107 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
3108 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjamin1444c3a2016-12-20 17:23:11 -05003109
3110 // By default, the client and server should each only send the leaf.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003111 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05003112
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003113 EXPECT_TRUE(
3114 ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()), {cert_.get()}));
3115 EXPECT_TRUE(
3116 ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()), {cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003117
3118 // If auto-chaining is enabled, then the intermediate is sent.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003119 SSL_CTX_clear_mode(client_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
3120 SSL_CTX_clear_mode(server_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
3121 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05003122
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003123 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
3124 {cert_.get(), intermediate.get()}));
3125 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
3126 {cert_.get(), intermediate.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003127
3128 // Auto-chaining does not override explicitly-configured intermediates.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003129 ASSERT_TRUE(SSL_CTX_add1_chain_cert(client_ctx_.get(), cert_.get()));
3130 ASSERT_TRUE(SSL_CTX_add1_chain_cert(server_ctx_.get(), cert_.get()));
3131 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05003132
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003133 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
3134 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003135
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003136 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
3137 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003138}
3139
David Benjamin48063c22017-01-01 23:56:36 -05003140static bool ExpectBadWriteRetry() {
3141 int err = ERR_get_error();
3142 if (ERR_GET_LIB(err) != ERR_LIB_SSL ||
3143 ERR_GET_REASON(err) != SSL_R_BAD_WRITE_RETRY) {
3144 char buf[ERR_ERROR_STRING_BUF_LEN];
3145 ERR_error_string_n(err, buf, sizeof(buf));
3146 fprintf(stderr, "Wanted SSL_R_BAD_WRITE_RETRY, got: %s.\n", buf);
3147 return false;
3148 }
3149
3150 if (ERR_peek_error() != 0) {
3151 fprintf(stderr, "Unexpected error following SSL_R_BAD_WRITE_RETRY.\n");
3152 return false;
3153 }
3154
3155 return true;
3156}
3157
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003158TEST_P(SSLVersionTest, SSLWriteRetry) {
3159 if (is_dtls()) {
3160 return;
David Benjamin48063c22017-01-01 23:56:36 -05003161 }
3162
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003163 for (bool enable_partial_write : {false, true}) {
3164 SCOPED_TRACE(enable_partial_write);
3165
David Benjamin48063c22017-01-01 23:56:36 -05003166 // Connect a client and server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003167 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
3168
3169 ASSERT_TRUE(Connect());
David Benjamin48063c22017-01-01 23:56:36 -05003170
3171 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003172 SSL_set_mode(client_.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003173 }
3174
3175 // Write without reading until the buffer is full and we have an unfinished
3176 // write. Keep a count so we may reread it again later. "hello!" will be
3177 // written in two chunks, "hello" and "!".
3178 char data[] = "hello!";
3179 static const int kChunkLen = 5; // The length of "hello".
3180 unsigned count = 0;
3181 for (;;) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003182 int ret = SSL_write(client_.get(), data, kChunkLen);
David Benjamin48063c22017-01-01 23:56:36 -05003183 if (ret <= 0) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003184 ASSERT_EQ(SSL_get_error(client_.get(), ret), SSL_ERROR_WANT_WRITE);
3185 break;
David Benjamin48063c22017-01-01 23:56:36 -05003186 }
3187
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003188 ASSERT_EQ(ret, 5);
David Benjamin48063c22017-01-01 23:56:36 -05003189
3190 count++;
3191 }
3192
3193 // Retrying with the same parameters is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003194 ASSERT_EQ(
3195 SSL_get_error(client_.get(), SSL_write(client_.get(), data, kChunkLen)),
3196 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003197
3198 // Retrying with the same buffer but shorter length is not legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003199 ASSERT_EQ(SSL_get_error(client_.get(),
3200 SSL_write(client_.get(), data, kChunkLen - 1)),
3201 SSL_ERROR_SSL);
3202 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05003203
3204 // Retrying with a different buffer pointer is not legal.
3205 char data2[] = "hello";
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003206 ASSERT_EQ(SSL_get_error(client_.get(),
3207 SSL_write(client_.get(), data2, kChunkLen)),
3208 SSL_ERROR_SSL);
3209 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05003210
3211 // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003212 SSL_set_mode(client_.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
3213 ASSERT_EQ(SSL_get_error(client_.get(),
3214 SSL_write(client_.get(), data2, kChunkLen)),
3215 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003216
3217 // |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| does not disable length checks.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003218 ASSERT_EQ(SSL_get_error(client_.get(),
3219 SSL_write(client_.get(), data2, kChunkLen - 1)),
3220 SSL_ERROR_SSL);
3221 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05003222
3223 // Retrying with a larger buffer is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003224 ASSERT_EQ(SSL_get_error(client_.get(),
3225 SSL_write(client_.get(), data, kChunkLen + 1)),
3226 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003227
3228 // Drain the buffer.
3229 char buf[20];
3230 for (unsigned i = 0; i < count; i++) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003231 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
3232 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
David Benjamin48063c22017-01-01 23:56:36 -05003233 }
3234
3235 // Now that there is space, a retry with a larger buffer should flush the
3236 // pending record, skip over that many bytes of input (on assumption they
3237 // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE
3238 // is set, this will complete in two steps.
3239 char data3[] = "_____!";
3240 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003241 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen);
3242 ASSERT_EQ(SSL_write(client_.get(), data3 + kChunkLen, 1), 1);
3243 } else {
3244 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen + 1);
David Benjamin48063c22017-01-01 23:56:36 -05003245 }
3246
3247 // Check the last write was correct. The data will be spread over two
3248 // records, so SSL_read returns twice.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003249 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
3250 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
3251 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), 1);
3252 ASSERT_EQ(buf[0], '!');
David Benjamin48063c22017-01-01 23:56:36 -05003253 }
David Benjamin48063c22017-01-01 23:56:36 -05003254}
3255
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003256TEST_P(SSLVersionTest, RecordCallback) {
3257 for (bool test_server : {true, false}) {
3258 SCOPED_TRACE(test_server);
3259 ResetContexts();
David Benjamin5df5be1a2017-06-22 19:43:11 -04003260
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003261 bool read_seen = false;
3262 bool write_seen = false;
3263 auto cb = [&](int is_write, int cb_version, int cb_type, const void *buf,
3264 size_t len, SSL *ssl) {
3265 if (cb_type != SSL3_RT_HEADER) {
3266 return;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003267 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003268
3269 // The callback does not report a version for records.
3270 EXPECT_EQ(0, cb_version);
3271
3272 if (is_write) {
3273 write_seen = true;
3274 } else {
3275 read_seen = true;
3276 }
3277
3278 // Sanity-check that the record header is plausible.
3279 CBS cbs;
3280 CBS_init(&cbs, reinterpret_cast<const uint8_t *>(buf), len);
3281 uint8_t type;
3282 uint16_t record_version, length;
3283 ASSERT_TRUE(CBS_get_u8(&cbs, &type));
3284 ASSERT_TRUE(CBS_get_u16(&cbs, &record_version));
Steven Valdez64cc1212017-12-04 11:15:37 -05003285 EXPECT_EQ(record_version & 0xff00, version() & 0xff00);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003286 if (is_dtls()) {
3287 uint16_t epoch;
3288 ASSERT_TRUE(CBS_get_u16(&cbs, &epoch));
3289 EXPECT_TRUE(epoch == 0 || epoch == 1) << "Invalid epoch: " << epoch;
3290 ASSERT_TRUE(CBS_skip(&cbs, 6));
3291 }
3292 ASSERT_TRUE(CBS_get_u16(&cbs, &length));
3293 EXPECT_EQ(0u, CBS_len(&cbs));
3294 };
3295 using CallbackType = decltype(cb);
3296 SSL_CTX *ctx = test_server ? server_ctx_.get() : client_ctx_.get();
3297 SSL_CTX_set_msg_callback(
3298 ctx, [](int is_write, int cb_version, int cb_type, const void *buf,
3299 size_t len, SSL *ssl, void *arg) {
3300 CallbackType *cb_ptr = reinterpret_cast<CallbackType *>(arg);
3301 (*cb_ptr)(is_write, cb_version, cb_type, buf, len, ssl);
3302 });
3303 SSL_CTX_set_msg_callback_arg(ctx, &cb);
3304
3305 ASSERT_TRUE(Connect());
3306
3307 EXPECT_TRUE(read_seen);
3308 EXPECT_TRUE(write_seen);
David Benjamin0fef3052016-11-18 15:11:10 +09003309 }
David Benjamin9ef31f02016-10-31 18:01:13 -04003310}
3311
David Benjamina8614602017-09-06 15:40:19 -04003312TEST_P(SSLVersionTest, GetServerName) {
David Benjamina8614602017-09-06 15:40:19 -04003313 ClientConfig config;
3314 config.servername = "host1";
3315
3316 SSL_CTX_set_tlsext_servername_callback(
3317 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
3318 // During the handshake, |SSL_get_servername| must match |config|.
3319 ClientConfig *config_p = reinterpret_cast<ClientConfig *>(arg);
3320 EXPECT_STREQ(config_p->servername.c_str(),
3321 SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name));
3322 return SSL_TLSEXT_ERR_OK;
3323 });
3324 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), &config);
3325
3326 ASSERT_TRUE(Connect(config));
3327 // After the handshake, it must also be available.
3328 EXPECT_STREQ(config.servername.c_str(),
3329 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3330
3331 // Establish a session under host1.
3332 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3333 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3334 bssl::UniquePtr<SSL_SESSION> session =
3335 CreateClientSession(client_ctx_.get(), server_ctx_.get(), config);
3336
3337 // If the client resumes a session with a different name, |SSL_get_servername|
3338 // must return the new name.
3339 ASSERT_TRUE(session);
3340 config.session = session.get();
3341 config.servername = "host2";
3342 ASSERT_TRUE(Connect(config));
3343 EXPECT_STREQ(config.servername.c_str(),
3344 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3345}
3346
David Benjamin3d8f0802017-09-06 16:12:52 -04003347// Test that session cache mode bits are honored in the client session callback.
3348TEST_P(SSLVersionTest, ClientSessionCacheMode) {
3349 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_OFF);
3350 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3351
3352 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_CLIENT);
3353 EXPECT_TRUE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3354
3355 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_SERVER);
3356 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3357}
3358
Steven Valdez777a2392019-02-21 11:30:47 -05003359// Test that all versions survive tiny write buffers. In particular, TLS 1.3
3360// NewSessionTickets are written post-handshake. Servers that block
3361// |SSL_do_handshake| on writing them will deadlock if clients are not draining
3362// the buffer. Test that we do not do this.
3363TEST_P(SSLVersionTest, SmallBuffer) {
3364 // DTLS is a datagram protocol and requires packet-sized buffers.
3365 if (is_dtls()) {
3366 return;
3367 }
3368
3369 // Test both flushing NewSessionTickets with a zero-sized write and
3370 // non-zero-sized write.
3371 for (bool use_zero_write : {false, true}) {
3372 SCOPED_TRACE(use_zero_write);
3373
3374 g_last_session = nullptr;
3375 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3376 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
3377
3378 bssl::UniquePtr<SSL> client(SSL_new(client_ctx_.get())),
3379 server(SSL_new(server_ctx_.get()));
3380 ASSERT_TRUE(client);
3381 ASSERT_TRUE(server);
3382 SSL_set_connect_state(client.get());
3383 SSL_set_accept_state(server.get());
3384
3385 // Use a tiny buffer.
3386 BIO *bio1, *bio2;
3387 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 1, &bio2, 1));
3388
3389 // SSL_set_bio takes ownership.
3390 SSL_set_bio(client.get(), bio1, bio1);
3391 SSL_set_bio(server.get(), bio2, bio2);
3392
3393 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
3394 if (version() >= TLS1_3_VERSION) {
3395 // The post-handshake ticket should not have been processed yet.
3396 EXPECT_FALSE(g_last_session);
3397 }
3398
3399 if (use_zero_write) {
3400 ASSERT_TRUE(FlushNewSessionTickets(client.get(), server.get()));
3401 EXPECT_TRUE(g_last_session);
3402 }
3403
3404 // Send some data from server to client. If |use_zero_write| is false, this
3405 // will also flush the NewSessionTickets.
3406 static const char kMessage[] = "hello world";
3407 char buf[sizeof(kMessage)];
3408 for (;;) {
3409 int server_ret = SSL_write(server.get(), kMessage, sizeof(kMessage));
3410 int server_err = SSL_get_error(server.get(), server_ret);
3411 int client_ret = SSL_read(client.get(), buf, sizeof(buf));
3412 int client_err = SSL_get_error(client.get(), client_ret);
3413
3414 // The server will write a single record, so every iteration should see
3415 // |SSL_ERROR_WANT_WRITE| and |SSL_ERROR_WANT_READ|, until the final
3416 // iteration, where both will complete.
3417 if (server_ret > 0) {
3418 EXPECT_EQ(server_ret, static_cast<int>(sizeof(kMessage)));
3419 EXPECT_EQ(client_ret, static_cast<int>(sizeof(kMessage)));
3420 EXPECT_EQ(Bytes(buf), Bytes(kMessage));
3421 break;
3422 }
3423
3424 ASSERT_EQ(server_ret, -1);
3425 ASSERT_EQ(server_err, SSL_ERROR_WANT_WRITE);
3426 ASSERT_EQ(client_ret, -1);
3427 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
3428 }
3429
3430 // The NewSessionTickets should have been flushed and processed.
3431 EXPECT_TRUE(g_last_session);
3432 }
3433}
3434
Adam Langleye1e78132017-01-31 15:24:31 -08003435TEST(SSLTest, AddChainCertHack) {
3436 // Ensure that we don't accidently break the hack that we have in place to
3437 // keep curl and serf happy when they use an |X509| even after transfering
3438 // ownership.
3439
3440 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3441 ASSERT_TRUE(ctx);
3442 X509 *cert = GetTestCertificate().release();
3443 ASSERT_TRUE(cert);
3444 SSL_CTX_add0_chain_cert(ctx.get(), cert);
3445
3446 // This should not trigger a use-after-free.
3447 X509_cmp(cert, cert);
3448}
3449
David Benjaminb2ff2622017-02-03 17:06:18 -05003450TEST(SSLTest, GetCertificate) {
3451 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3452 ASSERT_TRUE(ctx);
3453 bssl::UniquePtr<X509> cert = GetTestCertificate();
3454 ASSERT_TRUE(cert);
3455 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
3456 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3457 ASSERT_TRUE(ssl);
3458
3459 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
3460 ASSERT_TRUE(cert2);
3461 X509 *cert3 = SSL_get_certificate(ssl.get());
3462 ASSERT_TRUE(cert3);
3463
3464 // The old and new certificates must be identical.
3465 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
3466 EXPECT_EQ(0, X509_cmp(cert.get(), cert3));
3467
3468 uint8_t *der = nullptr;
3469 long der_len = i2d_X509(cert.get(), &der);
3470 ASSERT_LT(0, der_len);
3471 bssl::UniquePtr<uint8_t> free_der(der);
3472
3473 uint8_t *der2 = nullptr;
3474 long der2_len = i2d_X509(cert2, &der2);
3475 ASSERT_LT(0, der2_len);
3476 bssl::UniquePtr<uint8_t> free_der2(der2);
3477
3478 uint8_t *der3 = nullptr;
3479 long der3_len = i2d_X509(cert3, &der3);
3480 ASSERT_LT(0, der3_len);
3481 bssl::UniquePtr<uint8_t> free_der3(der3);
3482
3483 // They must also encode identically.
David Benjamin7d7554b2017-02-04 11:48:59 -05003484 EXPECT_EQ(Bytes(der, der_len), Bytes(der2, der2_len));
3485 EXPECT_EQ(Bytes(der, der_len), Bytes(der3, der3_len));
David Benjaminb2ff2622017-02-03 17:06:18 -05003486}
3487
Adam Langleyd04ca952017-02-28 11:26:51 -08003488TEST(SSLTest, SetChainAndKeyMismatch) {
3489 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_with_buffers_method()));
3490 ASSERT_TRUE(ctx);
3491
3492 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3493 ASSERT_TRUE(key);
3494 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3495 ASSERT_TRUE(leaf);
3496 std::vector<CRYPTO_BUFFER*> chain = {
3497 leaf.get(),
3498 };
3499
3500 // Should fail because |GetTestKey| doesn't match the chain-test certificate.
3501 ASSERT_FALSE(SSL_CTX_set_chain_and_key(ctx.get(), &chain[0], chain.size(),
3502 key.get(), nullptr));
3503 ERR_clear_error();
3504}
3505
3506TEST(SSLTest, SetChainAndKey) {
3507 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3508 ASSERT_TRUE(client_ctx);
3509 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3510 ASSERT_TRUE(server_ctx);
3511
Adam Langley964256d2020-03-19 11:57:12 -07003512 ASSERT_EQ(nullptr, SSL_CTX_get0_chain(server_ctx.get()));
3513
Adam Langleyd04ca952017-02-28 11:26:51 -08003514 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3515 ASSERT_TRUE(key);
3516 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3517 ASSERT_TRUE(leaf);
3518 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3519 GetChainTestIntermediateBuffer();
3520 ASSERT_TRUE(intermediate);
3521 std::vector<CRYPTO_BUFFER*> chain = {
3522 leaf.get(), intermediate.get(),
3523 };
3524 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3525 chain.size(), key.get(), nullptr));
3526
Adam Langley964256d2020-03-19 11:57:12 -07003527 ASSERT_EQ(chain.size(),
3528 sk_CRYPTO_BUFFER_num(SSL_CTX_get0_chain(server_ctx.get())));
3529
David Benjamin3a1dd462017-07-11 16:13:10 -04003530 SSL_CTX_set_custom_verify(
3531 client_ctx.get(), SSL_VERIFY_PEER,
3532 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3533 return ssl_verify_ok;
3534 });
Adam Langleyd04ca952017-02-28 11:26:51 -08003535
3536 bssl::UniquePtr<SSL> client, server;
3537 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003538 server_ctx.get()));
Adam Langleyd04ca952017-02-28 11:26:51 -08003539}
3540
Matthew Braithwaite5301c102018-01-23 12:08:55 -08003541TEST(SSLTest, BuffersFailWithoutCustomVerify) {
3542 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3543 ASSERT_TRUE(client_ctx);
3544 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3545 ASSERT_TRUE(server_ctx);
3546
3547 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3548 ASSERT_TRUE(key);
3549 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3550 ASSERT_TRUE(leaf);
3551 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
3552 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3553 chain.size(), key.get(), nullptr));
3554
3555 // Without SSL_CTX_set_custom_verify(), i.e. with everything in the default
3556 // configuration, certificate verification should fail.
3557 bssl::UniquePtr<SSL> client, server;
3558 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3559 server_ctx.get()));
3560
3561 // Whereas with a verifier, the connection should succeed.
3562 SSL_CTX_set_custom_verify(
3563 client_ctx.get(), SSL_VERIFY_PEER,
3564 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3565 return ssl_verify_ok;
3566 });
3567 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3568 server_ctx.get()));
3569}
3570
3571TEST(SSLTest, CustomVerify) {
3572 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3573 ASSERT_TRUE(client_ctx);
3574 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3575 ASSERT_TRUE(server_ctx);
3576
3577 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3578 ASSERT_TRUE(key);
3579 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3580 ASSERT_TRUE(leaf);
3581 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
3582 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3583 chain.size(), key.get(), nullptr));
3584
3585 SSL_CTX_set_custom_verify(
3586 client_ctx.get(), SSL_VERIFY_PEER,
3587 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3588 return ssl_verify_ok;
3589 });
3590
3591 bssl::UniquePtr<SSL> client, server;
3592 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3593 server_ctx.get()));
3594
3595 // With SSL_VERIFY_PEER, ssl_verify_invalid should result in a dropped
3596 // connection.
3597 SSL_CTX_set_custom_verify(
3598 client_ctx.get(), SSL_VERIFY_PEER,
3599 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3600 return ssl_verify_invalid;
3601 });
3602
3603 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3604 server_ctx.get()));
3605
3606 // But with SSL_VERIFY_NONE, ssl_verify_invalid should not cause a dropped
3607 // connection.
3608 SSL_CTX_set_custom_verify(
3609 client_ctx.get(), SSL_VERIFY_NONE,
3610 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3611 return ssl_verify_invalid;
3612 });
3613
3614 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3615 server_ctx.get()));
3616}
3617
David Benjamin71dfad42017-07-16 17:27:39 -04003618TEST(SSLTest, ClientCABuffers) {
3619 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3620 ASSERT_TRUE(client_ctx);
3621 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3622 ASSERT_TRUE(server_ctx);
3623
3624 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3625 ASSERT_TRUE(key);
3626 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3627 ASSERT_TRUE(leaf);
3628 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3629 GetChainTestIntermediateBuffer();
3630 ASSERT_TRUE(intermediate);
3631 std::vector<CRYPTO_BUFFER *> chain = {
3632 leaf.get(),
3633 intermediate.get(),
3634 };
3635 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3636 chain.size(), key.get(), nullptr));
3637
3638 bssl::UniquePtr<CRYPTO_BUFFER> ca_name(
3639 CRYPTO_BUFFER_new(kTestName, sizeof(kTestName), nullptr));
3640 ASSERT_TRUE(ca_name);
3641 bssl::UniquePtr<STACK_OF(CRYPTO_BUFFER)> ca_names(
3642 sk_CRYPTO_BUFFER_new_null());
3643 ASSERT_TRUE(ca_names);
David Benjamin2908dd12018-06-29 17:46:42 -04003644 ASSERT_TRUE(PushToStack(ca_names.get(), std::move(ca_name)));
David Benjamin71dfad42017-07-16 17:27:39 -04003645 SSL_CTX_set0_client_CAs(server_ctx.get(), ca_names.release());
3646
3647 // Configure client and server to accept all certificates.
3648 SSL_CTX_set_custom_verify(
3649 client_ctx.get(), SSL_VERIFY_PEER,
3650 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3651 return ssl_verify_ok;
3652 });
3653 SSL_CTX_set_custom_verify(
3654 server_ctx.get(), SSL_VERIFY_PEER,
3655 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3656 return ssl_verify_ok;
3657 });
3658
3659 bool cert_cb_called = false;
3660 SSL_CTX_set_cert_cb(
3661 client_ctx.get(),
3662 [](SSL *ssl, void *arg) -> int {
David Benjamin5f001d12018-05-08 16:46:48 -04003663 const STACK_OF(CRYPTO_BUFFER) *peer_names =
David Benjamin71dfad42017-07-16 17:27:39 -04003664 SSL_get0_server_requested_CAs(ssl);
3665 EXPECT_EQ(1u, sk_CRYPTO_BUFFER_num(peer_names));
3666 CRYPTO_BUFFER *peer_name = sk_CRYPTO_BUFFER_value(peer_names, 0);
3667 EXPECT_EQ(Bytes(kTestName), Bytes(CRYPTO_BUFFER_data(peer_name),
3668 CRYPTO_BUFFER_len(peer_name)));
3669 *reinterpret_cast<bool *>(arg) = true;
3670 return 1;
3671 },
3672 &cert_cb_called);
3673
3674 bssl::UniquePtr<SSL> client, server;
3675 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003676 server_ctx.get()));
David Benjamin71dfad42017-07-16 17:27:39 -04003677 EXPECT_TRUE(cert_cb_called);
3678}
3679
David Benjamin91222b82017-03-09 20:10:56 -05003680// Configuring the empty cipher list, though an error, should still modify the
3681// configuration.
3682TEST(SSLTest, EmptyCipherList) {
3683 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3684 ASSERT_TRUE(ctx);
3685
3686 // Initially, the cipher list is not empty.
3687 EXPECT_NE(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3688
3689 // Configuring the empty cipher list fails.
3690 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), ""));
3691 ERR_clear_error();
3692
3693 // But the cipher list is still updated to empty.
3694 EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3695}
3696
Adam Langley4c341d02017-03-08 19:33:21 -08003697// ssl_test_ticket_aead_failure_mode enumerates the possible ways in which the
3698// test |SSL_TICKET_AEAD_METHOD| can fail.
3699enum ssl_test_ticket_aead_failure_mode {
3700 ssl_test_ticket_aead_ok = 0,
3701 ssl_test_ticket_aead_seal_fail,
3702 ssl_test_ticket_aead_open_soft_fail,
3703 ssl_test_ticket_aead_open_hard_fail,
3704};
3705
3706struct ssl_test_ticket_aead_state {
3707 unsigned retry_count;
3708 ssl_test_ticket_aead_failure_mode failure_mode;
3709};
3710
3711static int ssl_test_ticket_aead_ex_index_dup(CRYPTO_EX_DATA *to,
3712 const CRYPTO_EX_DATA *from,
3713 void **from_d, int index,
3714 long argl, void *argp) {
3715 abort();
3716}
3717
3718static void ssl_test_ticket_aead_ex_index_free(void *parent, void *ptr,
3719 CRYPTO_EX_DATA *ad, int index,
3720 long argl, void *argp) {
3721 auto state = reinterpret_cast<ssl_test_ticket_aead_state*>(ptr);
3722 if (state == nullptr) {
3723 return;
3724 }
3725
3726 OPENSSL_free(state);
3727}
3728
3729static CRYPTO_once_t g_ssl_test_ticket_aead_ex_index_once = CRYPTO_ONCE_INIT;
3730static int g_ssl_test_ticket_aead_ex_index;
3731
3732static int ssl_test_ticket_aead_get_ex_index() {
3733 CRYPTO_once(&g_ssl_test_ticket_aead_ex_index_once, [] {
3734 g_ssl_test_ticket_aead_ex_index = SSL_get_ex_new_index(
3735 0, nullptr, nullptr, ssl_test_ticket_aead_ex_index_dup,
3736 ssl_test_ticket_aead_ex_index_free);
3737 });
3738 return g_ssl_test_ticket_aead_ex_index;
3739}
3740
3741static size_t ssl_test_ticket_aead_max_overhead(SSL *ssl) {
3742 return 1;
3743}
3744
3745static int ssl_test_ticket_aead_seal(SSL *ssl, uint8_t *out, size_t *out_len,
3746 size_t max_out_len, const uint8_t *in,
3747 size_t in_len) {
3748 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3749 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3750
3751 if (state->failure_mode == ssl_test_ticket_aead_seal_fail ||
3752 max_out_len < in_len + 1) {
3753 return 0;
3754 }
3755
3756 OPENSSL_memmove(out, in, in_len);
3757 out[in_len] = 0xff;
3758 *out_len = in_len + 1;
3759
3760 return 1;
3761}
3762
3763static ssl_ticket_aead_result_t ssl_test_ticket_aead_open(
3764 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len,
3765 const uint8_t *in, size_t in_len) {
3766 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3767 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3768
3769 if (state->retry_count > 0) {
3770 state->retry_count--;
3771 return ssl_ticket_aead_retry;
3772 }
3773
3774 switch (state->failure_mode) {
3775 case ssl_test_ticket_aead_ok:
3776 break;
3777 case ssl_test_ticket_aead_seal_fail:
3778 // If |seal| failed then there shouldn't be any ticket to try and
3779 // decrypt.
3780 abort();
3781 break;
3782 case ssl_test_ticket_aead_open_soft_fail:
3783 return ssl_ticket_aead_ignore_ticket;
3784 case ssl_test_ticket_aead_open_hard_fail:
3785 return ssl_ticket_aead_error;
3786 }
3787
3788 if (in_len == 0 || in[in_len - 1] != 0xff) {
3789 return ssl_ticket_aead_ignore_ticket;
3790 }
3791
3792 if (max_out_len < in_len - 1) {
3793 return ssl_ticket_aead_error;
3794 }
3795
3796 OPENSSL_memmove(out, in, in_len - 1);
3797 *out_len = in_len - 1;
3798 return ssl_ticket_aead_success;
3799}
3800
3801static const SSL_TICKET_AEAD_METHOD kSSLTestTicketMethod = {
3802 ssl_test_ticket_aead_max_overhead,
3803 ssl_test_ticket_aead_seal,
3804 ssl_test_ticket_aead_open,
3805};
3806
3807static void ConnectClientAndServerWithTicketMethod(
3808 bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
3809 SSL_CTX *client_ctx, SSL_CTX *server_ctx, unsigned retry_count,
3810 ssl_test_ticket_aead_failure_mode failure_mode, SSL_SESSION *session) {
3811 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
3812 ASSERT_TRUE(client);
3813 ASSERT_TRUE(server);
3814 SSL_set_connect_state(client.get());
3815 SSL_set_accept_state(server.get());
3816
3817 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3818 OPENSSL_malloc(sizeof(ssl_test_ticket_aead_state)));
3819 ASSERT_TRUE(state);
3820 OPENSSL_memset(state, 0, sizeof(ssl_test_ticket_aead_state));
3821 state->retry_count = retry_count;
3822 state->failure_mode = failure_mode;
3823
3824 ASSERT_TRUE(SSL_set_ex_data(server.get(), ssl_test_ticket_aead_get_ex_index(),
3825 state));
3826
3827 SSL_set_session(client.get(), session);
3828
3829 BIO *bio1, *bio2;
3830 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
3831
3832 // SSL_set_bio takes ownership.
3833 SSL_set_bio(client.get(), bio1, bio1);
3834 SSL_set_bio(server.get(), bio2, bio2);
3835
3836 if (CompleteHandshakes(client.get(), server.get())) {
3837 *out_client = std::move(client);
3838 *out_server = std::move(server);
3839 } else {
3840 out_client->reset();
3841 out_server->reset();
3842 }
3843}
3844
David Benjaminc9775322018-04-13 16:39:12 -04003845using TicketAEADMethodParam =
3846 testing::tuple<uint16_t, unsigned, ssl_test_ticket_aead_failure_mode>;
3847
Adam Langley4c341d02017-03-08 19:33:21 -08003848class TicketAEADMethodTest
David Benjaminc9775322018-04-13 16:39:12 -04003849 : public ::testing::TestWithParam<TicketAEADMethodParam> {};
Adam Langley4c341d02017-03-08 19:33:21 -08003850
3851TEST_P(TicketAEADMethodTest, Resume) {
3852 bssl::UniquePtr<X509> cert = GetTestCertificate();
3853 ASSERT_TRUE(cert);
3854 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3855 ASSERT_TRUE(key);
3856
3857 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
3858 ASSERT_TRUE(server_ctx);
3859 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
3860 ASSERT_TRUE(client_ctx);
3861
3862 const uint16_t version = testing::get<0>(GetParam());
3863 const unsigned retry_count = testing::get<1>(GetParam());
3864 const ssl_test_ticket_aead_failure_mode failure_mode =
3865 testing::get<2>(GetParam());
3866
3867 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3868 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3869 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), version));
3870 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), version));
3871 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), version));
3872 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), version));
3873
3874 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
3875 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
3876 SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
3877 SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
David Benjamin707af292017-03-10 17:47:18 -05003878 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langley4c341d02017-03-08 19:33:21 -08003879
3880 SSL_CTX_set_ticket_aead_method(server_ctx.get(), &kSSLTestTicketMethod);
3881
3882 bssl::UniquePtr<SSL> client, server;
3883 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3884 server_ctx.get(), retry_count,
3885 failure_mode, nullptr);
3886 switch (failure_mode) {
3887 case ssl_test_ticket_aead_ok:
3888 case ssl_test_ticket_aead_open_hard_fail:
3889 case ssl_test_ticket_aead_open_soft_fail:
3890 ASSERT_TRUE(client);
3891 break;
3892 case ssl_test_ticket_aead_seal_fail:
3893 EXPECT_FALSE(client);
3894 return;
3895 }
3896 EXPECT_FALSE(SSL_session_reused(client.get()));
3897 EXPECT_FALSE(SSL_session_reused(server.get()));
3898
Steven Valdez777a2392019-02-21 11:30:47 -05003899 ASSERT_TRUE(FlushNewSessionTickets(client.get(), server.get()));
David Benjamin707af292017-03-10 17:47:18 -05003900 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
Adam Langley4c341d02017-03-08 19:33:21 -08003901 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3902 server_ctx.get(), retry_count,
David Benjamin707af292017-03-10 17:47:18 -05003903 failure_mode, session.get());
Adam Langley4c341d02017-03-08 19:33:21 -08003904 switch (failure_mode) {
3905 case ssl_test_ticket_aead_ok:
3906 ASSERT_TRUE(client);
3907 EXPECT_TRUE(SSL_session_reused(client.get()));
3908 EXPECT_TRUE(SSL_session_reused(server.get()));
3909 break;
3910 case ssl_test_ticket_aead_seal_fail:
3911 abort();
3912 break;
3913 case ssl_test_ticket_aead_open_hard_fail:
3914 EXPECT_FALSE(client);
3915 break;
3916 case ssl_test_ticket_aead_open_soft_fail:
3917 ASSERT_TRUE(client);
3918 EXPECT_FALSE(SSL_session_reused(client.get()));
3919 EXPECT_FALSE(SSL_session_reused(server.get()));
3920 }
3921}
3922
David Benjaminc9775322018-04-13 16:39:12 -04003923std::string TicketAEADMethodParamToString(
3924 const testing::TestParamInfo<TicketAEADMethodParam> &params) {
3925 std::string ret = GetVersionName(std::get<0>(params.param));
3926 // GTest only allows alphanumeric characters and '_' in the parameter
3927 // string. Additionally filter out the 'v' to get "TLS13" over "TLSv13".
3928 for (auto it = ret.begin(); it != ret.end();) {
3929 if (*it == '.' || *it == 'v') {
3930 it = ret.erase(it);
3931 } else {
3932 ++it;
3933 }
3934 }
3935 char retry_count[256];
3936 snprintf(retry_count, sizeof(retry_count), "%d", std::get<1>(params.param));
3937 ret += "_";
3938 ret += retry_count;
3939 ret += "Retries_";
3940 switch (std::get<2>(params.param)) {
3941 case ssl_test_ticket_aead_ok:
3942 ret += "OK";
3943 break;
3944 case ssl_test_ticket_aead_seal_fail:
3945 ret += "SealFail";
3946 break;
3947 case ssl_test_ticket_aead_open_soft_fail:
3948 ret += "OpenSoftFail";
3949 break;
3950 case ssl_test_ticket_aead_open_hard_fail:
3951 ret += "OpenHardFail";
3952 break;
3953 }
3954 return ret;
3955}
3956
David Benjaminbe7006a2019-04-09 18:05:02 -05003957INSTANTIATE_TEST_SUITE_P(
Adam Langley4c341d02017-03-08 19:33:21 -08003958 TicketAEADMethodTests, TicketAEADMethodTest,
David Benjaminc9775322018-04-13 16:39:12 -04003959 testing::Combine(testing::Values(TLS1_2_VERSION, TLS1_3_VERSION),
3960 testing::Values(0, 1, 2),
3961 testing::Values(ssl_test_ticket_aead_ok,
3962 ssl_test_ticket_aead_seal_fail,
3963 ssl_test_ticket_aead_open_soft_fail,
3964 ssl_test_ticket_aead_open_hard_fail)),
3965 TicketAEADMethodParamToString);
Adam Langley4c341d02017-03-08 19:33:21 -08003966
David Benjaminca743582017-06-15 17:51:35 -04003967TEST(SSLTest, SelectNextProto) {
3968 uint8_t *result;
3969 uint8_t result_len;
3970
3971 // If there is an overlap, it should be returned.
3972 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3973 SSL_select_next_proto(&result, &result_len,
3974 (const uint8_t *)"\1a\2bb\3ccc", 9,
3975 (const uint8_t *)"\1x\1y\1a\1z", 8));
3976 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
3977
3978 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3979 SSL_select_next_proto(&result, &result_len,
3980 (const uint8_t *)"\1a\2bb\3ccc", 9,
3981 (const uint8_t *)"\1x\1y\2bb\1z", 9));
3982 EXPECT_EQ(Bytes("bb"), Bytes(result, result_len));
3983
3984 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3985 SSL_select_next_proto(&result, &result_len,
3986 (const uint8_t *)"\1a\2bb\3ccc", 9,
3987 (const uint8_t *)"\1x\1y\3ccc\1z", 10));
3988 EXPECT_EQ(Bytes("ccc"), Bytes(result, result_len));
3989
3990 // Peer preference order takes precedence over local.
3991 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3992 SSL_select_next_proto(&result, &result_len,
3993 (const uint8_t *)"\1a\2bb\3ccc", 9,
3994 (const uint8_t *)"\3ccc\2bb\1a", 9));
3995 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
3996
3997 // If there is no overlap, return the first local protocol.
3998 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
3999 SSL_select_next_proto(&result, &result_len,
4000 (const uint8_t *)"\1a\2bb\3ccc", 9,
4001 (const uint8_t *)"\1x\2yy\3zzz", 9));
4002 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
4003
4004 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
4005 SSL_select_next_proto(&result, &result_len, nullptr, 0,
4006 (const uint8_t *)"\1x\2yy\3zzz", 9));
4007 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
4008}
4009
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004010TEST(SSLTest, SealRecord) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004011 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
4012 server_ctx(SSL_CTX_new(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004013 ASSERT_TRUE(client_ctx);
4014 ASSERT_TRUE(server_ctx);
4015
4016 bssl::UniquePtr<X509> cert = GetTestCertificate();
4017 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4018 ASSERT_TRUE(cert);
4019 ASSERT_TRUE(key);
4020 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
4021 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
4022
4023 bssl::UniquePtr<SSL> client, server;
4024 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004025 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004026
4027 const std::vector<uint8_t> record = {1, 2, 3, 4, 5};
4028 std::vector<uint8_t> prefix(
4029 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004030 body(record.size()),
4031 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004032 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4033 bssl::MakeSpan(body), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004034 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004035
4036 std::vector<uint8_t> sealed;
4037 sealed.insert(sealed.end(), prefix.begin(), prefix.end());
4038 sealed.insert(sealed.end(), body.begin(), body.end());
4039 sealed.insert(sealed.end(), suffix.begin(), suffix.end());
4040 std::vector<uint8_t> sealed_copy = sealed;
4041
4042 bssl::Span<uint8_t> plaintext;
4043 size_t record_len;
4044 uint8_t alert = 255;
4045 EXPECT_EQ(bssl::OpenRecord(server.get(), &plaintext, &record_len, &alert,
4046 bssl::MakeSpan(sealed)),
4047 bssl::OpenRecordResult::kOK);
4048 EXPECT_EQ(record_len, sealed.size());
4049 EXPECT_EQ(plaintext, record);
4050 EXPECT_EQ(255, alert);
4051}
4052
4053TEST(SSLTest, SealRecordInPlace) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004054 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
4055 server_ctx(SSL_CTX_new(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004056 ASSERT_TRUE(client_ctx);
4057 ASSERT_TRUE(server_ctx);
4058
4059 bssl::UniquePtr<X509> cert = GetTestCertificate();
4060 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4061 ASSERT_TRUE(cert);
4062 ASSERT_TRUE(key);
4063 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
4064 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
4065
4066 bssl::UniquePtr<SSL> client, server;
4067 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004068 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004069
4070 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
4071 std::vector<uint8_t> record = plaintext;
4072 std::vector<uint8_t> prefix(
4073 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004074 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004075 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4076 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004077 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004078 record.insert(record.begin(), prefix.begin(), prefix.end());
4079 record.insert(record.end(), suffix.begin(), suffix.end());
4080
4081 bssl::Span<uint8_t> result;
4082 size_t record_len;
4083 uint8_t alert;
4084 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
4085 bssl::MakeSpan(record)),
4086 bssl::OpenRecordResult::kOK);
4087 EXPECT_EQ(record_len, record.size());
4088 EXPECT_EQ(plaintext, result);
4089}
4090
4091TEST(SSLTest, SealRecordTrailingData) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004092 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
4093 server_ctx(SSL_CTX_new(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004094 ASSERT_TRUE(client_ctx);
4095 ASSERT_TRUE(server_ctx);
4096
4097 bssl::UniquePtr<X509> cert = GetTestCertificate();
4098 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4099 ASSERT_TRUE(cert);
4100 ASSERT_TRUE(key);
4101 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
4102 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
4103
4104 bssl::UniquePtr<SSL> client, server;
4105 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004106 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004107
4108 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
4109 std::vector<uint8_t> record = plaintext;
4110 std::vector<uint8_t> prefix(
4111 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004112 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004113 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4114 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004115 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004116 record.insert(record.begin(), prefix.begin(), prefix.end());
4117 record.insert(record.end(), suffix.begin(), suffix.end());
4118 record.insert(record.end(), {5, 4, 3, 2, 1});
4119
4120 bssl::Span<uint8_t> result;
4121 size_t record_len;
4122 uint8_t alert;
4123 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
4124 bssl::MakeSpan(record)),
4125 bssl::OpenRecordResult::kOK);
4126 EXPECT_EQ(record_len, record.size() - 5);
4127 EXPECT_EQ(plaintext, result);
4128}
4129
4130TEST(SSLTest, SealRecordInvalidSpanSize) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004131 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
4132 server_ctx(SSL_CTX_new(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004133 ASSERT_TRUE(client_ctx);
4134 ASSERT_TRUE(server_ctx);
4135
4136 bssl::UniquePtr<X509> cert = GetTestCertificate();
4137 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4138 ASSERT_TRUE(cert);
4139 ASSERT_TRUE(key);
4140 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
4141 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
4142
4143 bssl::UniquePtr<SSL> client, server;
4144 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004145 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004146
4147 std::vector<uint8_t> record = {1, 2, 3, 4, 5};
4148 std::vector<uint8_t> prefix(
4149 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004150 body(record.size()),
4151 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004152
4153 auto expect_err = []() {
4154 int err = ERR_get_error();
4155 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
4156 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_BUFFER_TOO_SMALL);
4157 ERR_clear_error();
4158 };
4159 EXPECT_FALSE(bssl::SealRecord(
4160 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004161 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004162 expect_err();
4163 EXPECT_FALSE(bssl::SealRecord(
4164 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004165 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004166 expect_err();
4167
4168 EXPECT_FALSE(
4169 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4170 bssl::MakeSpan(record.data(), record.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004171 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004172 expect_err();
4173 EXPECT_FALSE(
4174 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4175 bssl::MakeSpan(record.data(), record.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004176 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004177 expect_err();
4178
4179 EXPECT_FALSE(bssl::SealRecord(
4180 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004181 bssl::MakeSpan(suffix.data(), suffix.size() - 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004182 expect_err();
4183 EXPECT_FALSE(bssl::SealRecord(
4184 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004185 bssl::MakeSpan(suffix.data(), suffix.size() + 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004186 expect_err();
4187}
4188
David Benjamin617b8182017-08-29 15:33:10 -04004189// The client should gracefully handle no suitable ciphers being enabled.
4190TEST(SSLTest, NoCiphersAvailable) {
4191 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4192 ASSERT_TRUE(ctx);
4193
4194 // Configure |client_ctx| with a cipher list that does not intersect with its
4195 // version configuration.
4196 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
4197 ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
4198 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
4199
4200 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
4201 ASSERT_TRUE(ssl);
4202 SSL_set_connect_state(ssl.get());
4203
4204 UniquePtr<BIO> rbio(BIO_new(BIO_s_mem())), wbio(BIO_new(BIO_s_mem()));
4205 ASSERT_TRUE(rbio);
4206 ASSERT_TRUE(wbio);
4207 SSL_set0_rbio(ssl.get(), rbio.release());
4208 SSL_set0_wbio(ssl.get(), wbio.release());
4209
4210 int ret = SSL_do_handshake(ssl.get());
4211 EXPECT_EQ(-1, ret);
4212 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), ret));
4213 uint32_t err = ERR_get_error();
4214 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
4215 EXPECT_EQ(SSL_R_NO_CIPHERS_AVAILABLE, ERR_GET_REASON(err));
4216}
4217
David Benjamina4bafd32017-10-03 15:06:29 -04004218TEST_P(SSLVersionTest, SessionVersion) {
4219 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4220 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4221
4222 bssl::UniquePtr<SSL_SESSION> session =
4223 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4224 ASSERT_TRUE(session);
4225 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
4226
4227 // Sessions in TLS 1.3 and later should be single-use.
4228 EXPECT_EQ(version() == TLS1_3_VERSION,
4229 !!SSL_SESSION_should_be_single_use(session.get()));
4230
4231 // Making fake sessions for testing works.
4232 session.reset(SSL_SESSION_new(client_ctx_.get()));
4233 ASSERT_TRUE(session);
4234 ASSERT_TRUE(SSL_SESSION_set_protocol_version(session.get(), version()));
4235 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
4236}
4237
David Benjaminfdb7a352017-10-12 17:34:18 -04004238TEST_P(SSLVersionTest, SSLPending) {
4239 UniquePtr<SSL> ssl(SSL_new(client_ctx_.get()));
4240 ASSERT_TRUE(ssl);
4241 EXPECT_EQ(0, SSL_pending(ssl.get()));
4242
4243 ASSERT_TRUE(Connect());
4244 EXPECT_EQ(0, SSL_pending(client_.get()));
4245
4246 ASSERT_EQ(5, SSL_write(server_.get(), "hello", 5));
4247 ASSERT_EQ(5, SSL_write(server_.get(), "world", 5));
4248 EXPECT_EQ(0, SSL_pending(client_.get()));
4249
4250 char buf[10];
4251 ASSERT_EQ(1, SSL_peek(client_.get(), buf, 1));
4252 EXPECT_EQ(5, SSL_pending(client_.get()));
4253
4254 ASSERT_EQ(1, SSL_read(client_.get(), buf, 1));
4255 EXPECT_EQ(4, SSL_pending(client_.get()));
4256
4257 ASSERT_EQ(4, SSL_read(client_.get(), buf, 10));
4258 EXPECT_EQ(0, SSL_pending(client_.get()));
4259
4260 ASSERT_EQ(2, SSL_read(client_.get(), buf, 2));
4261 EXPECT_EQ(3, SSL_pending(client_.get()));
4262}
4263
David Benjamina031b612017-10-11 20:48:25 -04004264// Test that post-handshake tickets consumed by |SSL_shutdown| are ignored.
4265TEST(SSLTest, ShutdownIgnoresTickets) {
4266 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4267 ASSERT_TRUE(ctx);
4268 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_3_VERSION));
4269 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
4270
4271 bssl::UniquePtr<X509> cert = GetTestCertificate();
4272 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4273 ASSERT_TRUE(cert);
4274 ASSERT_TRUE(key);
4275 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
4276 ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
4277
4278 SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_BOTH);
4279
4280 bssl::UniquePtr<SSL> client, server;
4281 ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
4282
4283 SSL_CTX_sess_set_new_cb(ctx.get(), [](SSL *ssl, SSL_SESSION *session) -> int {
4284 ADD_FAILURE() << "New session callback called during SSL_shutdown";
4285 return 0;
4286 });
4287
4288 // Send close_notify.
4289 EXPECT_EQ(0, SSL_shutdown(server.get()));
4290 EXPECT_EQ(0, SSL_shutdown(client.get()));
4291
4292 // Receive close_notify.
4293 EXPECT_EQ(1, SSL_shutdown(server.get()));
4294 EXPECT_EQ(1, SSL_shutdown(client.get()));
4295}
4296
David Benjamin6cc352e2017-11-02 17:21:39 -04004297TEST(SSLTest, SignatureAlgorithmProperties) {
4298 EXPECT_EQ(EVP_PKEY_NONE, SSL_get_signature_algorithm_key_type(0x1234));
4299 EXPECT_EQ(nullptr, SSL_get_signature_algorithm_digest(0x1234));
4300 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(0x1234));
4301
4302 EXPECT_EQ(EVP_PKEY_RSA,
4303 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4304 EXPECT_EQ(EVP_md5_sha1(),
4305 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4306 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4307
4308 EXPECT_EQ(EVP_PKEY_EC, SSL_get_signature_algorithm_key_type(
4309 SSL_SIGN_ECDSA_SECP256R1_SHA256));
4310 EXPECT_EQ(EVP_sha256(), SSL_get_signature_algorithm_digest(
4311 SSL_SIGN_ECDSA_SECP256R1_SHA256));
4312 EXPECT_FALSE(
4313 SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_ECDSA_SECP256R1_SHA256));
4314
4315 EXPECT_EQ(EVP_PKEY_RSA,
David Benjamin6879e192018-04-13 16:01:02 -04004316 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04004317 EXPECT_EQ(EVP_sha384(),
David Benjamin6879e192018-04-13 16:01:02 -04004318 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PSS_RSAE_SHA384));
4319 EXPECT_TRUE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04004320}
4321
Adam Langley85967952018-07-03 08:04:58 -07004322static int XORCompressFunc(SSL *ssl, CBB *out, const uint8_t *in,
4323 size_t in_len) {
4324 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07004325 if (!CBB_add_u8(out, in[i] ^ 0x55)) {
Adam Langley85967952018-07-03 08:04:58 -07004326 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07004327 }
4328 }
4329
4330 SSL_set_app_data(ssl, XORCompressFunc);
4331
Adam Langley85967952018-07-03 08:04:58 -07004332 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07004333}
4334
Adam Langley85967952018-07-03 08:04:58 -07004335static int XORDecompressFunc(SSL *ssl, CRYPTO_BUFFER **out,
4336 size_t uncompressed_len, const uint8_t *in,
4337 size_t in_len) {
4338 if (in_len != uncompressed_len) {
4339 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07004340 }
4341
4342 uint8_t *data;
Adam Langley85967952018-07-03 08:04:58 -07004343 *out = CRYPTO_BUFFER_alloc(&data, uncompressed_len);
4344 if (*out == nullptr) {
4345 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07004346 }
4347
Adam Langley85967952018-07-03 08:04:58 -07004348 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07004349 data[i] = in[i] ^ 0x55;
4350 }
4351
4352 SSL_set_app_data(ssl, XORDecompressFunc);
4353
Adam Langley85967952018-07-03 08:04:58 -07004354 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07004355}
4356
4357TEST(SSLTest, CertCompression) {
4358 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4359 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4360 ASSERT_TRUE(client_ctx);
4361 ASSERT_TRUE(server_ctx);
4362
4363 bssl::UniquePtr<X509> cert = GetTestCertificate();
4364 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4365 ASSERT_TRUE(cert);
4366 ASSERT_TRUE(key);
4367 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
4368 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
4369
4370 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
4371 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
4372 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
4373 client_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
4374 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
4375 server_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
4376
4377 bssl::UniquePtr<SSL> client, server;
4378 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4379 server_ctx.get()));
4380
4381 EXPECT_TRUE(SSL_get_app_data(client.get()) == XORDecompressFunc);
4382 EXPECT_TRUE(SSL_get_app_data(server.get()) == XORCompressFunc);
4383}
4384
Adam Langleyddb57cf2018-01-26 09:17:53 -08004385void MoveBIOs(SSL *dest, SSL *src) {
4386 BIO *rbio = SSL_get_rbio(src);
4387 BIO_up_ref(rbio);
4388 SSL_set0_rbio(dest, rbio);
4389
4390 BIO *wbio = SSL_get_wbio(src);
4391 BIO_up_ref(wbio);
4392 SSL_set0_wbio(dest, wbio);
4393
4394 SSL_set0_rbio(src, nullptr);
4395 SSL_set0_wbio(src, nullptr);
4396}
4397
4398TEST(SSLTest, Handoff) {
4399 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4400 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4401 bssl::UniquePtr<SSL_CTX> handshaker_ctx(SSL_CTX_new(TLS_method()));
4402 ASSERT_TRUE(client_ctx);
4403 ASSERT_TRUE(server_ctx);
4404 ASSERT_TRUE(handshaker_ctx);
4405
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004406 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_CLIENT);
4407 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langleyddb57cf2018-01-26 09:17:53 -08004408 SSL_CTX_set_handoff_mode(server_ctx.get(), 1);
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004409 uint8_t keys[48];
David Benjamin243b5cc2019-12-04 11:23:50 -05004410 SSL_CTX_get_tlsext_ticket_keys(server_ctx.get(), &keys, sizeof(keys));
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004411 SSL_CTX_set_tlsext_ticket_keys(handshaker_ctx.get(), &keys, sizeof(keys));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004412
4413 bssl::UniquePtr<X509> cert = GetTestCertificate();
4414 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4415 ASSERT_TRUE(cert);
4416 ASSERT_TRUE(key);
4417 ASSERT_TRUE(SSL_CTX_use_certificate(handshaker_ctx.get(), cert.get()));
4418 ASSERT_TRUE(SSL_CTX_use_PrivateKey(handshaker_ctx.get(), key.get()));
4419
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004420 for (bool early_data : {false, true}) {
4421 SCOPED_TRACE(early_data);
4422 for (bool is_resume : {false, true}) {
4423 SCOPED_TRACE(is_resume);
4424 bssl::UniquePtr<SSL> client, server;
4425 auto config = ClientConfig();
4426 config.early_data = early_data;
4427 if (is_resume) {
4428 ASSERT_TRUE(g_last_session);
4429 config.session = g_last_session.get();
4430 }
4431 if (is_resume && config.early_data) {
4432 EXPECT_GT(g_last_session->ticket_max_early_data, 0u);
4433 }
4434 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4435 server_ctx.get(), config,
4436 false /* don't handshake */));
4437
4438 int client_ret = SSL_do_handshake(client.get());
4439 int client_err = SSL_get_error(client.get(), client_ret);
4440
4441 uint8_t byte_written;
4442 if (config.early_data && is_resume) {
4443 ASSERT_EQ(client_err, 0);
4444 EXPECT_TRUE(SSL_in_early_data(client.get()));
4445 // Attempt to write early data.
4446 byte_written = 43;
4447 EXPECT_EQ(SSL_write(client.get(), &byte_written, 1), 1);
4448 } else {
4449 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4450 }
4451
4452 int server_ret = SSL_do_handshake(server.get());
4453 int server_err = SSL_get_error(server.get(), server_ret);
4454 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
4455
4456 ScopedCBB cbb;
4457 Array<uint8_t> handoff;
4458 SSL_CLIENT_HELLO hello;
4459 ASSERT_TRUE(CBB_init(cbb.get(), 256));
4460 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
4461 ASSERT_TRUE(CBBFinishArray(cbb.get(), &handoff));
4462
4463 bssl::UniquePtr<SSL> handshaker(SSL_new(handshaker_ctx.get()));
4464 // Note split handshakes determines 0-RTT support, for both the current
4465 // handshake and newly-issued tickets, entirely by |handshaker|. There is
4466 // no need to call |SSL_set_early_data_enabled| on |server|.
4467 SSL_set_early_data_enabled(handshaker.get(), 1);
4468 ASSERT_TRUE(SSL_apply_handoff(handshaker.get(), handoff));
4469
4470 MoveBIOs(handshaker.get(), server.get());
4471
4472 int handshake_ret = SSL_do_handshake(handshaker.get());
4473 int handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
4474 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
4475
4476 // Double-check that additional calls to |SSL_do_handshake| continue
Adam Langley472d91c2020-02-18 12:12:35 -08004477 // to get |SSL_ERROR_HANDBACK|.
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004478 handshake_ret = SSL_do_handshake(handshaker.get());
4479 handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
4480 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
4481
4482 ScopedCBB cbb_handback;
4483 Array<uint8_t> handback;
4484 ASSERT_TRUE(CBB_init(cbb_handback.get(), 1024));
4485 ASSERT_TRUE(SSL_serialize_handback(handshaker.get(), cbb_handback.get()));
4486 ASSERT_TRUE(CBBFinishArray(cbb_handback.get(), &handback));
4487
4488 bssl::UniquePtr<SSL> server2(SSL_new(server_ctx.get()));
4489 ASSERT_TRUE(SSL_apply_handback(server2.get(), handback));
4490
4491 MoveBIOs(server2.get(), handshaker.get());
4492 ASSERT_TRUE(CompleteHandshakes(client.get(), server2.get()));
4493 EXPECT_EQ(is_resume, SSL_session_reused(client.get()));
4494
4495 if (config.early_data && is_resume) {
4496 // In this case, one byte of early data has already been written above.
4497 EXPECT_TRUE(SSL_early_data_accepted(client.get()));
4498 } else {
4499 byte_written = 42;
4500 EXPECT_EQ(SSL_write(client.get(), &byte_written, 1), 1);
4501 }
4502 uint8_t byte;
4503 EXPECT_EQ(SSL_read(server2.get(), &byte, 1), 1);
4504 EXPECT_EQ(byte_written, byte);
4505
4506 byte = 44;
4507 EXPECT_EQ(SSL_write(server2.get(), &byte, 1), 1);
4508 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
4509 EXPECT_EQ(44, byte);
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004510 }
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004511 }
Adam Langleyddb57cf2018-01-26 09:17:53 -08004512}
4513
4514TEST(SSLTest, HandoffDeclined) {
4515 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4516 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4517 ASSERT_TRUE(client_ctx);
4518 ASSERT_TRUE(server_ctx);
4519
4520 SSL_CTX_set_handoff_mode(server_ctx.get(), 1);
4521 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
4522
4523 bssl::UniquePtr<X509> cert = GetTestCertificate();
4524 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4525 ASSERT_TRUE(cert);
4526 ASSERT_TRUE(key);
4527 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
4528 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
4529
4530 bssl::UniquePtr<SSL> client, server;
4531 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4532 server_ctx.get(), ClientConfig(),
4533 false /* don't handshake */));
4534
4535 int client_ret = SSL_do_handshake(client.get());
4536 int client_err = SSL_get_error(client.get(), client_ret);
4537 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4538
4539 int server_ret = SSL_do_handshake(server.get());
4540 int server_err = SSL_get_error(server.get(), server_ret);
4541 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
4542
4543 ScopedCBB cbb;
Adam Langleyc9827e02019-04-12 14:46:50 -07004544 SSL_CLIENT_HELLO hello;
Adam Langleyddb57cf2018-01-26 09:17:53 -08004545 ASSERT_TRUE(CBB_init(cbb.get(), 256));
Adam Langleyc9827e02019-04-12 14:46:50 -07004546 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004547
4548 ASSERT_TRUE(SSL_decline_handoff(server.get()));
4549
4550 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
4551
4552 uint8_t byte = 42;
4553 EXPECT_EQ(SSL_write(client.get(), &byte, 1), 1);
4554 EXPECT_EQ(SSL_read(server.get(), &byte, 1), 1);
4555 EXPECT_EQ(42, byte);
4556
4557 byte = 43;
4558 EXPECT_EQ(SSL_write(server.get(), &byte, 1), 1);
4559 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
4560 EXPECT_EQ(43, byte);
4561}
4562
Adam Langley826ce152018-08-03 10:31:21 -07004563static std::string SigAlgsToString(Span<const uint16_t> sigalgs) {
4564 std::string ret = "{";
4565
4566 for (uint16_t v : sigalgs) {
4567 if (ret.size() > 1) {
4568 ret += ", ";
4569 }
4570
4571 char buf[8];
4572 snprintf(buf, sizeof(buf) - 1, "0x%02x", v);
4573 buf[sizeof(buf)-1] = 0;
4574 ret += std::string(buf);
4575 }
4576
4577 ret += "}";
4578 return ret;
4579}
4580
4581void ExpectSigAlgsEqual(Span<const uint16_t> expected,
4582 Span<const uint16_t> actual) {
4583 bool matches = false;
4584 if (expected.size() == actual.size()) {
4585 matches = true;
4586
4587 for (size_t i = 0; i < expected.size(); i++) {
4588 if (expected[i] != actual[i]) {
4589 matches = false;
4590 break;
4591 }
4592 }
4593 }
4594
4595 if (!matches) {
4596 ADD_FAILURE() << "expected: " << SigAlgsToString(expected)
4597 << " got: " << SigAlgsToString(actual);
4598 }
4599}
4600
4601TEST(SSLTest, SigAlgs) {
4602 static const struct {
4603 std::vector<int> input;
4604 bool ok;
4605 std::vector<uint16_t> expected;
4606 } kTests[] = {
4607 {{}, true, {}},
4608 {{1}, false, {}},
4609 {{1, 2, 3}, false, {}},
4610 {{NID_sha256, EVP_PKEY_ED25519}, false, {}},
4611 {{NID_sha256, EVP_PKEY_RSA, NID_sha256, EVP_PKEY_RSA}, false, {}},
4612
4613 {{NID_sha256, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA256}},
4614 {{NID_sha512, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA512}},
4615 {{NID_sha256, EVP_PKEY_RSA_PSS}, true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4616 {{NID_undef, EVP_PKEY_ED25519}, true, {SSL_SIGN_ED25519}},
4617 {{NID_undef, EVP_PKEY_ED25519, NID_sha384, EVP_PKEY_EC},
4618 true,
4619 {SSL_SIGN_ED25519, SSL_SIGN_ECDSA_SECP384R1_SHA384}},
4620 };
4621
4622 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4623
4624 unsigned n = 1;
4625 for (const auto &test : kTests) {
4626 SCOPED_TRACE(n++);
4627
4628 const bool ok =
4629 SSL_CTX_set1_sigalgs(ctx.get(), test.input.data(), test.input.size());
4630 EXPECT_EQ(ok, test.ok);
4631
4632 if (!ok) {
4633 ERR_clear_error();
4634 }
4635
4636 if (!test.ok) {
4637 continue;
4638 }
4639
4640 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
4641 }
4642}
4643
4644TEST(SSLTest, SigAlgsList) {
4645 static const struct {
4646 const char *input;
4647 bool ok;
4648 std::vector<uint16_t> expected;
4649 } kTests[] = {
4650 {"", false, {}},
4651 {":", false, {}},
4652 {"+", false, {}},
4653 {"RSA", false, {}},
4654 {"RSA+", false, {}},
4655 {"RSA+SHA256:", false, {}},
4656 {":RSA+SHA256:", false, {}},
4657 {":RSA+SHA256+:", false, {}},
4658 {"!", false, {}},
4659 {"\x01", false, {}},
4660 {"RSA+SHA256:RSA+SHA384:RSA+SHA256", false, {}},
4661 {"RSA-PSS+SHA256:rsa_pss_rsae_sha256", false, {}},
4662
4663 {"RSA+SHA256", true, {SSL_SIGN_RSA_PKCS1_SHA256}},
4664 {"RSA+SHA256:ed25519",
4665 true,
4666 {SSL_SIGN_RSA_PKCS1_SHA256, SSL_SIGN_ED25519}},
4667 {"ECDSA+SHA256:RSA+SHA512",
4668 true,
4669 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PKCS1_SHA512}},
4670 {"ecdsa_secp256r1_sha256:rsa_pss_rsae_sha256",
4671 true,
4672 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4673 {"RSA-PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4674 {"PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4675 };
4676
4677 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4678
4679 unsigned n = 1;
4680 for (const auto &test : kTests) {
4681 SCOPED_TRACE(n++);
4682
4683 const bool ok = SSL_CTX_set1_sigalgs_list(ctx.get(), test.input);
4684 EXPECT_EQ(ok, test.ok);
4685
4686 if (!ok) {
4687 if (test.ok) {
4688 ERR_print_errors_fp(stderr);
4689 }
4690 ERR_clear_error();
4691 }
4692
4693 if (!test.ok) {
4694 continue;
4695 }
4696
4697 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
4698 }
4699}
4700
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004701TEST(SSLTest, ApplyHandoffRemovesUnsupportedCiphers) {
4702 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4703 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
4704
4705 // handoff is a handoff message that has been artificially modified to pretend
4706 // that only cipher 0x0A is supported. When it is applied to |server|, all
4707 // ciphers but that one should be removed.
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004708 //
4709 // To make a new one of these, try sticking this in the |Handoff| test above:
4710 //
4711 // hexdump(stderr, "", handoff.data(), handoff.size());
4712 // sed -e 's/\(..\)/0x\1, /g'
4713 //
4714 // and modify serialize_features() to emit only cipher 0x0A.
4715
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004716 uint8_t handoff[] = {
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004717 0x30, 0x81, 0x9a, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
4718 0x00, 0x00, 0x7e, 0x03, 0x03, 0x30, 0x8e, 0x8f, 0x79, 0xd2, 0x87, 0x39,
4719 0xc2, 0x23, 0x23, 0x13, 0xca, 0x3c, 0x80, 0x44, 0xfd, 0x80, 0x83, 0x62,
4720 0x3c, 0xcc, 0xf8, 0x76, 0xd3, 0x62, 0xbb, 0x54, 0xe3, 0xc4, 0x39, 0x24,
4721 0xa5, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004722 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
4723 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004724 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
4725 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
4726 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
4727 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
4728 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x02, 0x00,
4729 0x0a, 0x04, 0x0a, 0x00, 0x15, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00,
4730 0x1d,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004731 };
4732
4733 EXPECT_EQ(20u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
4734 ASSERT_TRUE(
4735 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
4736 EXPECT_EQ(1u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
4737}
4738
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004739TEST(SSLTest, ApplyHandoffRemovesUnsupportedCurves) {
4740 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4741 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
4742
4743 // handoff is a handoff message that has been artificially modified to pretend
4744 // that only one curve is supported. When it is applied to |server|, all
4745 // curves but that one should be removed.
4746 //
4747 // See |ApplyHandoffRemovesUnsupportedCiphers| for how to make a new one of
4748 // these.
4749 uint8_t handoff[] = {
4750 0x30, 0x81, 0xc0, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
4751 0x00, 0x00, 0x7e, 0x03, 0x03, 0x98, 0x30, 0xce, 0xd9, 0xb0, 0xdf, 0x5f,
4752 0x82, 0x05, 0x4a, 0x43, 0x67, 0x7e, 0xdb, 0x6a, 0x4f, 0x21, 0x18, 0x4e,
4753 0x0d, 0x94, 0x63, 0x18, 0x8b, 0x54, 0x89, 0xdb, 0x8b, 0x1d, 0x84, 0xbc,
4754 0x09, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
4755 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
4756 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
4757 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
4758 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
4759 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
4760 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
4761 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x30, 0x00,
4762 0x02, 0x00, 0x0a, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x8c, 0x00, 0x8d, 0x00,
4763 0x9c, 0x00, 0x9d, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xc0, 0x09, 0xc0,
4764 0x0a, 0xc0, 0x13, 0xc0, 0x14, 0xc0, 0x2b, 0xc0, 0x2c, 0xc0, 0x2f, 0xc0,
4765 0x30, 0xc0, 0x35, 0xc0, 0x36, 0xcc, 0xa8, 0xcc, 0xa9, 0xcc, 0xac, 0x04,
4766 0x02, 0x00, 0x17,
4767 };
4768
4769 // The zero length means that the default list of groups is used.
4770 EXPECT_EQ(0u, server->config->supported_group_list.size());
4771 ASSERT_TRUE(
4772 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
4773 EXPECT_EQ(1u, server->config->supported_group_list.size());
4774}
4775
Adam Langleyba9ad662018-12-17 13:59:38 -08004776TEST(SSLTest, ZeroSizedWiteFlushesHandshakeMessages) {
4777 // If there are pending handshake mesages, an |SSL_write| of zero bytes should
4778 // flush them.
4779 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4780 EXPECT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
4781 EXPECT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
4782 bssl::UniquePtr<X509> cert = GetTestCertificate();
4783 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4784 ASSERT_TRUE(cert);
4785 ASSERT_TRUE(key);
4786 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
4787 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
4788
4789 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4790 EXPECT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
4791 EXPECT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
4792
4793 bssl::UniquePtr<SSL> client, server;
4794 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4795 server_ctx.get()));
4796
4797 BIO *client_wbio = SSL_get_wbio(client.get());
4798 EXPECT_EQ(0u, BIO_wpending(client_wbio));
4799 EXPECT_TRUE(SSL_key_update(client.get(), SSL_KEY_UPDATE_NOT_REQUESTED));
4800 EXPECT_EQ(0u, BIO_wpending(client_wbio));
4801 EXPECT_EQ(0, SSL_write(client.get(), nullptr, 0));
4802 EXPECT_NE(0u, BIO_wpending(client_wbio));
4803}
4804
David Benjamin5869eb32018-07-17 00:59:45 -04004805TEST_P(SSLVersionTest, VerifyBeforeCertRequest) {
4806 // Configure the server to request client certificates.
4807 SSL_CTX_set_custom_verify(
4808 server_ctx_.get(), SSL_VERIFY_PEER,
4809 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
4810
4811 // Configure the client to reject the server certificate.
4812 SSL_CTX_set_custom_verify(
4813 client_ctx_.get(), SSL_VERIFY_PEER,
4814 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_invalid; });
4815
4816 // cert_cb should not be called. Verification should fail first.
4817 SSL_CTX_set_cert_cb(client_ctx_.get(),
4818 [](SSL *ssl, void *arg) {
4819 ADD_FAILURE() << "cert_cb unexpectedly called";
4820 return 0;
4821 },
4822 nullptr);
4823
4824 bssl::UniquePtr<SSL> client, server;
4825 EXPECT_FALSE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
4826 server_ctx_.get()));
4827}
4828
David Benjamin492c9aa2018-08-31 16:35:22 -05004829// Test that ticket-based sessions on the client get fake session IDs.
4830TEST_P(SSLVersionTest, FakeIDsForTickets) {
4831 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4832 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4833
4834 bssl::UniquePtr<SSL_SESSION> session =
4835 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4836 ASSERT_TRUE(session);
4837
4838 EXPECT_TRUE(SSL_SESSION_has_ticket(session.get()));
4839 unsigned session_id_length;
4840 SSL_SESSION_get_id(session.get(), &session_id_length);
4841 EXPECT_NE(session_id_length, 0u);
4842}
4843
David Benjamin6c04bd12018-07-19 18:13:09 -04004844// These tests test multi-threaded behavior. They are intended to run with
4845// ThreadSanitizer.
David Benjamin5b33eff2018-09-22 16:52:48 -07004846#if defined(OPENSSL_THREADS)
David Benjamin6c04bd12018-07-19 18:13:09 -04004847TEST_P(SSLVersionTest, SessionCacheThreads) {
4848 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
4849 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4850 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4851
4852 if (version() == TLS1_3_VERSION) {
4853 // Our TLS 1.3 implementation does not support stateful resumption.
4854 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
4855 return;
4856 }
4857
4858 // Establish two client sessions to test with.
4859 bssl::UniquePtr<SSL_SESSION> session1 =
4860 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4861 ASSERT_TRUE(session1);
4862 bssl::UniquePtr<SSL_SESSION> session2 =
4863 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4864 ASSERT_TRUE(session2);
4865
4866 auto connect_with_session = [&](SSL_SESSION *session) {
4867 ClientConfig config;
4868 config.session = session;
4869 UniquePtr<SSL> client, server;
4870 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
4871 server_ctx_.get(), config));
4872 };
4873
4874 // Resume sessions in parallel with establishing new ones.
4875 {
4876 std::vector<std::thread> threads;
4877 threads.emplace_back([&] { connect_with_session(nullptr); });
4878 threads.emplace_back([&] { connect_with_session(nullptr); });
4879 threads.emplace_back([&] { connect_with_session(session1.get()); });
4880 threads.emplace_back([&] { connect_with_session(session1.get()); });
4881 threads.emplace_back([&] { connect_with_session(session2.get()); });
4882 threads.emplace_back([&] { connect_with_session(session2.get()); });
4883 for (auto &thread : threads) {
4884 thread.join();
4885 }
4886 }
4887
4888 // Hit the maximum session cache size across multiple threads
4889 size_t limit = SSL_CTX_sess_number(server_ctx_.get()) + 2;
4890 SSL_CTX_sess_set_cache_size(server_ctx_.get(), limit);
4891 {
4892 std::vector<std::thread> threads;
4893 for (int i = 0; i < 4; i++) {
4894 threads.emplace_back([&]() {
4895 connect_with_session(nullptr);
4896 EXPECT_LE(SSL_CTX_sess_number(server_ctx_.get()), limit);
4897 });
4898 }
4899 for (auto &thread : threads) {
4900 thread.join();
4901 }
4902 EXPECT_EQ(SSL_CTX_sess_number(server_ctx_.get()), limit);
4903 }
4904}
4905
4906TEST_P(SSLVersionTest, SessionTicketThreads) {
4907 for (bool renew_ticket : {false, true}) {
4908 SCOPED_TRACE(renew_ticket);
4909 ResetContexts();
4910 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4911 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4912 if (renew_ticket) {
4913 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
4914 }
4915
4916 // Establish two client sessions to test with.
4917 bssl::UniquePtr<SSL_SESSION> session1 =
4918 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4919 ASSERT_TRUE(session1);
4920 bssl::UniquePtr<SSL_SESSION> session2 =
4921 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4922 ASSERT_TRUE(session2);
4923
4924 auto connect_with_session = [&](SSL_SESSION *session) {
4925 ClientConfig config;
4926 config.session = session;
4927 UniquePtr<SSL> client, server;
4928 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
4929 server_ctx_.get(), config));
4930 };
4931
4932 // Resume sessions in parallel with establishing new ones.
4933 {
4934 std::vector<std::thread> threads;
4935 threads.emplace_back([&] { connect_with_session(nullptr); });
4936 threads.emplace_back([&] { connect_with_session(nullptr); });
4937 threads.emplace_back([&] { connect_with_session(session1.get()); });
4938 threads.emplace_back([&] { connect_with_session(session1.get()); });
4939 threads.emplace_back([&] { connect_with_session(session2.get()); });
4940 threads.emplace_back([&] { connect_with_session(session2.get()); });
4941 for (auto &thread : threads) {
4942 thread.join();
4943 }
4944 }
4945 }
4946}
4947
4948// SSL_CTX_get0_certificate needs to lock internally. Test this works.
4949TEST(SSLTest, GetCertificateThreads) {
4950 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4951 ASSERT_TRUE(ctx);
4952 bssl::UniquePtr<X509> cert = GetTestCertificate();
4953 ASSERT_TRUE(cert);
4954 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
4955
4956 // Existing code expects |SSL_CTX_get0_certificate| to be callable from two
4957 // threads concurrently. It originally was an immutable operation. Now we
4958 // implement it with a thread-safe cache, so it is worth testing.
4959 X509 *cert2_thread;
4960 std::thread thread(
4961 [&] { cert2_thread = SSL_CTX_get0_certificate(ctx.get()); });
4962 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
4963 thread.join();
4964
4965 EXPECT_EQ(cert2, cert2_thread);
4966 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
4967}
David Benjamin4cce9552018-12-13 12:20:54 -06004968
4969// Functions which access properties on the negotiated session are thread-safe
4970// where needed. Prior to TLS 1.3, clients resuming sessions and servers
4971// performing stateful resumption will share an underlying SSL_SESSION object,
4972// potentially across threads.
4973TEST_P(SSLVersionTest, SessionPropertiesThreads) {
4974 if (version() == TLS1_3_VERSION) {
4975 // Our TLS 1.3 implementation does not support stateful resumption.
4976 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
4977 return;
4978 }
4979
4980 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
4981 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4982 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4983
4984 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
4985 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
4986
4987 // Configure mutual authentication, so we have more session state.
4988 SSL_CTX_set_custom_verify(
4989 client_ctx_.get(), SSL_VERIFY_PEER,
4990 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
4991 SSL_CTX_set_custom_verify(
4992 server_ctx_.get(), SSL_VERIFY_PEER,
4993 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
4994
4995 // Establish a client session to test with.
4996 bssl::UniquePtr<SSL_SESSION> session =
4997 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4998 ASSERT_TRUE(session);
4999
5000 // Resume with it twice.
5001 UniquePtr<SSL> ssls[4];
5002 ClientConfig config;
5003 config.session = session.get();
5004 ASSERT_TRUE(ConnectClientAndServer(&ssls[0], &ssls[1], client_ctx_.get(),
5005 server_ctx_.get(), config));
5006 ASSERT_TRUE(ConnectClientAndServer(&ssls[2], &ssls[3], client_ctx_.get(),
5007 server_ctx_.get(), config));
5008
5009 // Read properties in parallel.
5010 auto read_properties = [](const SSL *ssl) {
5011 EXPECT_TRUE(SSL_get_peer_cert_chain(ssl));
5012 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(ssl));
5013 EXPECT_TRUE(peer);
5014 EXPECT_TRUE(SSL_get_current_cipher(ssl));
5015 EXPECT_TRUE(SSL_get_curve_id(ssl));
5016 };
5017
5018 std::vector<std::thread> threads;
5019 for (const auto &ssl_ptr : ssls) {
5020 const SSL *ssl = ssl_ptr.get();
5021 threads.emplace_back([=] { read_properties(ssl); });
5022 }
5023 for (auto &thread : threads) {
5024 thread.join();
5025 }
5026}
David Benjamina486c6c2019-03-28 18:32:38 -05005027#endif // OPENSSL_THREADS
David Benjamin6c04bd12018-07-19 18:13:09 -04005028
Steven Valdezc8e0f902018-07-14 11:23:01 -04005029constexpr size_t kNumQUICLevels = 4;
5030static_assert(ssl_encryption_initial < kNumQUICLevels,
5031 "kNumQUICLevels is wrong");
5032static_assert(ssl_encryption_early_data < kNumQUICLevels,
5033 "kNumQUICLevels is wrong");
5034static_assert(ssl_encryption_handshake < kNumQUICLevels,
5035 "kNumQUICLevels is wrong");
5036static_assert(ssl_encryption_application < kNumQUICLevels,
5037 "kNumQUICLevels is wrong");
5038
David Benjamin1e859052020-02-09 16:04:58 -05005039const char *LevelToString(ssl_encryption_level_t level) {
5040 switch (level) {
5041 case ssl_encryption_initial:
5042 return "initial";
5043 case ssl_encryption_early_data:
5044 return "early data";
5045 case ssl_encryption_handshake:
5046 return "handshake";
5047 case ssl_encryption_application:
5048 return "application";
5049 }
5050 return "<unknown>";
5051}
5052
Steven Valdezc8e0f902018-07-14 11:23:01 -04005053class MockQUICTransport {
5054 public:
David Benjamind6343572019-08-15 17:29:02 -04005055 enum class Role { kClient, kServer };
5056
5057 explicit MockQUICTransport(Role role) : role_(role) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005058 // The caller is expected to configure initial secrets.
5059 levels_[ssl_encryption_initial].write_secret = {1};
5060 levels_[ssl_encryption_initial].read_secret = {1};
5061 }
5062
5063 void set_peer(MockQUICTransport *peer) { peer_ = peer; }
5064
5065 bool has_alert() const { return has_alert_; }
5066 ssl_encryption_level_t alert_level() const { return alert_level_; }
5067 uint8_t alert() const { return alert_; }
5068
5069 bool PeerSecretsMatch(ssl_encryption_level_t level) const {
5070 return levels_[level].write_secret == peer_->levels_[level].read_secret &&
Steven Valdez384d0ea2018-11-06 10:45:36 -05005071 levels_[level].read_secret == peer_->levels_[level].write_secret &&
5072 levels_[level].cipher == peer_->levels_[level].cipher;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005073 }
5074
David Benjamin1e859052020-02-09 16:04:58 -05005075 bool HasReadSecret(ssl_encryption_level_t level) const {
5076 return !levels_[level].read_secret.empty();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005077 }
5078
David Benjamin1e859052020-02-09 16:04:58 -05005079 bool HasWriteSecret(ssl_encryption_level_t level) const {
5080 return !levels_[level].write_secret.empty();
5081 }
5082
David Benjamin5298ef92020-03-13 12:17:30 -04005083 void AllowOutOfOrderWrites() { allow_out_of_order_writes_ = true; }
5084
David Benjamin1e859052020-02-09 16:04:58 -05005085 bool SetReadSecret(ssl_encryption_level_t level, const SSL_CIPHER *cipher,
5086 Span<const uint8_t> secret) {
5087 if (HasReadSecret(level)) {
5088 ADD_FAILURE() << LevelToString(level) << " read secret configured twice";
5089 return false;
5090 }
5091
5092 if (role_ == Role::kClient && level == ssl_encryption_early_data) {
5093 ADD_FAILURE() << "Unexpected early data read secret";
5094 return false;
5095 }
5096
5097 ssl_encryption_level_t ack_level =
5098 level == ssl_encryption_early_data ? ssl_encryption_application : level;
5099 if (!HasWriteSecret(ack_level)) {
5100 ADD_FAILURE() << LevelToString(level)
5101 << " read secret configured before ACK write secret";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005102 return false;
5103 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05005104
5105 if (cipher == nullptr) {
David Benjamin1e859052020-02-09 16:04:58 -05005106 ADD_FAILURE() << "Unexpected null cipher";
Steven Valdez384d0ea2018-11-06 10:45:36 -05005107 return false;
5108 }
5109
David Benjamin1e859052020-02-09 16:04:58 -05005110 if (level != ssl_encryption_early_data &&
5111 SSL_CIPHER_get_id(cipher) != levels_[level].cipher) {
5112 ADD_FAILURE() << "Cipher suite inconsistent";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005113 return false;
5114 }
David Benjamind6343572019-08-15 17:29:02 -04005115
David Benjamin1e859052020-02-09 16:04:58 -05005116 levels_[level].read_secret.assign(secret.begin(), secret.end());
5117 levels_[level].cipher = SSL_CIPHER_get_id(cipher);
5118 return true;
5119 }
5120
5121 bool SetWriteSecret(ssl_encryption_level_t level, const SSL_CIPHER *cipher,
5122 Span<const uint8_t> secret) {
5123 if (HasWriteSecret(level)) {
5124 ADD_FAILURE() << LevelToString(level) << " write secret configured twice";
David Benjamind6343572019-08-15 17:29:02 -04005125 return false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005126 }
David Benjamind6343572019-08-15 17:29:02 -04005127
David Benjamin1e859052020-02-09 16:04:58 -05005128 if (role_ == Role::kServer && level == ssl_encryption_early_data) {
5129 ADD_FAILURE() << "Unexpected early data write secret";
5130 return false;
5131 }
5132
5133 if (cipher == nullptr) {
5134 ADD_FAILURE() << "Unexpected null cipher";
5135 return false;
5136 }
5137
5138 levels_[level].write_secret.assign(secret.begin(), secret.end());
Steven Valdez384d0ea2018-11-06 10:45:36 -05005139 levels_[level].cipher = SSL_CIPHER_get_id(cipher);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005140 return true;
5141 }
5142
5143 bool WriteHandshakeData(ssl_encryption_level_t level,
5144 Span<const uint8_t> data) {
5145 if (levels_[level].write_secret.empty()) {
David Benjamin1e859052020-02-09 16:04:58 -05005146 ADD_FAILURE() << LevelToString(level)
5147 << " write secret not yet configured";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005148 return false;
5149 }
David Benjamin5298ef92020-03-13 12:17:30 -04005150
5151 // Although the levels are conceptually separate, BoringSSL finishes writing
5152 // data from a previous level before installing keys for the next level.
5153 if (!allow_out_of_order_writes_) {
5154 switch (level) {
5155 case ssl_encryption_early_data:
5156 ADD_FAILURE() << "unexpected handshake data at early data level";
5157 return false;
5158 case ssl_encryption_initial:
5159 if (!levels_[ssl_encryption_handshake].write_secret.empty()) {
5160 ADD_FAILURE()
5161 << LevelToString(level)
5162 << " handshake data written after handshake keys installed";
5163 return false;
5164 }
5165 OPENSSL_FALLTHROUGH;
5166 case ssl_encryption_handshake:
5167 if (!levels_[ssl_encryption_application].write_secret.empty()) {
5168 ADD_FAILURE()
5169 << LevelToString(level)
5170 << " handshake data written after application keys installed";
5171 return false;
5172 }
5173 OPENSSL_FALLTHROUGH;
5174 case ssl_encryption_application:
5175 break;
5176 }
5177 }
5178
Steven Valdezc8e0f902018-07-14 11:23:01 -04005179 levels_[level].write_data.insert(levels_[level].write_data.end(),
5180 data.begin(), data.end());
5181 return true;
5182 }
5183
5184 bool SendAlert(ssl_encryption_level_t level, uint8_t alert_value) {
5185 if (has_alert_) {
5186 ADD_FAILURE() << "duplicate alert sent";
5187 return false;
5188 }
5189
5190 if (levels_[level].write_secret.empty()) {
David Benjamin1e859052020-02-09 16:04:58 -05005191 ADD_FAILURE() << LevelToString(level)
5192 << " write secret not yet configured";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005193 return false;
5194 }
5195
5196 has_alert_ = true;
5197 alert_level_ = level;
5198 alert_ = alert_value;
5199 return true;
5200 }
5201
5202 bool ReadHandshakeData(std::vector<uint8_t> *out,
5203 ssl_encryption_level_t level,
5204 size_t num = std::numeric_limits<size_t>::max()) {
5205 if (levels_[level].read_secret.empty()) {
David Benjamind6343572019-08-15 17:29:02 -04005206 ADD_FAILURE() << "data read before keys configured in level " << level;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005207 return false;
5208 }
5209 // The peer may not have configured any keys yet.
5210 if (peer_->levels_[level].write_secret.empty()) {
David Benjamind0b97942019-08-21 12:54:20 -04005211 out->clear();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005212 return true;
5213 }
5214 // Check the peer computed the same key.
5215 if (peer_->levels_[level].write_secret != levels_[level].read_secret) {
David Benjamind6343572019-08-15 17:29:02 -04005216 ADD_FAILURE() << "peer write key does not match read key in level "
5217 << level;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005218 return false;
5219 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05005220 if (peer_->levels_[level].cipher != levels_[level].cipher) {
David Benjamind6343572019-08-15 17:29:02 -04005221 ADD_FAILURE() << "peer cipher does not match in level " << level;
Steven Valdez384d0ea2018-11-06 10:45:36 -05005222 return false;
5223 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04005224 std::vector<uint8_t> *peer_data = &peer_->levels_[level].write_data;
5225 num = std::min(num, peer_data->size());
5226 out->assign(peer_data->begin(), peer_data->begin() + num);
5227 peer_data->erase(peer_data->begin(), peer_data->begin() + num);
5228 return true;
5229 }
5230
5231 private:
David Benjamind6343572019-08-15 17:29:02 -04005232 Role role_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005233 MockQUICTransport *peer_ = nullptr;
5234
David Benjamin5298ef92020-03-13 12:17:30 -04005235 bool allow_out_of_order_writes_ = false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005236 bool has_alert_ = false;
5237 ssl_encryption_level_t alert_level_ = ssl_encryption_initial;
5238 uint8_t alert_ = 0;
5239
5240 struct Level {
5241 std::vector<uint8_t> write_data;
5242 std::vector<uint8_t> write_secret;
5243 std::vector<uint8_t> read_secret;
Steven Valdez384d0ea2018-11-06 10:45:36 -05005244 uint32_t cipher = 0;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005245 };
5246 Level levels_[kNumQUICLevels];
5247};
5248
5249class MockQUICTransportPair {
5250 public:
David Benjamind6343572019-08-15 17:29:02 -04005251 MockQUICTransportPair()
5252 : client_(MockQUICTransport::Role::kClient),
5253 server_(MockQUICTransport::Role::kServer) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005254 client_.set_peer(&server_);
David Benjamind6343572019-08-15 17:29:02 -04005255 server_.set_peer(&client_);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005256 }
5257
5258 ~MockQUICTransportPair() {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005259 client_.set_peer(nullptr);
David Benjamind6343572019-08-15 17:29:02 -04005260 server_.set_peer(nullptr);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005261 }
5262
5263 MockQUICTransport *client() { return &client_; }
5264 MockQUICTransport *server() { return &server_; }
5265
5266 bool SecretsMatch(ssl_encryption_level_t level) const {
David Benjamin1e859052020-02-09 16:04:58 -05005267 // We only need to check |HasReadSecret| and |HasWriteSecret| on |client_|.
5268 // |PeerSecretsMatch| checks that |server_| is analogously configured.
5269 return client_.PeerSecretsMatch(level) &&
5270 client_.HasWriteSecret(level) &&
5271 (level == ssl_encryption_early_data || client_.HasReadSecret(level));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005272 }
5273
5274 private:
5275 MockQUICTransport client_;
5276 MockQUICTransport server_;
5277};
5278
5279class QUICMethodTest : public testing::Test {
5280 protected:
5281 void SetUp() override {
5282 client_ctx_.reset(SSL_CTX_new(TLS_method()));
5283 server_ctx_.reset(SSL_CTX_new(TLS_method()));
5284 ASSERT_TRUE(client_ctx_);
5285 ASSERT_TRUE(server_ctx_);
5286
5287 bssl::UniquePtr<X509> cert = GetTestCertificate();
5288 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
5289 ASSERT_TRUE(cert);
5290 ASSERT_TRUE(key);
5291 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx_.get(), cert.get()));
5292 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx_.get(), key.get()));
5293
5294 SSL_CTX_set_min_proto_version(server_ctx_.get(), TLS1_3_VERSION);
5295 SSL_CTX_set_max_proto_version(server_ctx_.get(), TLS1_3_VERSION);
5296 SSL_CTX_set_min_proto_version(client_ctx_.get(), TLS1_3_VERSION);
5297 SSL_CTX_set_max_proto_version(client_ctx_.get(), TLS1_3_VERSION);
Nick Harper74161f42020-07-24 15:35:27 -07005298
5299 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
5300 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
5301 sizeof(kALPNProtos)),
5302 0);
5303 SSL_CTX_set_alpn_select_cb(
5304 server_ctx_.get(),
5305 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
5306 unsigned in_len, void *arg) -> int {
5307 return SSL_select_next_proto(
5308 const_cast<uint8_t **>(out), out_len, in, in_len,
5309 kALPNProtos, sizeof(kALPNProtos)) == OPENSSL_NPN_NEGOTIATED
5310 ? SSL_TLSEXT_ERR_OK
5311 : SSL_TLSEXT_ERR_NOACK;
5312 },
5313 nullptr);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005314 }
5315
5316 static MockQUICTransport *TransportFromSSL(const SSL *ssl) {
5317 return ex_data_.Get(ssl);
5318 }
5319
5320 static bool ProvideHandshakeData(
5321 SSL *ssl, size_t num = std::numeric_limits<size_t>::max()) {
5322 MockQUICTransport *transport = TransportFromSSL(ssl);
5323 ssl_encryption_level_t level = SSL_quic_read_level(ssl);
5324 std::vector<uint8_t> data;
5325 return transport->ReadHandshakeData(&data, level, num) &&
5326 SSL_provide_quic_data(ssl, level, data.data(), data.size());
5327 }
5328
David Benjamin5298ef92020-03-13 12:17:30 -04005329 void AllowOutOfOrderWrites() {
5330 allow_out_of_order_writes_ = true;
5331 }
5332
Steven Valdezc8e0f902018-07-14 11:23:01 -04005333 bool CreateClientAndServer() {
5334 client_.reset(SSL_new(client_ctx_.get()));
5335 server_.reset(SSL_new(server_ctx_.get()));
5336 if (!client_ || !server_) {
5337 return false;
5338 }
5339
5340 SSL_set_connect_state(client_.get());
5341 SSL_set_accept_state(server_.get());
5342
David Benjamind6343572019-08-15 17:29:02 -04005343 transport_.reset(new MockQUICTransportPair);
5344 ex_data_.Set(client_.get(), transport_->client());
5345 ex_data_.Set(server_.get(), transport_->server());
David Benjamin5298ef92020-03-13 12:17:30 -04005346 if (allow_out_of_order_writes_) {
5347 transport_->client()->AllowOutOfOrderWrites();
5348 transport_->server()->AllowOutOfOrderWrites();
5349 }
Nick Harper7c522992020-04-30 14:15:49 -07005350 static const uint8_t client_transport_params[] = {0};
5351 if (!SSL_set_quic_transport_params(client_.get(), client_transport_params,
5352 sizeof(client_transport_params)) ||
5353 !SSL_set_quic_transport_params(server_.get(),
5354 server_transport_params_.data(),
5355 server_transport_params_.size()) ||
5356 !SSL_set_quic_early_data_context(
5357 server_.get(), server_quic_early_data_context_.data(),
5358 server_quic_early_data_context_.size())) {
Nick Harper72cff812020-03-26 18:06:16 -07005359 return false;
5360 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04005361 return true;
5362 }
5363
Nick Harper72cff812020-03-26 18:06:16 -07005364 enum class ExpectedError {
5365 kNoError,
5366 kClientError,
5367 kServerError,
5368 };
5369
David Benjamind6343572019-08-15 17:29:02 -04005370 // CompleteHandshakesForQUIC runs |SSL_do_handshake| on |client_| and
5371 // |server_| until each completes once. It returns true on success and false
5372 // on failure.
5373 bool CompleteHandshakesForQUIC() {
Nick Harper72cff812020-03-26 18:06:16 -07005374 return RunQUICHandshakesAndExpectError(ExpectedError::kNoError);
5375 }
5376
5377 // Runs |SSL_do_handshake| on |client_| and |server_| until each completes
5378 // once. If |expect_client_error| is true, it will return true only if the
5379 // client handshake failed. Otherwise, it returns true if both handshakes
5380 // succeed and false otherwise.
5381 bool RunQUICHandshakesAndExpectError(ExpectedError expected_error) {
David Benjamind6343572019-08-15 17:29:02 -04005382 bool client_done = false, server_done = false;
5383 while (!client_done || !server_done) {
5384 if (!client_done) {
5385 if (!ProvideHandshakeData(client_.get())) {
5386 ADD_FAILURE() << "ProvideHandshakeData(client_) failed";
5387 return false;
5388 }
5389 int client_ret = SSL_do_handshake(client_.get());
David Benjamin2fb729d2020-02-20 17:37:33 -05005390 int client_err = SSL_get_error(client_.get(), client_ret);
David Benjamind6343572019-08-15 17:29:02 -04005391 if (client_ret == 1) {
5392 client_done = true;
David Benjamin2fb729d2020-02-20 17:37:33 -05005393 } else if (client_ret != -1 || client_err != SSL_ERROR_WANT_READ) {
Nick Harper72cff812020-03-26 18:06:16 -07005394 if (expected_error == ExpectedError::kClientError) {
5395 return true;
5396 }
David Benjamin2fb729d2020-02-20 17:37:33 -05005397 ADD_FAILURE() << "Unexpected client output: " << client_ret << " "
5398 << client_err;
5399 return false;
David Benjamind6343572019-08-15 17:29:02 -04005400 }
5401 }
5402
5403 if (!server_done) {
5404 if (!ProvideHandshakeData(server_.get())) {
5405 ADD_FAILURE() << "ProvideHandshakeData(server_) failed";
5406 return false;
5407 }
5408 int server_ret = SSL_do_handshake(server_.get());
David Benjamin2fb729d2020-02-20 17:37:33 -05005409 int server_err = SSL_get_error(server_.get(), server_ret);
David Benjamind6343572019-08-15 17:29:02 -04005410 if (server_ret == 1) {
5411 server_done = true;
David Benjamin2fb729d2020-02-20 17:37:33 -05005412 } else if (server_ret != -1 || server_err != SSL_ERROR_WANT_READ) {
Nick Harper72cff812020-03-26 18:06:16 -07005413 if (expected_error == ExpectedError::kServerError) {
5414 return true;
5415 }
David Benjamin2fb729d2020-02-20 17:37:33 -05005416 ADD_FAILURE() << "Unexpected server output: " << server_ret << " "
5417 << server_err;
5418 return false;
David Benjamind6343572019-08-15 17:29:02 -04005419 }
5420 }
5421 }
Nick Harper72cff812020-03-26 18:06:16 -07005422 return expected_error == ExpectedError::kNoError;
David Benjamind6343572019-08-15 17:29:02 -04005423 }
5424
5425 bssl::UniquePtr<SSL_SESSION> CreateClientSessionForQUIC() {
5426 g_last_session = nullptr;
5427 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
5428 if (!CreateClientAndServer() ||
5429 !CompleteHandshakesForQUIC()) {
5430 return nullptr;
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005431 }
5432
David Benjamind6343572019-08-15 17:29:02 -04005433 // The server sent NewSessionTicket messages in the handshake.
5434 if (!ProvideHandshakeData(client_.get()) ||
5435 !SSL_process_quic_post_handshake(client_.get())) {
5436 return nullptr;
5437 }
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005438
David Benjamind6343572019-08-15 17:29:02 -04005439 return std::move(g_last_session);
5440 }
5441
5442 void ExpectHandshakeSuccess() {
5443 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_application));
5444 EXPECT_EQ(ssl_encryption_application, SSL_quic_read_level(client_.get()));
5445 EXPECT_EQ(ssl_encryption_application, SSL_quic_write_level(client_.get()));
5446 EXPECT_EQ(ssl_encryption_application, SSL_quic_read_level(server_.get()));
5447 EXPECT_EQ(ssl_encryption_application, SSL_quic_write_level(server_.get()));
5448 EXPECT_FALSE(transport_->client()->has_alert());
5449 EXPECT_FALSE(transport_->server()->has_alert());
5450
5451 // SSL_do_handshake is now idempotent.
5452 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
5453 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005454 }
5455
David Benjamin1e859052020-02-09 16:04:58 -05005456 // Returns a default SSL_QUIC_METHOD. Individual methods may be overwritten by
5457 // the test.
5458 SSL_QUIC_METHOD DefaultQUICMethod() {
5459 return SSL_QUIC_METHOD{
5460 SetReadSecretCallback, SetWriteSecretCallback, AddHandshakeDataCallback,
5461 FlushFlightCallback, SendAlertCallback,
5462 };
5463 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04005464
David Benjamin1e859052020-02-09 16:04:58 -05005465 static int SetReadSecretCallback(SSL *ssl, ssl_encryption_level_t level,
5466 const SSL_CIPHER *cipher,
5467 const uint8_t *secret, size_t secret_len) {
5468 return TransportFromSSL(ssl)->SetReadSecret(
5469 level, cipher, MakeConstSpan(secret, secret_len));
5470 }
5471
5472 static int SetWriteSecretCallback(SSL *ssl, ssl_encryption_level_t level,
5473 const SSL_CIPHER *cipher,
5474 const uint8_t *secret, size_t secret_len) {
5475 return TransportFromSSL(ssl)->SetWriteSecret(
5476 level, cipher, MakeConstSpan(secret, secret_len));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005477 }
5478
David Benjamincc9d9352018-10-30 19:45:22 -05005479 static int AddHandshakeDataCallback(SSL *ssl,
5480 enum ssl_encryption_level_t level,
5481 const uint8_t *data, size_t len) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005482 EXPECT_EQ(level, SSL_quic_write_level(ssl));
5483 return TransportFromSSL(ssl)->WriteHandshakeData(level,
5484 MakeConstSpan(data, len));
5485 }
5486
5487 static int FlushFlightCallback(SSL *ssl) { return 1; }
5488
5489 static int SendAlertCallback(SSL *ssl, ssl_encryption_level_t level,
5490 uint8_t alert) {
5491 EXPECT_EQ(level, SSL_quic_write_level(ssl));
5492 return TransportFromSSL(ssl)->SendAlert(level, alert);
5493 }
5494
5495 bssl::UniquePtr<SSL_CTX> client_ctx_;
5496 bssl::UniquePtr<SSL_CTX> server_ctx_;
5497
5498 static UnownedSSLExData<MockQUICTransport> ex_data_;
David Benjamind6343572019-08-15 17:29:02 -04005499 std::unique_ptr<MockQUICTransportPair> transport_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005500
5501 bssl::UniquePtr<SSL> client_;
5502 bssl::UniquePtr<SSL> server_;
David Benjamin5298ef92020-03-13 12:17:30 -04005503
Nick Harper7c522992020-04-30 14:15:49 -07005504 std::vector<uint8_t> server_transport_params_ = {1};
5505 std::vector<uint8_t> server_quic_early_data_context_ = {2};
5506
David Benjamin5298ef92020-03-13 12:17:30 -04005507 bool allow_out_of_order_writes_ = false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005508};
5509
5510UnownedSSLExData<MockQUICTransport> QUICMethodTest::ex_data_;
5511
David Benjaminfd863b62019-07-25 13:51:32 -04005512// Test a full handshake and resumption work.
Steven Valdezc8e0f902018-07-14 11:23:01 -04005513TEST_F(QUICMethodTest, Basic) {
David Benjamin1e859052020-02-09 16:04:58 -05005514 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005515
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005516 g_last_session = nullptr;
5517
5518 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5519 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005520 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5521 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
David Benjamind6343572019-08-15 17:29:02 -04005522
Steven Valdezc8e0f902018-07-14 11:23:01 -04005523 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04005524 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdezc8e0f902018-07-14 11:23:01 -04005525
David Benjamind6343572019-08-15 17:29:02 -04005526 ExpectHandshakeSuccess();
5527 EXPECT_FALSE(SSL_session_reused(client_.get()));
5528 EXPECT_FALSE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005529
5530 // The server sent NewSessionTicket messages in the handshake.
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005531 EXPECT_FALSE(g_last_session);
5532 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5533 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
5534 EXPECT_TRUE(g_last_session);
5535
5536 // Create a second connection to verify resumption works.
David Benjamind6343572019-08-15 17:29:02 -04005537 ASSERT_TRUE(CreateClientAndServer());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005538 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
5539 SSL_set_session(client_.get(), session.get());
5540
David Benjamind6343572019-08-15 17:29:02 -04005541 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005542
David Benjamind6343572019-08-15 17:29:02 -04005543 ExpectHandshakeSuccess();
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005544 EXPECT_TRUE(SSL_session_reused(client_.get()));
5545 EXPECT_TRUE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005546}
5547
David Benjaminfd863b62019-07-25 13:51:32 -04005548// Test that HelloRetryRequest in QUIC works.
5549TEST_F(QUICMethodTest, HelloRetryRequest) {
David Benjamin1e859052020-02-09 16:04:58 -05005550 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjaminfd863b62019-07-25 13:51:32 -04005551
5552 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5553 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5554
5555 // BoringSSL predicts the most preferred curve, so using different preferences
5556 // will trigger HelloRetryRequest.
5557 static const int kClientPrefs[] = {NID_X25519, NID_X9_62_prime256v1};
5558 ASSERT_TRUE(SSL_CTX_set1_curves(client_ctx_.get(), kClientPrefs,
5559 OPENSSL_ARRAY_SIZE(kClientPrefs)));
5560 static const int kServerPrefs[] = {NID_X9_62_prime256v1, NID_X25519};
5561 ASSERT_TRUE(SSL_CTX_set1_curves(server_ctx_.get(), kServerPrefs,
5562 OPENSSL_ARRAY_SIZE(kServerPrefs)));
5563
5564 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04005565 ASSERT_TRUE(CompleteHandshakesForQUIC());
5566 ExpectHandshakeSuccess();
5567}
David Benjaminfd863b62019-07-25 13:51:32 -04005568
Nick Harpere32549e2020-05-06 14:27:11 -07005569// Test that the client does not send a legacy_session_id in the ClientHello.
5570TEST_F(QUICMethodTest, NoLegacySessionId) {
5571 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
5572
5573 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5574 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5575 // Check that the session ID length is 0 in an early callback.
5576 SSL_CTX_set_select_certificate_cb(
5577 server_ctx_.get(),
5578 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
5579 EXPECT_EQ(client_hello->session_id_len, 0u);
5580 return ssl_select_cert_success;
5581 });
5582
5583 ASSERT_TRUE(CreateClientAndServer());
5584 ASSERT_TRUE(CompleteHandshakesForQUIC());
5585
5586 ExpectHandshakeSuccess();
5587}
5588
David Benjamin1e859052020-02-09 16:04:58 -05005589// Test that, even in a 1-RTT handshake, the server installs keys at the right
5590// time. Half-RTT keys are available early, but 1-RTT read keys are deferred.
5591TEST_F(QUICMethodTest, HalfRTTKeys) {
5592 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
5593
5594 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5595 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5596 ASSERT_TRUE(CreateClientAndServer());
5597
5598 // The client sends ClientHello.
5599 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5600 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client_.get(), -1));
5601
5602 // The server reads ClientHello and sends ServerHello..Finished.
5603 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5604 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
5605 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
5606
5607 // At this point, the server has half-RTT write keys, but it cannot access
5608 // 1-RTT read keys until client Finished.
5609 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
5610 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
5611
5612 // Finish up the client and server handshakes.
5613 ASSERT_TRUE(CompleteHandshakesForQUIC());
5614
5615 // Both sides can now exchange 1-RTT data.
5616 ExpectHandshakeSuccess();
5617}
5618
David Benjamind6343572019-08-15 17:29:02 -04005619TEST_F(QUICMethodTest, ZeroRTTAccept) {
David Benjamin1e859052020-02-09 16:04:58 -05005620 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjamind6343572019-08-15 17:29:02 -04005621
5622 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5623 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
5624 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
5625 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5626 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5627
5628 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
5629 ASSERT_TRUE(session);
5630
5631 ASSERT_TRUE(CreateClientAndServer());
5632 SSL_set_session(client_.get(), session.get());
5633
5634 // The client handshake should return immediately into the early data state.
5635 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
5636 EXPECT_TRUE(SSL_in_early_data(client_.get()));
5637 // The transport should have keys for sending 0-RTT data.
David Benjamin1e859052020-02-09 16:04:58 -05005638 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04005639
5640 // The server will consume the ClientHello and also enter the early data
5641 // state.
5642 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5643 ASSERT_EQ(SSL_do_handshake(server_.get()), 1);
5644 EXPECT_TRUE(SSL_in_early_data(server_.get()));
5645 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_early_data));
David Benjamin1e859052020-02-09 16:04:58 -05005646 // At this point, the server has half-RTT write keys, but it cannot access
5647 // 1-RTT read keys until client Finished.
5648 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
5649 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
David Benjamind6343572019-08-15 17:29:02 -04005650
5651 // Finish up the client and server handshakes.
5652 ASSERT_TRUE(CompleteHandshakesForQUIC());
5653
5654 // Both sides can now exchange 1-RTT data.
5655 ExpectHandshakeSuccess();
5656 EXPECT_TRUE(SSL_session_reused(client_.get()));
5657 EXPECT_TRUE(SSL_session_reused(server_.get()));
5658 EXPECT_FALSE(SSL_in_early_data(client_.get()));
5659 EXPECT_FALSE(SSL_in_early_data(server_.get()));
5660 EXPECT_TRUE(SSL_early_data_accepted(client_.get()));
5661 EXPECT_TRUE(SSL_early_data_accepted(server_.get()));
Nick Harper5e086952020-09-30 13:59:14 -07005662
5663 // Finish handling post-handshake messages after the first 0-RTT resumption.
5664 EXPECT_TRUE(ProvideHandshakeData(client_.get()));
5665 EXPECT_TRUE(SSL_process_quic_post_handshake(client_.get()));
5666
5667 // Perform a second 0-RTT resumption attempt, and confirm that 0-RTT is
5668 // accepted again.
5669 ASSERT_TRUE(CreateClientAndServer());
5670 SSL_set_session(client_.get(), g_last_session.get());
5671
5672 // The client handshake should return immediately into the early data state.
5673 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
5674 EXPECT_TRUE(SSL_in_early_data(client_.get()));
5675 // The transport should have keys for sending 0-RTT data.
5676 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
5677
5678 // The server will consume the ClientHello and also enter the early data
5679 // state.
5680 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5681 ASSERT_EQ(SSL_do_handshake(server_.get()), 1);
5682 EXPECT_TRUE(SSL_in_early_data(server_.get()));
5683 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_early_data));
5684 // At this point, the server has half-RTT write keys, but it cannot access
5685 // 1-RTT read keys until client Finished.
5686 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
5687 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
5688
5689 // Finish up the client and server handshakes.
5690 ASSERT_TRUE(CompleteHandshakesForQUIC());
5691
5692 // Both sides can now exchange 1-RTT data.
5693 ExpectHandshakeSuccess();
5694 EXPECT_TRUE(SSL_session_reused(client_.get()));
5695 EXPECT_TRUE(SSL_session_reused(server_.get()));
5696 EXPECT_FALSE(SSL_in_early_data(client_.get()));
5697 EXPECT_FALSE(SSL_in_early_data(server_.get()));
5698 EXPECT_TRUE(SSL_early_data_accepted(client_.get()));
5699 EXPECT_TRUE(SSL_early_data_accepted(server_.get()));
5700 EXPECT_EQ(SSL_get_early_data_reason(client_.get()), ssl_early_data_accepted);
5701 EXPECT_EQ(SSL_get_early_data_reason(server_.get()), ssl_early_data_accepted);
David Benjamind6343572019-08-15 17:29:02 -04005702}
5703
Nick Harper7c522992020-04-30 14:15:49 -07005704TEST_F(QUICMethodTest, ZeroRTTRejectMismatchedParameters) {
5705 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
5706
5707 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5708 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
5709 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
5710 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5711 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5712
5713
5714 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
5715 ASSERT_TRUE(session);
5716
Nick Harper85194322020-05-20 16:59:29 -07005717 ASSERT_TRUE(CreateClientAndServer());
5718 static const uint8_t new_context[] = {4};
5719 ASSERT_TRUE(SSL_set_quic_early_data_context(server_.get(), new_context,
5720 sizeof(new_context)));
5721 SSL_set_session(client_.get(), session.get());
Nick Harper7c522992020-04-30 14:15:49 -07005722
Nick Harper85194322020-05-20 16:59:29 -07005723 // The client handshake should return immediately into the early data
5724 // state.
5725 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
5726 EXPECT_TRUE(SSL_in_early_data(client_.get()));
5727 // The transport should have keys for sending 0-RTT data.
5728 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
Nick Harper7c522992020-04-30 14:15:49 -07005729
Nick Harper85194322020-05-20 16:59:29 -07005730 // The server will consume the ClientHello, but it will not accept 0-RTT.
5731 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5732 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
5733 EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
5734 EXPECT_FALSE(SSL_in_early_data(server_.get()));
5735 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_early_data));
Nick Harper7c522992020-04-30 14:15:49 -07005736
Nick Harper85194322020-05-20 16:59:29 -07005737 // The client consumes the server response and signals 0-RTT rejection.
5738 for (;;) {
5739 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5740 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
5741 int err = SSL_get_error(client_.get(), -1);
5742 if (err == SSL_ERROR_EARLY_DATA_REJECTED) {
5743 break;
Nick Harper7c522992020-04-30 14:15:49 -07005744 }
Nick Harper85194322020-05-20 16:59:29 -07005745 ASSERT_EQ(SSL_ERROR_WANT_READ, err);
Nick Harper7c522992020-04-30 14:15:49 -07005746 }
Nick Harper85194322020-05-20 16:59:29 -07005747
5748 // As in TLS over TCP, 0-RTT rejection is sticky.
5749 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
5750 ASSERT_EQ(SSL_ERROR_EARLY_DATA_REJECTED, SSL_get_error(client_.get(), -1));
5751
5752 // Finish up the client and server handshakes.
5753 SSL_reset_early_data_reject(client_.get());
5754 ASSERT_TRUE(CompleteHandshakesForQUIC());
5755
5756 // Both sides can now exchange 1-RTT data.
5757 ExpectHandshakeSuccess();
5758 EXPECT_TRUE(SSL_session_reused(client_.get()));
5759 EXPECT_TRUE(SSL_session_reused(server_.get()));
5760 EXPECT_FALSE(SSL_in_early_data(client_.get()));
5761 EXPECT_FALSE(SSL_in_early_data(server_.get()));
5762 EXPECT_FALSE(SSL_early_data_accepted(client_.get()));
5763 EXPECT_FALSE(SSL_early_data_accepted(server_.get()));
5764}
5765
5766TEST_F(QUICMethodTest, NoZeroRTTTicketWithoutEarlyDataContext) {
5767 server_quic_early_data_context_ = {};
5768 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
5769
5770 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5771 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
5772 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
5773 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5774 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5775
5776 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
5777 ASSERT_TRUE(session);
5778 EXPECT_FALSE(SSL_SESSION_early_data_capable(session.get()));
Nick Harper7c522992020-04-30 14:15:49 -07005779}
5780
David Benjamind6343572019-08-15 17:29:02 -04005781TEST_F(QUICMethodTest, ZeroRTTReject) {
David Benjamin1e859052020-02-09 16:04:58 -05005782 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjamind6343572019-08-15 17:29:02 -04005783
5784 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5785 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
5786 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
5787 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5788 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5789
5790 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
5791 ASSERT_TRUE(session);
5792
5793 for (bool reject_hrr : {false, true}) {
5794 SCOPED_TRACE(reject_hrr);
5795
5796 ASSERT_TRUE(CreateClientAndServer());
5797 if (reject_hrr) {
5798 // Configure the server to prefer P-256, which will reject 0-RTT via
5799 // HelloRetryRequest.
5800 int p256 = NID_X9_62_prime256v1;
5801 ASSERT_TRUE(SSL_set1_curves(server_.get(), &p256, 1));
5802 } else {
5803 // Disable 0-RTT on the server, so it will reject it.
5804 SSL_set_early_data_enabled(server_.get(), 0);
David Benjaminfd863b62019-07-25 13:51:32 -04005805 }
David Benjamind6343572019-08-15 17:29:02 -04005806 SSL_set_session(client_.get(), session.get());
David Benjaminfd863b62019-07-25 13:51:32 -04005807
David Benjamind6343572019-08-15 17:29:02 -04005808 // The client handshake should return immediately into the early data state.
5809 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
5810 EXPECT_TRUE(SSL_in_early_data(client_.get()));
5811 // The transport should have keys for sending 0-RTT data.
David Benjamin1e859052020-02-09 16:04:58 -05005812 EXPECT_TRUE(
5813 transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04005814
5815 // The server will consume the ClientHello, but it will not accept 0-RTT.
David Benjaminfd863b62019-07-25 13:51:32 -04005816 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
David Benjamind6343572019-08-15 17:29:02 -04005817 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
5818 EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
5819 EXPECT_FALSE(SSL_in_early_data(server_.get()));
David Benjamin1e859052020-02-09 16:04:58 -05005820 EXPECT_FALSE(
5821 transport_->server()->HasReadSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04005822
5823 // The client consumes the server response and signals 0-RTT rejection.
5824 for (;;) {
5825 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5826 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
5827 int err = SSL_get_error(client_.get(), -1);
5828 if (err == SSL_ERROR_EARLY_DATA_REJECTED) {
5829 break;
5830 }
5831 ASSERT_EQ(SSL_ERROR_WANT_READ, err);
David Benjaminfd863b62019-07-25 13:51:32 -04005832 }
5833
David Benjamind6343572019-08-15 17:29:02 -04005834 // As in TLS over TCP, 0-RTT rejection is sticky.
5835 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
5836 ASSERT_EQ(SSL_ERROR_EARLY_DATA_REJECTED, SSL_get_error(client_.get(), -1));
5837
5838 // Finish up the client and server handshakes.
5839 SSL_reset_early_data_reject(client_.get());
5840 ASSERT_TRUE(CompleteHandshakesForQUIC());
5841
5842 // Both sides can now exchange 1-RTT data.
5843 ExpectHandshakeSuccess();
5844 EXPECT_TRUE(SSL_session_reused(client_.get()));
5845 EXPECT_TRUE(SSL_session_reused(server_.get()));
5846 EXPECT_FALSE(SSL_in_early_data(client_.get()));
5847 EXPECT_FALSE(SSL_in_early_data(server_.get()));
5848 EXPECT_FALSE(SSL_early_data_accepted(client_.get()));
5849 EXPECT_FALSE(SSL_early_data_accepted(server_.get()));
David Benjaminfd863b62019-07-25 13:51:32 -04005850 }
David Benjaminfd863b62019-07-25 13:51:32 -04005851}
5852
David Benjaminee0716f2019-11-19 14:16:28 +08005853TEST_F(QUICMethodTest, NoZeroRTTKeysBeforeReverify) {
David Benjamin1e859052020-02-09 16:04:58 -05005854 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjaminee0716f2019-11-19 14:16:28 +08005855
5856 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5857 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
5858 SSL_CTX_set_reverify_on_resume(client_ctx_.get(), 1);
5859 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
5860 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5861 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5862
5863 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
5864 ASSERT_TRUE(session);
5865
5866 ASSERT_TRUE(CreateClientAndServer());
5867 SSL_set_session(client_.get(), session.get());
5868
5869 // Configure the certificate (re)verification to never complete. The client
5870 // handshake should pause.
5871 SSL_set_custom_verify(
5872 client_.get(), SSL_VERIFY_PEER,
5873 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
5874 return ssl_verify_retry;
5875 });
5876 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5877 ASSERT_EQ(SSL_get_error(client_.get(), -1),
5878 SSL_ERROR_WANT_CERTIFICATE_VERIFY);
5879
5880 // The early data keys have not yet been released.
David Benjamin1e859052020-02-09 16:04:58 -05005881 EXPECT_FALSE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjaminee0716f2019-11-19 14:16:28 +08005882
5883 // After the verification completes, the handshake progresses to the 0-RTT
5884 // point and releases keys.
5885 SSL_set_custom_verify(
5886 client_.get(), SSL_VERIFY_PEER,
5887 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
5888 return ssl_verify_ok;
5889 });
5890 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
5891 EXPECT_TRUE(SSL_in_early_data(client_.get()));
David Benjamin1e859052020-02-09 16:04:58 -05005892 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjaminee0716f2019-11-19 14:16:28 +08005893}
5894
Steven Valdezc8e0f902018-07-14 11:23:01 -04005895// Test only releasing data to QUIC one byte at a time on request, to maximize
5896// state machine pauses. Additionally, test that existing asynchronous callbacks
5897// still work.
5898TEST_F(QUICMethodTest, Async) {
David Benjamin1e859052020-02-09 16:04:58 -05005899 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005900
5901 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5902 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5903 ASSERT_TRUE(CreateClientAndServer());
5904
5905 // Install an asynchronous certificate callback.
5906 bool cert_cb_ok = false;
5907 SSL_set_cert_cb(server_.get(),
5908 [](SSL *, void *arg) -> int {
5909 return *static_cast<bool *>(arg) ? 1 : -1;
5910 },
5911 &cert_cb_ok);
5912
5913 for (;;) {
5914 int client_ret = SSL_do_handshake(client_.get());
5915 if (client_ret != 1) {
5916 ASSERT_EQ(client_ret, -1);
5917 ASSERT_EQ(SSL_get_error(client_.get(), client_ret), SSL_ERROR_WANT_READ);
5918 ASSERT_TRUE(ProvideHandshakeData(client_.get(), 1));
5919 }
5920
5921 int server_ret = SSL_do_handshake(server_.get());
5922 if (server_ret != 1) {
5923 ASSERT_EQ(server_ret, -1);
5924 int ssl_err = SSL_get_error(server_.get(), server_ret);
5925 switch (ssl_err) {
5926 case SSL_ERROR_WANT_READ:
5927 ASSERT_TRUE(ProvideHandshakeData(server_.get(), 1));
5928 break;
5929 case SSL_ERROR_WANT_X509_LOOKUP:
5930 ASSERT_FALSE(cert_cb_ok);
5931 cert_cb_ok = true;
5932 break;
5933 default:
5934 FAIL() << "Unexpected SSL_get_error result: " << ssl_err;
5935 }
5936 }
5937
5938 if (client_ret == 1 && server_ret == 1) {
5939 break;
5940 }
5941 }
5942
David Benjamind6343572019-08-15 17:29:02 -04005943 ExpectHandshakeSuccess();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005944}
5945
5946// Test buffering write data until explicit flushes.
5947TEST_F(QUICMethodTest, Buffered) {
David Benjamin5298ef92020-03-13 12:17:30 -04005948 AllowOutOfOrderWrites();
5949
Steven Valdezc8e0f902018-07-14 11:23:01 -04005950 struct BufferedFlight {
5951 std::vector<uint8_t> data[kNumQUICLevels];
5952 };
5953 static UnownedSSLExData<BufferedFlight> buffered_flights;
5954
David Benjamincc9d9352018-10-30 19:45:22 -05005955 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
5956 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005957 BufferedFlight *flight = buffered_flights.Get(ssl);
5958 flight->data[level].insert(flight->data[level].end(), data, data + len);
5959 return 1;
5960 };
5961
5962 auto flush_flight = [](SSL *ssl) -> int {
5963 BufferedFlight *flight = buffered_flights.Get(ssl);
5964 for (size_t level = 0; level < kNumQUICLevels; level++) {
5965 if (!flight->data[level].empty()) {
5966 if (!TransportFromSSL(ssl)->WriteHandshakeData(
5967 static_cast<ssl_encryption_level_t>(level),
5968 flight->data[level])) {
5969 return 0;
5970 }
5971 flight->data[level].clear();
5972 }
5973 }
5974 return 1;
5975 };
5976
David Benjamin1e859052020-02-09 16:04:58 -05005977 SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
5978 quic_method.add_handshake_data = add_handshake_data;
5979 quic_method.flush_flight = flush_flight;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005980
5981 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5982 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5983 ASSERT_TRUE(CreateClientAndServer());
5984
5985 BufferedFlight client_flight, server_flight;
5986 buffered_flights.Set(client_.get(), &client_flight);
5987 buffered_flights.Set(server_.get(), &server_flight);
5988
David Benjamind6343572019-08-15 17:29:02 -04005989 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdezc8e0f902018-07-14 11:23:01 -04005990
David Benjamind6343572019-08-15 17:29:02 -04005991 ExpectHandshakeSuccess();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005992}
5993
5994// Test that excess data at one level is rejected. That is, if a single
5995// |SSL_provide_quic_data| call included both ServerHello and
5996// EncryptedExtensions in a single chunk, BoringSSL notices and rejects this on
5997// key change.
5998TEST_F(QUICMethodTest, ExcessProvidedData) {
David Benjamin5298ef92020-03-13 12:17:30 -04005999 AllowOutOfOrderWrites();
6000
David Benjamincc9d9352018-10-30 19:45:22 -05006001 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
6002 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04006003 // Switch everything to the initial level.
6004 return TransportFromSSL(ssl)->WriteHandshakeData(ssl_encryption_initial,
6005 MakeConstSpan(data, len));
6006 };
6007
David Benjamin1e859052020-02-09 16:04:58 -05006008 SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6009 quic_method.add_handshake_data = add_handshake_data;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006010
6011 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6012 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6013 ASSERT_TRUE(CreateClientAndServer());
6014
6015 // Send the ClientHello and ServerHello through Finished.
6016 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6017 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
6018 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6019 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6020 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
6021
6022 // The client is still waiting for the ServerHello at initial
6023 // encryption.
6024 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
6025
David Benjamincc9d9352018-10-30 19:45:22 -05006026 // |add_handshake_data| incorrectly wrote everything at the initial level, so
6027 // this queues up ServerHello through Finished in one chunk.
Steven Valdezc8e0f902018-07-14 11:23:01 -04006028 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6029
6030 // The client reads ServerHello successfully, but then rejects the buffered
6031 // EncryptedExtensions on key change.
6032 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6033 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_SSL);
6034 uint32_t err = ERR_get_error();
6035 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
David Benjaminf9cc26f2020-02-09 16:49:31 -05006036 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_EXCESS_HANDSHAKE_DATA);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006037
David Benjamin1e859052020-02-09 16:04:58 -05006038 // The client sends an alert in response to this. The alert is sent at
6039 // handshake level because we install write secrets before read secrets and
6040 // the error is discovered when installing the read secret. (How to send
6041 // alerts on protocol syntax errors near key changes is ambiguous in general.)
David Benjamind6343572019-08-15 17:29:02 -04006042 ASSERT_TRUE(transport_->client()->has_alert());
David Benjamin1e859052020-02-09 16:04:58 -05006043 EXPECT_EQ(transport_->client()->alert_level(), ssl_encryption_handshake);
David Benjamind6343572019-08-15 17:29:02 -04006044 EXPECT_EQ(transport_->client()->alert(), SSL_AD_UNEXPECTED_MESSAGE);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006045
David Benjamin5298ef92020-03-13 12:17:30 -04006046 // Sanity-check handshake secrets. The error is discovered while setting the
6047 // read secret, so only the write secret has been installed.
David Benjamin1e859052020-02-09 16:04:58 -05006048 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_handshake));
David Benjamin5298ef92020-03-13 12:17:30 -04006049 EXPECT_FALSE(transport_->client()->HasReadSecret(ssl_encryption_handshake));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006050}
6051
6052// Test that |SSL_provide_quic_data| will reject data at the wrong level.
6053TEST_F(QUICMethodTest, ProvideWrongLevel) {
David Benjamin1e859052020-02-09 16:04:58 -05006054 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006055
6056 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6057 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6058 ASSERT_TRUE(CreateClientAndServer());
6059
6060 // Send the ClientHello and ServerHello through Finished.
6061 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6062 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
6063 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6064 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6065 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
6066
6067 // The client is still waiting for the ServerHello at initial
6068 // encryption.
6069 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
6070
6071 // Data cannot be provided at the next level.
6072 std::vector<uint8_t> data;
6073 ASSERT_TRUE(
David Benjamind6343572019-08-15 17:29:02 -04006074 transport_->client()->ReadHandshakeData(&data, ssl_encryption_initial));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006075 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_handshake,
6076 data.data(), data.size()));
6077 ERR_clear_error();
6078
6079 // Progress to EncryptedExtensions.
6080 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
6081 data.data(), data.size()));
6082 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6083 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
6084 ASSERT_EQ(ssl_encryption_handshake, SSL_quic_read_level(client_.get()));
6085
6086 // Data cannot be provided at the previous level.
6087 ASSERT_TRUE(
David Benjamind6343572019-08-15 17:29:02 -04006088 transport_->client()->ReadHandshakeData(&data, ssl_encryption_handshake));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006089 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
6090 data.data(), data.size()));
6091}
6092
6093TEST_F(QUICMethodTest, TooMuchData) {
David Benjamin1e859052020-02-09 16:04:58 -05006094 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006095
6096 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6097 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6098 ASSERT_TRUE(CreateClientAndServer());
6099
6100 size_t limit =
6101 SSL_quic_max_handshake_flight_len(client_.get(), ssl_encryption_initial);
6102 uint8_t b = 0;
6103 for (size_t i = 0; i < limit; i++) {
6104 ASSERT_TRUE(
6105 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
6106 }
6107
6108 EXPECT_FALSE(
6109 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
6110}
6111
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006112// Provide invalid post-handshake data.
6113TEST_F(QUICMethodTest, BadPostHandshake) {
David Benjamin1e859052020-02-09 16:04:58 -05006114 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006115
6116 g_last_session = nullptr;
6117
6118 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6119 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6120 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6121 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6122 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04006123 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006124
6125 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
6126 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
David Benjamind6343572019-08-15 17:29:02 -04006127 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_application));
6128 EXPECT_FALSE(transport_->client()->has_alert());
6129 EXPECT_FALSE(transport_->server()->has_alert());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006130
6131 // Junk sent as part of post-handshake data should cause an error.
6132 uint8_t kJunk[] = {0x17, 0x0, 0x0, 0x4, 0xB, 0xE, 0xE, 0xF};
6133 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_application,
6134 kJunk, sizeof(kJunk)));
6135 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 0);
6136}
6137
Nick Harper80ddfc72020-03-11 18:26:31 -07006138static void ExpectReceivedTransportParamsEqual(const SSL *ssl,
6139 Span<const uint8_t> expected) {
6140 const uint8_t *received;
6141 size_t received_len;
6142 SSL_get_peer_quic_transport_params(ssl, &received, &received_len);
6143 ASSERT_EQ(received_len, expected.size());
6144 EXPECT_EQ(Bytes(received, received_len), Bytes(expected));
6145}
6146
6147TEST_F(QUICMethodTest, SetTransportParameters) {
6148 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6149 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6150 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6151
6152 ASSERT_TRUE(CreateClientAndServer());
6153 uint8_t kClientParams[] = {1, 2, 3, 4};
6154 uint8_t kServerParams[] = {5, 6, 7};
6155 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6156 sizeof(kClientParams)));
6157 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6158 sizeof(kServerParams)));
6159
6160 ASSERT_TRUE(CompleteHandshakesForQUIC());
6161 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6162 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6163}
6164
6165TEST_F(QUICMethodTest, SetTransportParamsInCallback) {
6166 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6167 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6168 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6169
6170 ASSERT_TRUE(CreateClientAndServer());
6171 uint8_t kClientParams[] = {1, 2, 3, 4};
6172 static uint8_t kServerParams[] = {5, 6, 7};
6173 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6174 sizeof(kClientParams)));
6175 SSL_CTX_set_tlsext_servername_callback(
6176 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
6177 EXPECT_TRUE(SSL_set_quic_transport_params(ssl, kServerParams,
6178 sizeof(kServerParams)));
6179 return SSL_TLSEXT_ERR_OK;
6180 });
6181
6182 ASSERT_TRUE(CompleteHandshakesForQUIC());
6183 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6184 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6185}
6186
Nick Harper6bfd25c2020-03-30 17:15:19 -07006187TEST_F(QUICMethodTest, ForbidCrossProtocolResumptionClient) {
6188 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6189
6190 g_last_session = nullptr;
6191
6192 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6193 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6194 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6195 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6196
6197 ASSERT_TRUE(CreateClientAndServer());
6198 ASSERT_TRUE(CompleteHandshakesForQUIC());
6199
6200 ExpectHandshakeSuccess();
6201 EXPECT_FALSE(SSL_session_reused(client_.get()));
6202 EXPECT_FALSE(SSL_session_reused(server_.get()));
6203
6204 // The server sent NewSessionTicket messages in the handshake.
6205 EXPECT_FALSE(g_last_session);
6206 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6207 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
6208 EXPECT_TRUE(g_last_session);
6209
6210 // Pretend that g_last_session came from a TLS-over-TCP connection.
6211 g_last_session.get()->is_quic = false;
6212
6213 // Create a second connection and verify that resumption does not occur with
6214 // a session from a non-QUIC connection. This tests that the client does not
6215 // offer over QUIC a session believed to be received over TCP. The server
6216 // believes this is a QUIC session, so if the client offered the session, the
6217 // server would have resumed it.
6218 ASSERT_TRUE(CreateClientAndServer());
6219 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
6220 SSL_set_session(client_.get(), session.get());
6221
6222 ASSERT_TRUE(CompleteHandshakesForQUIC());
6223 ExpectHandshakeSuccess();
6224 EXPECT_FALSE(SSL_session_reused(client_.get()));
6225 EXPECT_FALSE(SSL_session_reused(server_.get()));
6226}
6227
6228TEST_F(QUICMethodTest, ForbidCrossProtocolResumptionServer) {
6229 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6230
6231 g_last_session = nullptr;
6232
6233 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6234 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6235 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6236 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6237
6238 ASSERT_TRUE(CreateClientAndServer());
6239 ASSERT_TRUE(CompleteHandshakesForQUIC());
6240
6241 ExpectHandshakeSuccess();
6242 EXPECT_FALSE(SSL_session_reused(client_.get()));
6243 EXPECT_FALSE(SSL_session_reused(server_.get()));
6244
6245 // The server sent NewSessionTicket messages in the handshake.
6246 EXPECT_FALSE(g_last_session);
6247 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6248 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
6249 EXPECT_TRUE(g_last_session);
6250
6251 // Attempt a resumption with g_last_session using TLS_method.
6252 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
6253 ASSERT_TRUE(client_ctx);
6254
6255 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), nullptr));
6256
6257 bssl::UniquePtr<SSL> client(SSL_new(client_ctx.get())),
6258 server(SSL_new(server_ctx_.get()));
6259 ASSERT_TRUE(client);
6260 ASSERT_TRUE(server);
6261 SSL_set_connect_state(client.get());
6262 SSL_set_accept_state(server.get());
6263
6264 // The TLS-over-TCP client will refuse to resume with a quic session, so
6265 // mark is_quic = false to bypass the client check to test the server check.
6266 g_last_session.get()->is_quic = false;
6267 SSL_set_session(client.get(), g_last_session.get());
6268
6269 BIO *bio1, *bio2;
6270 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
6271
6272 // SSL_set_bio takes ownership.
6273 SSL_set_bio(client.get(), bio1, bio1);
6274 SSL_set_bio(server.get(), bio2, bio2);
6275 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
6276
6277 EXPECT_FALSE(SSL_session_reused(client.get()));
6278 EXPECT_FALSE(SSL_session_reused(server.get()));
6279}
6280
Nick Harper72cff812020-03-26 18:06:16 -07006281TEST_F(QUICMethodTest, ClientRejectsMissingTransportParams) {
6282 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6283 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6284 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6285
6286 ASSERT_TRUE(CreateClientAndServer());
6287 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), nullptr, 0));
6288 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
6289}
6290
6291TEST_F(QUICMethodTest, ServerRejectsMissingTransportParams) {
6292 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6293 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6294 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6295
6296 ASSERT_TRUE(CreateClientAndServer());
6297 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), nullptr, 0));
6298 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kClientError));
6299}
6300
David Schinazi3d8b8c32021-01-14 11:25:49 -08006301TEST_F(QUICMethodTest, QuicLegacyCodepointEnabled) {
6302 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6303 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6304 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6305
6306 ASSERT_TRUE(CreateClientAndServer());
6307 uint8_t kClientParams[] = {1, 2, 3, 4};
6308 uint8_t kServerParams[] = {5, 6, 7};
6309 SSL_set_quic_use_legacy_codepoint(client_.get(), 1);
6310 SSL_set_quic_use_legacy_codepoint(server_.get(), 1);
6311 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6312 sizeof(kClientParams)));
6313 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6314 sizeof(kServerParams)));
6315
6316 ASSERT_TRUE(CompleteHandshakesForQUIC());
6317 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6318 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6319}
6320
6321TEST_F(QUICMethodTest, QuicLegacyCodepointDisabled) {
6322 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6323 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6324 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6325
6326 ASSERT_TRUE(CreateClientAndServer());
6327 uint8_t kClientParams[] = {1, 2, 3, 4};
6328 uint8_t kServerParams[] = {5, 6, 7};
6329 SSL_set_quic_use_legacy_codepoint(client_.get(), 0);
6330 SSL_set_quic_use_legacy_codepoint(server_.get(), 0);
6331 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6332 sizeof(kClientParams)));
6333 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6334 sizeof(kServerParams)));
6335
6336 ASSERT_TRUE(CompleteHandshakesForQUIC());
6337 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6338 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6339}
6340
6341TEST_F(QUICMethodTest, QuicLegacyCodepointClientOnly) {
6342 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6343 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6344 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6345
6346 ASSERT_TRUE(CreateClientAndServer());
6347 uint8_t kClientParams[] = {1, 2, 3, 4};
6348 uint8_t kServerParams[] = {5, 6, 7};
6349 SSL_set_quic_use_legacy_codepoint(client_.get(), 1);
6350 SSL_set_quic_use_legacy_codepoint(server_.get(), 0);
6351 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6352 sizeof(kClientParams)));
6353 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6354 sizeof(kServerParams)));
6355
6356 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
6357}
6358
6359TEST_F(QUICMethodTest, QuicLegacyCodepointServerOnly) {
6360 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6361 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6362 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6363
6364 ASSERT_TRUE(CreateClientAndServer());
6365 uint8_t kClientParams[] = {1, 2, 3, 4};
6366 uint8_t kServerParams[] = {5, 6, 7};
6367 SSL_set_quic_use_legacy_codepoint(client_.get(), 0);
6368 SSL_set_quic_use_legacy_codepoint(server_.get(), 1);
6369 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6370 sizeof(kClientParams)));
6371 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6372 sizeof(kServerParams)));
6373
6374 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
6375}
6376
David Benjaminc47bfce2021-01-20 17:10:32 -05006377// Test that the default QUIC code point is consistent with
6378// |TLSEXT_TYPE_quic_transport_parameters|. This test ensures we remember to
6379// update the two values together.
6380TEST_F(QUICMethodTest, QuicCodePointDefault) {
6381 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6382 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6383 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6384 SSL_CTX_set_select_certificate_cb(
6385 server_ctx_.get(),
6386 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
6387 const uint8_t *data;
6388 size_t len;
6389 if (!SSL_early_callback_ctx_extension_get(
6390 client_hello, TLSEXT_TYPE_quic_transport_parameters, &data,
6391 &len)) {
6392 ADD_FAILURE() << "Could not find quic_transport_parameters extension";
6393 return ssl_select_cert_error;
6394 }
6395 return ssl_select_cert_success;
6396 });
6397
6398 ASSERT_TRUE(CreateClientAndServer());
6399 ASSERT_TRUE(CompleteHandshakesForQUIC());
6400}
6401
Adam Langley7540cc22019-04-18 09:56:13 -07006402extern "C" {
6403int BORINGSSL_enum_c_type_test(void);
6404}
6405
6406TEST(SSLTest, EnumTypes) {
6407 EXPECT_EQ(sizeof(int), sizeof(ssl_private_key_result_t));
6408 EXPECT_EQ(1, BORINGSSL_enum_c_type_test());
6409}
6410
David Benjaminb29e1e12019-05-06 14:44:46 -05006411TEST_P(SSLVersionTest, DoubleSSLError) {
6412 // Connect the inner SSL connections.
6413 ASSERT_TRUE(Connect());
6414
6415 // Make a pair of |BIO|s which wrap |client_| and |server_|.
6416 UniquePtr<BIO_METHOD> bio_method(BIO_meth_new(0, nullptr));
6417 ASSERT_TRUE(bio_method);
6418 ASSERT_TRUE(BIO_meth_set_read(
6419 bio_method.get(), [](BIO *bio, char *out, int len) -> int {
6420 SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
6421 int ret = SSL_read(ssl, out, len);
6422 int ssl_ret = SSL_get_error(ssl, ret);
6423 if (ssl_ret == SSL_ERROR_WANT_READ) {
6424 BIO_set_retry_read(bio);
6425 }
6426 return ret;
6427 }));
6428 ASSERT_TRUE(BIO_meth_set_write(
6429 bio_method.get(), [](BIO *bio, const char *in, int len) -> int {
6430 SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
6431 int ret = SSL_write(ssl, in, len);
6432 int ssl_ret = SSL_get_error(ssl, ret);
6433 if (ssl_ret == SSL_ERROR_WANT_WRITE) {
6434 BIO_set_retry_write(bio);
6435 }
6436 return ret;
6437 }));
6438 ASSERT_TRUE(BIO_meth_set_ctrl(
6439 bio_method.get(), [](BIO *bio, int cmd, long larg, void *parg) -> long {
6440 // |SSL| objects require |BIO_flush| support.
6441 if (cmd == BIO_CTRL_FLUSH) {
6442 return 1;
6443 }
6444 return 0;
6445 }));
6446
6447 UniquePtr<BIO> client_bio(BIO_new(bio_method.get()));
6448 ASSERT_TRUE(client_bio);
6449 BIO_set_data(client_bio.get(), client_.get());
6450 BIO_set_init(client_bio.get(), 1);
6451
6452 UniquePtr<BIO> server_bio(BIO_new(bio_method.get()));
6453 ASSERT_TRUE(server_bio);
6454 BIO_set_data(server_bio.get(), server_.get());
6455 BIO_set_init(server_bio.get(), 1);
6456
6457 // Wrap the inner connections in another layer of SSL.
6458 UniquePtr<SSL> client_outer(SSL_new(client_ctx_.get()));
6459 ASSERT_TRUE(client_outer);
6460 SSL_set_connect_state(client_outer.get());
6461 SSL_set_bio(client_outer.get(), client_bio.get(), client_bio.get());
6462 client_bio.release(); // |SSL_set_bio| takes ownership.
6463
6464 UniquePtr<SSL> server_outer(SSL_new(server_ctx_.get()));
6465 ASSERT_TRUE(server_outer);
6466 SSL_set_accept_state(server_outer.get());
6467 SSL_set_bio(server_outer.get(), server_bio.get(), server_bio.get());
6468 server_bio.release(); // |SSL_set_bio| takes ownership.
6469
6470 // Configure |client_outer| to reject the server certificate.
6471 SSL_set_custom_verify(
6472 client_outer.get(), SSL_VERIFY_PEER,
6473 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
6474 return ssl_verify_invalid;
6475 });
6476
6477 for (;;) {
6478 int client_ret = SSL_do_handshake(client_outer.get());
6479 int client_err = SSL_get_error(client_outer.get(), client_ret);
6480 if (client_err != SSL_ERROR_WANT_READ &&
6481 client_err != SSL_ERROR_WANT_WRITE) {
6482 // The client handshake should terminate on a certificate verification
6483 // error.
6484 EXPECT_EQ(SSL_ERROR_SSL, client_err);
6485 uint32_t err = ERR_peek_error();
6486 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
6487 EXPECT_EQ(SSL_R_CERTIFICATE_VERIFY_FAILED, ERR_GET_REASON(err));
6488 break;
6489 }
6490
6491 // Run the server handshake and continue.
6492 int server_ret = SSL_do_handshake(server_outer.get());
6493 int server_err = SSL_get_error(server_outer.get(), server_ret);
6494 ASSERT_TRUE(server_err == SSL_ERROR_NONE ||
6495 server_err == SSL_ERROR_WANT_READ ||
6496 server_err == SSL_ERROR_WANT_WRITE);
6497 }
6498}
6499
David Benjamin1b819472020-06-09 14:01:02 -04006500TEST_P(SSLVersionTest, SameKeyResume) {
6501 uint8_t key[48];
6502 RAND_bytes(key, sizeof(key));
6503
6504 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
6505 ASSERT_TRUE(server_ctx2);
6506 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
6507 ASSERT_TRUE(
6508 SSL_CTX_set_tlsext_ticket_keys(server_ctx_.get(), key, sizeof(key)));
6509 ASSERT_TRUE(
6510 SSL_CTX_set_tlsext_ticket_keys(server_ctx2.get(), key, sizeof(key)));
6511
6512 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6513 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
6514 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
6515
6516 // Establish a session for |server_ctx_|.
6517 bssl::UniquePtr<SSL_SESSION> session =
6518 CreateClientSession(client_ctx_.get(), server_ctx_.get());
6519 ASSERT_TRUE(session);
6520 ClientConfig config;
6521 config.session = session.get();
6522
6523 // Resuming with |server_ctx_| again works.
6524 bssl::UniquePtr<SSL> client, server;
6525 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6526 server_ctx_.get(), config));
6527 EXPECT_TRUE(SSL_session_reused(client.get()));
6528 EXPECT_TRUE(SSL_session_reused(server.get()));
6529
6530 // Resuming with |server_ctx2| also works.
6531 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6532 server_ctx2.get(), config));
6533 EXPECT_TRUE(SSL_session_reused(client.get()));
6534 EXPECT_TRUE(SSL_session_reused(server.get()));
6535}
6536
6537TEST_P(SSLVersionTest, DifferentKeyNoResume) {
6538 uint8_t key1[48], key2[48];
6539 RAND_bytes(key1, sizeof(key1));
6540 RAND_bytes(key2, sizeof(key2));
6541
6542 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
6543 ASSERT_TRUE(server_ctx2);
6544 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
6545 ASSERT_TRUE(
6546 SSL_CTX_set_tlsext_ticket_keys(server_ctx_.get(), key1, sizeof(key1)));
6547 ASSERT_TRUE(
6548 SSL_CTX_set_tlsext_ticket_keys(server_ctx2.get(), key2, sizeof(key2)));
6549
6550 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6551 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
6552 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
6553
6554 // Establish a session for |server_ctx_|.
6555 bssl::UniquePtr<SSL_SESSION> session =
6556 CreateClientSession(client_ctx_.get(), server_ctx_.get());
6557 ASSERT_TRUE(session);
6558 ClientConfig config;
6559 config.session = session.get();
6560
6561 // Resuming with |server_ctx_| again works.
6562 bssl::UniquePtr<SSL> client, server;
6563 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6564 server_ctx_.get(), config));
6565 EXPECT_TRUE(SSL_session_reused(client.get()));
6566 EXPECT_TRUE(SSL_session_reused(server.get()));
6567
6568 // Resuming with |server_ctx2| does not work.
6569 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6570 server_ctx2.get(), config));
6571 EXPECT_FALSE(SSL_session_reused(client.get()));
6572 EXPECT_FALSE(SSL_session_reused(server.get()));
6573}
6574
6575TEST_P(SSLVersionTest, UnrelatedServerNoResume) {
6576 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
6577 ASSERT_TRUE(server_ctx2);
6578 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
6579
6580 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6581 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
6582 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
6583
6584 // Establish a session for |server_ctx_|.
6585 bssl::UniquePtr<SSL_SESSION> session =
6586 CreateClientSession(client_ctx_.get(), server_ctx_.get());
6587 ASSERT_TRUE(session);
6588 ClientConfig config;
6589 config.session = session.get();
6590
6591 // Resuming with |server_ctx_| again works.
6592 bssl::UniquePtr<SSL> client, server;
6593 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6594 server_ctx_.get(), config));
6595 EXPECT_TRUE(SSL_session_reused(client.get()));
6596 EXPECT_TRUE(SSL_session_reused(server.get()));
6597
6598 // Resuming with |server_ctx2| does not work.
6599 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6600 server_ctx2.get(), config));
6601 EXPECT_FALSE(SSL_session_reused(client.get()));
6602 EXPECT_FALSE(SSL_session_reused(server.get()));
6603}
6604
David Benjamin0e7dbd52019-05-15 16:01:18 -04006605TEST(SSLTest, WriteWhileExplicitRenegotiate) {
6606 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
6607 ASSERT_TRUE(ctx);
6608
6609 bssl::UniquePtr<X509> cert = GetTestCertificate();
6610 bssl::UniquePtr<EVP_PKEY> pkey = GetTestKey();
6611 ASSERT_TRUE(cert);
6612 ASSERT_TRUE(pkey);
6613 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
6614 ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), pkey.get()));
6615 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_2_VERSION));
6616 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_2_VERSION));
6617 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
6618 ctx.get(), "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"));
6619
6620 bssl::UniquePtr<SSL> client, server;
6621 ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
6622 ClientConfig(), true /* do_handshake */,
6623 false /* don't shed handshake config */));
6624 SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_explicit);
6625
6626 static const uint8_t kInput[] = {'h', 'e', 'l', 'l', 'o'};
6627
6628 // Write "hello" until the buffer is full, so |client| has a pending write.
6629 size_t num_writes = 0;
6630 for (;;) {
6631 int ret = SSL_write(client.get(), kInput, sizeof(kInput));
6632 if (ret != int(sizeof(kInput))) {
6633 ASSERT_EQ(-1, ret);
6634 ASSERT_EQ(SSL_ERROR_WANT_WRITE, SSL_get_error(client.get(), ret));
6635 break;
6636 }
6637 num_writes++;
6638 }
6639
6640 // Encrypt a HelloRequest.
6641 uint8_t in[] = {SSL3_MT_HELLO_REQUEST, 0, 0, 0};
6642#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
6643 // Fuzzer-mode records are unencrypted.
6644 uint8_t record[5 + sizeof(in)];
6645 record[0] = SSL3_RT_HANDSHAKE;
6646 record[1] = 3;
6647 record[2] = 3; // TLS 1.2
6648 record[3] = 0;
6649 record[4] = sizeof(record) - 5;
6650 memcpy(record + 5, in, sizeof(in));
6651#else
6652 // Extract key material from |server|.
6653 static const size_t kKeyLen = 32;
6654 static const size_t kNonceLen = 12;
6655 ASSERT_EQ(2u * (kKeyLen + kNonceLen), SSL_get_key_block_len(server.get()));
6656 uint8_t key_block[2u * (kKeyLen + kNonceLen)];
6657 ASSERT_TRUE(
6658 SSL_generate_key_block(server.get(), key_block, sizeof(key_block)));
6659 Span<uint8_t> key = MakeSpan(key_block + kKeyLen, kKeyLen);
6660 Span<uint8_t> nonce =
6661 MakeSpan(key_block + kKeyLen + kKeyLen + kNonceLen, kNonceLen);
6662
6663 uint8_t ad[13];
6664 uint64_t seq = SSL_get_write_sequence(server.get());
6665 for (size_t i = 0; i < 8; i++) {
6666 // The nonce is XORed with the sequence number.
6667 nonce[11 - i] ^= uint8_t(seq);
6668 ad[7 - i] = uint8_t(seq);
6669 seq >>= 8;
6670 }
6671
6672 ad[8] = SSL3_RT_HANDSHAKE;
6673 ad[9] = 3;
6674 ad[10] = 3; // TLS 1.2
6675 ad[11] = 0;
6676 ad[12] = sizeof(in);
6677
6678 uint8_t record[5 + sizeof(in) + 16];
6679 record[0] = SSL3_RT_HANDSHAKE;
6680 record[1] = 3;
6681 record[2] = 3; // TLS 1.2
6682 record[3] = 0;
6683 record[4] = sizeof(record) - 5;
6684
6685 ScopedEVP_AEAD_CTX aead;
6686 ASSERT_TRUE(EVP_AEAD_CTX_init(aead.get(), EVP_aead_chacha20_poly1305(),
6687 key.data(), key.size(),
6688 EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr));
6689 size_t len;
6690 ASSERT_TRUE(EVP_AEAD_CTX_seal(aead.get(), record + 5, &len,
6691 sizeof(record) - 5, nonce.data(), nonce.size(),
6692 in, sizeof(in), ad, sizeof(ad)));
6693 ASSERT_EQ(sizeof(record) - 5, len);
6694#endif // BORINGSSL_UNSAFE_FUZZER_MODE
6695
6696 ASSERT_EQ(int(sizeof(record)),
6697 BIO_write(SSL_get_wbio(server.get()), record, sizeof(record)));
6698
6699 // |SSL_read| should pick up the HelloRequest.
6700 uint8_t byte;
6701 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
6702 ASSERT_EQ(SSL_ERROR_WANT_RENEGOTIATE, SSL_get_error(client.get(), -1));
6703
6704 // Drain the data from the |client|.
6705 uint8_t buf[sizeof(kInput)];
6706 for (size_t i = 0; i < num_writes; i++) {
6707 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
6708 EXPECT_EQ(Bytes(buf), Bytes(kInput));
6709 }
6710
6711 // |client| should be able to finish the pending write and continue to write,
6712 // despite the paused HelloRequest.
6713 ASSERT_EQ(int(sizeof(kInput)),
6714 SSL_write(client.get(), kInput, sizeof(kInput)));
6715 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
6716 EXPECT_EQ(Bytes(buf), Bytes(kInput));
6717
6718 ASSERT_EQ(int(sizeof(kInput)),
6719 SSL_write(client.get(), kInput, sizeof(kInput)));
6720 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
6721 EXPECT_EQ(Bytes(buf), Bytes(kInput));
6722
6723 // |SSL_read| is stuck until we acknowledge the HelloRequest.
6724 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
6725 ASSERT_EQ(SSL_ERROR_WANT_RENEGOTIATE, SSL_get_error(client.get(), -1));
6726
6727 ASSERT_TRUE(SSL_renegotiate(client.get()));
6728 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
6729 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
6730
6731 // We never renegotiate as a server.
6732 ASSERT_EQ(-1, SSL_read(server.get(), buf, sizeof(buf)));
6733 ASSERT_EQ(SSL_ERROR_SSL, SSL_get_error(server.get(), -1));
6734 uint32_t err = ERR_get_error();
6735 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
6736 EXPECT_EQ(SSL_R_NO_RENEGOTIATION, ERR_GET_REASON(err));
6737}
6738
David Benjaminf9e0cda2020-03-23 18:29:09 -04006739
6740TEST(SSLTest, CopyWithoutEarlyData) {
6741 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
6742 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
6743 ASSERT_TRUE(client_ctx);
6744 ASSERT_TRUE(server_ctx);
6745
6746 bssl::UniquePtr<X509> cert = GetTestCertificate();
6747 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
6748 ASSERT_TRUE(cert);
6749 ASSERT_TRUE(key);
6750 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
6751 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
6752
6753 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
6754 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
6755 SSL_CTX_set_early_data_enabled(client_ctx.get(), 1);
6756 SSL_CTX_set_early_data_enabled(server_ctx.get(), 1);
6757
6758 bssl::UniquePtr<SSL_SESSION> session =
6759 CreateClientSession(client_ctx.get(), server_ctx.get());
6760 ASSERT_TRUE(session);
6761
6762 // The client should attempt early data with |session|.
6763 auto config = ClientConfig();
6764 config.early_data = true;
6765 config.session = session.get();
6766 bssl::UniquePtr<SSL> client, server;
6767 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
6768 server_ctx.get(), config,
6769 /*do_handshake=*/false));
6770 ASSERT_EQ(1, SSL_do_handshake(client.get()));
6771 EXPECT_TRUE(SSL_in_early_data(client.get()));
6772
6773 // |SSL_SESSION_copy_without_early_data| should disable early data but
6774 // still resume the session.
6775 bssl::UniquePtr<SSL_SESSION> session2(
6776 SSL_SESSION_copy_without_early_data(session.get()));
6777 ASSERT_TRUE(session2);
6778 EXPECT_NE(session.get(), session2.get());
6779 config.session = session2.get();
6780 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
6781 server_ctx.get(), config));
6782 EXPECT_TRUE(SSL_session_reused(client.get()));
6783 EXPECT_EQ(ssl_early_data_unsupported_for_session,
6784 SSL_get_early_data_reason(client.get()));
6785
6786 // |SSL_SESSION_copy_without_early_data| should be a reference count increase
6787 // when passed an early-data-incapable session.
6788 bssl::UniquePtr<SSL_SESSION> session3(
6789 SSL_SESSION_copy_without_early_data(session2.get()));
6790 EXPECT_EQ(session2.get(), session3.get());
6791}
6792
Adam Langley53a17f52020-05-26 14:44:07 -07006793TEST(SSLTest, ProcessTLS13NewSessionTicket) {
6794 // Configure client and server to negotiate TLS 1.3 only.
6795 bssl::UniquePtr<X509> cert = GetTestCertificate();
6796 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
6797 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
6798 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
6799 ASSERT_TRUE(client_ctx);
6800 ASSERT_TRUE(server_ctx);
6801 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
6802 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
6803 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
6804 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
6805 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
6806 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
6807
6808 bssl::UniquePtr<SSL> client, server;
6809 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
6810 server_ctx.get()));
6811 EXPECT_EQ(TLS1_3_VERSION, SSL_version(client.get()));
6812
6813 // Process a TLS 1.3 NewSessionTicket.
6814 static const uint8_t kTicket[] = {
6815 0x04, 0x00, 0x00, 0xb2, 0x00, 0x02, 0xa3, 0x00, 0x04, 0x03, 0x02, 0x01,
6816 0x01, 0x00, 0x00, 0xa0, 0x01, 0x06, 0x09, 0x11, 0x16, 0x19, 0x21, 0x26,
6817 0x29, 0x31, 0x36, 0x39, 0x41, 0x46, 0x49, 0x51, 0x03, 0x06, 0x09, 0x13,
6818 0x16, 0x19, 0x23, 0x26, 0x29, 0x33, 0x36, 0x39, 0x43, 0x46, 0x49, 0x53,
6819 0xf7, 0x00, 0x29, 0xec, 0xf2, 0xc4, 0xa4, 0x41, 0xfc, 0x30, 0x17, 0x2e,
6820 0x9f, 0x7c, 0xa8, 0xaf, 0x75, 0x70, 0xf0, 0x1f, 0xc7, 0x98, 0xf7, 0xcf,
6821 0x5a, 0x5a, 0x6b, 0x5b, 0xfe, 0xf1, 0xe7, 0x3a, 0xe8, 0xf7, 0x6c, 0xd2,
6822 0xa8, 0xa6, 0x92, 0x5b, 0x96, 0x8d, 0xde, 0xdb, 0xd3, 0x20, 0x6a, 0xcb,
6823 0x69, 0x06, 0xf4, 0x91, 0x85, 0x2e, 0xe6, 0x5e, 0x0c, 0x59, 0xf2, 0x9e,
6824 0x9b, 0x79, 0x91, 0x24, 0x7e, 0x4a, 0x32, 0x3d, 0xbe, 0x4b, 0x80, 0x70,
6825 0xaf, 0xd0, 0x1d, 0xe2, 0xca, 0x05, 0x35, 0x09, 0x09, 0x05, 0x0f, 0xbb,
6826 0xc4, 0xae, 0xd7, 0xc4, 0xed, 0xd7, 0xae, 0x35, 0xc8, 0x73, 0x63, 0x78,
6827 0x64, 0xc9, 0x7a, 0x1f, 0xed, 0x7a, 0x9a, 0x47, 0x44, 0xfd, 0x50, 0xf7,
6828 0xb7, 0xe0, 0x64, 0xa9, 0x02, 0xc1, 0x5c, 0x23, 0x18, 0x3f, 0xc4, 0xcf,
6829 0x72, 0x02, 0x59, 0x2d, 0xe1, 0xaa, 0x61, 0x72, 0x00, 0x04, 0x5a, 0x5a,
6830 0x00, 0x00,
6831 };
6832 bssl::UniquePtr<SSL_SESSION> session(SSL_process_tls13_new_session_ticket(
6833 client.get(), kTicket, sizeof(kTicket)));
6834 ASSERT_TRUE(session);
6835 ASSERT_TRUE(SSL_SESSION_has_ticket(session.get()));
6836
6837 uint8_t *session_buf = nullptr;
6838 size_t session_length = 0;
6839 ASSERT_TRUE(
6840 SSL_SESSION_to_bytes(session.get(), &session_buf, &session_length));
6841 bssl::UniquePtr<uint8_t> session_buf_free(session_buf);
6842 ASSERT_TRUE(session_buf);
6843 ASSERT_GT(session_length, 0u);
6844
6845 // Servers cannot call |SSL_process_tls13_new_session_ticket|.
6846 ASSERT_FALSE(SSL_process_tls13_new_session_ticket(server.get(), kTicket,
6847 sizeof(kTicket)));
6848
6849 // Clients cannot call |SSL_process_tls13_new_session_ticket| before the
6850 // handshake completes.
6851 bssl::UniquePtr<SSL> client2(SSL_new(client_ctx.get()));
6852 ASSERT_TRUE(client2);
6853 SSL_set_connect_state(client2.get());
6854 ASSERT_FALSE(SSL_process_tls13_new_session_ticket(client2.get(), kTicket,
6855 sizeof(kTicket)));
6856}
6857
David Benjamin3989c992020-10-09 14:12:06 -04006858TEST(SSLTest, BIO) {
6859 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
6860 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
6861 ASSERT_TRUE(client_ctx);
6862 ASSERT_TRUE(server_ctx);
6863
6864 bssl::UniquePtr<X509> cert = GetTestCertificate();
6865 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
6866 ASSERT_TRUE(cert);
6867 ASSERT_TRUE(key);
6868 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
6869 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
6870
6871 for (bool take_ownership : {true, false}) {
6872 // For simplicity, get the handshake out of the way first.
6873 bssl::UniquePtr<SSL> client, server;
6874 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
6875 server_ctx.get()));
6876
6877 // Wrap |client| in an SSL BIO.
6878 bssl::UniquePtr<BIO> client_bio(BIO_new(BIO_f_ssl()));
6879 ASSERT_TRUE(client_bio);
6880 ASSERT_EQ(1, BIO_set_ssl(client_bio.get(), client.get(), take_ownership));
6881 if (take_ownership) {
6882 client.release();
6883 }
6884
6885 // Flushing the BIO should not crash.
6886 EXPECT_EQ(1, BIO_flush(client_bio.get()));
6887
6888 // Exchange some data.
6889 EXPECT_EQ(5, BIO_write(client_bio.get(), "hello", 5));
6890 uint8_t buf[5];
6891 ASSERT_EQ(5, SSL_read(server.get(), buf, sizeof(buf)));
6892 EXPECT_EQ(Bytes("hello"), Bytes(buf));
6893
6894 EXPECT_EQ(5, SSL_write(server.get(), "world", 5));
6895 ASSERT_EQ(5, BIO_read(client_bio.get(), buf, sizeof(buf)));
6896 EXPECT_EQ(Bytes("world"), Bytes(buf));
6897
6898 // |BIO_should_read| should work.
6899 EXPECT_EQ(-1, BIO_read(client_bio.get(), buf, sizeof(buf)));
6900 EXPECT_TRUE(BIO_should_read(client_bio.get()));
6901
6902 // Writing data should eventually exceed the buffer size and fail, reporting
6903 // |BIO_should_write|.
6904 int ret;
6905 for (int i = 0; i < 1024; i++) {
6906 std::vector<uint8_t> buffer(1024);
6907 ret = BIO_write(client_bio.get(), buffer.data(), buffer.size());
6908 if (ret <= 0) {
6909 break;
6910 }
6911 }
6912 EXPECT_EQ(-1, ret);
6913 EXPECT_TRUE(BIO_should_write(client_bio.get()));
6914 }
6915}
6916
Martin Kreichgauer72912d22017-08-04 12:06:43 -07006917} // namespace
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -07006918BSSL_NAMESPACE_END