blob: e2708b1b0c0cbbd24d30198c25a0b1541b89304a [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 Benjaminc890ae52021-06-06 13:32:29 -040035#include <openssl/hpke.h>
David Benjaminde942382016-02-11 12:02:01 -050036#include <openssl/pem.h>
David Benjamin25490f22016-07-14 00:22:54 -040037#include <openssl/sha.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040038#include <openssl/ssl.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040039#include <openssl/rand.h>
David Benjaminde942382016-02-11 12:02:01 -050040#include <openssl/x509.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040041
Steven Valdez87eab492016-06-27 16:34:59 -040042#include "internal.h"
Steven Valdezcb966542016-08-17 16:56:14 -040043#include "../crypto/internal.h"
Sigbjorn Vik2b23d242015-06-29 15:07:26 +020044#include "../crypto/test/test_util.h"
45
David Benjamin721e8b72016-08-03 13:13:17 -040046#if defined(OPENSSL_WINDOWS)
David Benjaminc11ea9422017-08-29 16:33:21 -040047// Windows defines struct timeval in winsock2.h.
David Benjamin721e8b72016-08-03 13:13:17 -040048OPENSSL_MSVC_PRAGMA(warning(push, 3))
49#include <winsock2.h>
50OPENSSL_MSVC_PRAGMA(warning(pop))
51#else
52#include <sys/time.h>
53#endif
54
David Benjamin5b33eff2018-09-22 16:52:48 -070055#if defined(OPENSSL_THREADS)
David Benjamin6c04bd12018-07-19 18:13:09 -040056#include <thread>
57#endif
58
David Benjamin1d77e562015-03-22 17:22:08 -040059
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -070060BSSL_NAMESPACE_BEGIN
Martin Kreichgauer72912d22017-08-04 12:06:43 -070061
62namespace {
63
Martin Kreichgauer1a663262017-08-16 14:54:04 -070064#define TRACED_CALL(code) \
65 do { \
66 SCOPED_TRACE("<- called from here"); \
67 code; \
68 if (::testing::Test::HasFatalFailure()) { \
69 return; \
70 } \
71 } while (false)
72
Martin Kreichgauer72912d22017-08-04 12:06:43 -070073struct VersionParam {
74 uint16_t version;
75 enum { is_tls, is_dtls } ssl_method;
76 const char name[8];
77};
78
79static const size_t kTicketKeyLen = 48;
80
81static const VersionParam kAllVersions[] = {
Martin Kreichgauer72912d22017-08-04 12:06:43 -070082 {TLS1_VERSION, VersionParam::is_tls, "TLS1"},
83 {TLS1_1_VERSION, VersionParam::is_tls, "TLS1_1"},
84 {TLS1_2_VERSION, VersionParam::is_tls, "TLS1_2"},
Martin Kreichgauer72912d22017-08-04 12:06:43 -070085 {TLS1_3_VERSION, VersionParam::is_tls, "TLS1_3"},
Martin Kreichgauer72912d22017-08-04 12:06:43 -070086 {DTLS1_VERSION, VersionParam::is_dtls, "DTLS1"},
87 {DTLS1_2_VERSION, VersionParam::is_dtls, "DTLS1_2"},
88};
89
David Benjamin1d77e562015-03-22 17:22:08 -040090struct ExpectedCipher {
91 unsigned long id;
David Benjaminbb0a17c2014-09-20 15:35:39 -040092 int in_group_flag;
David Benjamin1d77e562015-03-22 17:22:08 -040093};
David Benjaminbb0a17c2014-09-20 15:35:39 -040094
David Benjamin1d77e562015-03-22 17:22:08 -040095struct CipherTest {
96 // The rule string to apply.
David Benjaminbb0a17c2014-09-20 15:35:39 -040097 const char *rule;
David Benjaminfb974e62015-12-16 19:34:22 -050098 // The list of expected ciphers, in order.
99 std::vector<ExpectedCipher> expected;
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800100 // True if this cipher list should fail in strict mode.
101 bool strict_fail;
David Benjamin1d77e562015-03-22 17:22:08 -0400102};
David Benjaminbb0a17c2014-09-20 15:35:39 -0400103
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100104struct CurveTest {
105 // The rule string to apply.
106 const char *rule;
107 // The list of expected curves, in order.
108 std::vector<uint16_t> expected;
109};
110
Steven Valdezc8e0f902018-07-14 11:23:01 -0400111template <typename T>
112class UnownedSSLExData {
113 public:
114 UnownedSSLExData() {
115 index_ = SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
116 }
117
118 T *Get(const SSL *ssl) {
119 return index_ < 0 ? nullptr
120 : static_cast<T *>(SSL_get_ex_data(ssl, index_));
121 }
122
123 bool Set(SSL *ssl, T *t) {
124 return index_ >= 0 && SSL_set_ex_data(ssl, index_, t);
125 }
126
127 private:
128 int index_;
129};
130
David Benjaminfb974e62015-12-16 19:34:22 -0500131static const CipherTest kCipherTests[] = {
132 // Selecting individual ciphers should work.
133 {
134 "ECDHE-ECDSA-CHACHA20-POLY1305:"
135 "ECDHE-RSA-CHACHA20-POLY1305:"
136 "ECDHE-ECDSA-AES128-GCM-SHA256:"
137 "ECDHE-RSA-AES128-GCM-SHA256",
138 {
139 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500140 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500141 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
142 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
143 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800144 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500145 },
146 // + reorders selected ciphers to the end, keeping their relative order.
147 {
148 "ECDHE-ECDSA-CHACHA20-POLY1305:"
149 "ECDHE-RSA-CHACHA20-POLY1305:"
150 "ECDHE-ECDSA-AES128-GCM-SHA256:"
151 "ECDHE-RSA-AES128-GCM-SHA256:"
152 "+aRSA",
153 {
154 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500155 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
156 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500157 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
158 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800159 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500160 },
161 // ! banishes ciphers from future selections.
162 {
163 "!aRSA:"
164 "ECDHE-ECDSA-CHACHA20-POLY1305:"
165 "ECDHE-RSA-CHACHA20-POLY1305:"
166 "ECDHE-ECDSA-AES128-GCM-SHA256:"
167 "ECDHE-RSA-AES128-GCM-SHA256",
168 {
169 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500170 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
171 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800172 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500173 },
174 // Multiple masks can be ANDed in a single rule.
175 {
176 "kRSA+AESGCM+AES128",
177 {
178 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
179 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800180 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500181 },
182 // - removes selected ciphers, but preserves their order for future
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700183 // selections. Select AES_128_GCM, but order the key exchanges RSA,
David Benjaminfb974e62015-12-16 19:34:22 -0500184 // ECDHE_RSA.
185 {
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700186 "ALL:-kECDHE:"
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700187 "-kRSA:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500188 "AESGCM+AES128+aRSA",
189 {
190 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500191 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
192 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800193 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500194 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800195 // Unknown selectors are no-ops, except in strict mode.
David Benjaminfb974e62015-12-16 19:34:22 -0500196 {
197 "ECDHE-ECDSA-CHACHA20-POLY1305:"
198 "ECDHE-RSA-CHACHA20-POLY1305:"
199 "ECDHE-ECDSA-AES128-GCM-SHA256:"
200 "ECDHE-RSA-AES128-GCM-SHA256:"
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800201 "BOGUS1",
David Benjaminfb974e62015-12-16 19:34:22 -0500202 {
203 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500204 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500205 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
206 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
207 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800208 true,
209 },
210 // Unknown selectors are no-ops, except in strict mode.
211 {
212 "ECDHE-ECDSA-CHACHA20-POLY1305:"
213 "ECDHE-RSA-CHACHA20-POLY1305:"
214 "ECDHE-ECDSA-AES128-GCM-SHA256:"
215 "ECDHE-RSA-AES128-GCM-SHA256:"
216 "-BOGUS2:+BOGUS3:!BOGUS4",
217 {
218 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
219 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
220 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
221 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
222 },
223 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500224 },
225 // Square brackets specify equi-preference groups.
226 {
227 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
228 "[ECDHE-RSA-CHACHA20-POLY1305]:"
229 "ECDHE-RSA-AES128-GCM-SHA256",
230 {
231 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
David Benjaminfb974e62015-12-16 19:34:22 -0500232 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley2e839242017-01-19 15:12:44 -0800233 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500234 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
235 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800236 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500237 },
David Benjamin6fff3862017-06-21 21:07:04 -0400238 // Standard names may be used instead of OpenSSL names.
239 {
240 "[TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256|"
David Benjaminbf5f1922017-07-01 11:13:53 -0400241 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256]:"
David Benjamin6fff3862017-06-21 21:07:04 -0400242 "[TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256]:"
243 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
244 {
245 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
246 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
247 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
248 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
249 },
250 false,
251 },
David Benjaminfb974e62015-12-16 19:34:22 -0500252 // @STRENGTH performs a stable strength-sort of the selected ciphers and
253 // only the selected ciphers.
254 {
255 // To simplify things, banish all but {ECDHE_RSA,RSA} x
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700256 // {CHACHA20,AES_256_CBC,AES_128_CBC} x SHA1.
David Benjamin6e678ee2018-04-16 19:54:42 -0400257 "!AESGCM:!3DES:"
David Benjaminfb974e62015-12-16 19:34:22 -0500258 // Order some ciphers backwards by strength.
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700259 "ALL:-CHACHA20:-AES256:-AES128:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500260 // Select ECDHE ones and sort them by strength. Ties should resolve
261 // based on the order above.
262 "kECDHE:@STRENGTH:-ALL:"
263 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
264 // by strength. Then RSA, backwards by strength.
265 "aRSA",
266 {
267 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
268 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500269 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500270 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
271 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
272 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800273 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500274 },
David Benjaminbf5f1922017-07-01 11:13:53 -0400275 // Additional masks after @STRENGTH get silently discarded.
276 //
277 // TODO(davidben): Make this an error. If not silently discarded, they get
278 // interpreted as + opcodes which are very different.
279 {
280 "ECDHE-RSA-AES128-GCM-SHA256:"
281 "ECDHE-RSA-AES256-GCM-SHA384:"
282 "@STRENGTH+AES256",
283 {
284 {TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
285 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
286 },
287 false,
288 },
289 {
290 "ECDHE-RSA-AES128-GCM-SHA256:"
291 "ECDHE-RSA-AES256-GCM-SHA384:"
292 "@STRENGTH+AES256:"
293 "ECDHE-RSA-CHACHA20-POLY1305",
294 {
295 {TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
296 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
297 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
298 },
299 false,
300 },
David Benjaminfb974e62015-12-16 19:34:22 -0500301 // Exact ciphers may not be used in multi-part rules; they are treated
302 // as unknown aliases.
303 {
304 "ECDHE-ECDSA-AES128-GCM-SHA256:"
305 "ECDHE-RSA-AES128-GCM-SHA256:"
306 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
307 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
308 {
309 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
310 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
311 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800312 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500313 },
314 // SSLv3 matches everything that existed before TLS 1.2.
315 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400316 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!SSLv3",
David Benjaminfb974e62015-12-16 19:34:22 -0500317 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400318 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500319 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800320 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500321 },
322 // TLSv1.2 matches everything added in TLS 1.2.
323 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400324 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!TLSv1.2",
David Benjaminfb974e62015-12-16 19:34:22 -0500325 {
326 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
327 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800328 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500329 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800330 // The two directives have no intersection. But each component is valid, so
331 // even in strict mode it is accepted.
David Benjaminfb974e62015-12-16 19:34:22 -0500332 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400333 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!TLSv1.2+SSLv3",
David Benjaminfb974e62015-12-16 19:34:22 -0500334 {
335 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400336 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500337 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800338 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500339 },
Adam Langley22df6912017-07-25 12:27:37 -0700340 // Spaces, semi-colons and commas are separators.
341 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400342 "AES128-SHA: ECDHE-RSA-AES128-GCM-SHA256 AES256-SHA ,ECDHE-ECDSA-AES128-GCM-SHA256 ; AES128-GCM-SHA256",
Adam Langley22df6912017-07-25 12:27:37 -0700343 {
344 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400345 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley22df6912017-07-25 12:27:37 -0700346 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400347 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley22df6912017-07-25 12:27:37 -0700348 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
349 },
350 // …but not in strict mode.
351 true,
352 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400353};
354
355static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400356 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400357 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
358 "RSA]",
359 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400360 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400361 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400362 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400363 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400364 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400365 "",
366 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400367 // COMPLEMENTOFDEFAULT is empty.
368 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400369 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400370 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400371 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400372 "[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]:-FOO",
375 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
Adam Langleyf99f2442016-10-02 09:53:38 -0700376 // Opcode supplied, but missing selector.
377 "+",
Adam Langley22df6912017-07-25 12:27:37 -0700378 // Spaces are forbidden in equal-preference groups.
379 "[AES128-SHA | AES128-SHA256]",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400380};
381
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700382static const char *kMustNotIncludeNull[] = {
383 "ALL",
384 "DEFAULT",
David Benjamind6e9eec2015-11-18 09:48:55 -0500385 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700386 "FIPS",
387 "SHA",
388 "SHA1",
389 "RSA",
390 "SSLv3",
391 "TLSv1",
392 "TLSv1.2",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700393};
394
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100395static const CurveTest kCurveTests[] = {
396 {
397 "P-256",
398 { SSL_CURVE_SECP256R1 },
399 },
400 {
Adam Langley7b935932018-11-12 13:53:42 -0800401 "P-256:CECPQ2",
402 { SSL_CURVE_SECP256R1, SSL_CURVE_CECPQ2 },
403 },
404
405 {
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100406 "P-256:P-384:P-521:X25519",
407 {
408 SSL_CURVE_SECP256R1,
409 SSL_CURVE_SECP384R1,
410 SSL_CURVE_SECP521R1,
411 SSL_CURVE_X25519,
412 },
413 },
David Benjamin6dda1662017-11-02 20:44:26 -0400414 {
415 "prime256v1:secp384r1:secp521r1:x25519",
416 {
417 SSL_CURVE_SECP256R1,
418 SSL_CURVE_SECP384R1,
419 SSL_CURVE_SECP521R1,
420 SSL_CURVE_X25519,
421 },
422 },
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100423};
424
425static const char *kBadCurvesLists[] = {
426 "",
427 ":",
428 "::",
429 "P-256::X25519",
430 "RSA:P-256",
431 "P-256:RSA",
432 "X25519:P-256:",
433 ":X25519:P-256",
434};
435
David Benjamin70dbf042017-08-08 18:51:37 -0400436static std::string CipherListToString(SSL_CTX *ctx) {
David Benjamin1d77e562015-03-22 17:22:08 -0400437 bool in_group = false;
David Benjamine11726a2017-04-23 12:14:28 -0400438 std::string ret;
David Benjamin70dbf042017-08-08 18:51:37 -0400439 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
440 for (size_t i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
441 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
442 if (!in_group && SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400443 ret += "\t[\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400444 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400445 }
David Benjamine11726a2017-04-23 12:14:28 -0400446 ret += "\t";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400447 if (in_group) {
David Benjamine11726a2017-04-23 12:14:28 -0400448 ret += " ";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400449 }
David Benjamine11726a2017-04-23 12:14:28 -0400450 ret += SSL_CIPHER_get_name(cipher);
451 ret += "\n";
David Benjamin70dbf042017-08-08 18:51:37 -0400452 if (in_group && !SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400453 ret += "\t]\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400454 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400455 }
456 }
David Benjamine11726a2017-04-23 12:14:28 -0400457 return ret;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400458}
459
David Benjamin70dbf042017-08-08 18:51:37 -0400460static bool CipherListsEqual(SSL_CTX *ctx,
David Benjamine11726a2017-04-23 12:14:28 -0400461 const std::vector<ExpectedCipher> &expected) {
David Benjamin70dbf042017-08-08 18:51:37 -0400462 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
463 if (sk_SSL_CIPHER_num(ciphers) != expected.size()) {
David Benjamin1d77e562015-03-22 17:22:08 -0400464 return false;
David Benjamin65226252015-02-05 16:49:47 -0500465 }
466
David Benjamine11726a2017-04-23 12:14:28 -0400467 for (size_t i = 0; i < expected.size(); i++) {
David Benjamin70dbf042017-08-08 18:51:37 -0400468 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
David Benjamine11726a2017-04-23 12:14:28 -0400469 if (expected[i].id != SSL_CIPHER_get_id(cipher) ||
David Benjamin70dbf042017-08-08 18:51:37 -0400470 expected[i].in_group_flag != !!SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400471 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400472 }
473 }
474
David Benjamin1d77e562015-03-22 17:22:08 -0400475 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400476}
477
Daniel McArdleff746c12019-09-16 12:35:05 -0400478TEST(GrowableArrayTest, Resize) {
479 GrowableArray<size_t> array;
480 ASSERT_TRUE(array.empty());
481 EXPECT_EQ(array.size(), 0u);
482
483 ASSERT_TRUE(array.Push(42));
484 ASSERT_TRUE(!array.empty());
485 EXPECT_EQ(array.size(), 1u);
486
487 // Force a resize operation to occur
488 for (size_t i = 0; i < 16; i++) {
489 ASSERT_TRUE(array.Push(i + 1));
490 }
491
492 EXPECT_EQ(array.size(), 17u);
493
494 // Verify that expected values are still contained in array
495 for (size_t i = 0; i < array.size(); i++) {
496 EXPECT_EQ(array[i], i == 0 ? 42 : i);
497 }
498}
499
500TEST(GrowableArrayTest, MoveConstructor) {
501 GrowableArray<size_t> array;
502 for (size_t i = 0; i < 100; i++) {
503 ASSERT_TRUE(array.Push(i));
504 }
505
506 GrowableArray<size_t> array_moved(std::move(array));
507 for (size_t i = 0; i < 100; i++) {
508 EXPECT_EQ(array_moved[i], i);
509 }
510}
511
512TEST(GrowableArrayTest, GrowableArrayContainingGrowableArrays) {
513 // Representative example of a struct that contains a GrowableArray.
514 struct TagAndArray {
515 size_t tag;
516 GrowableArray<size_t> array;
517 };
518
519 GrowableArray<TagAndArray> array;
520 for (size_t i = 0; i < 100; i++) {
521 TagAndArray elem;
522 elem.tag = i;
523 for (size_t j = 0; j < i; j++) {
524 ASSERT_TRUE(elem.array.Push(j));
525 }
526 ASSERT_TRUE(array.Push(std::move(elem)));
527 }
528 EXPECT_EQ(array.size(), static_cast<size_t>(100));
529
530 GrowableArray<TagAndArray> array_moved(std::move(array));
531 EXPECT_EQ(array_moved.size(), static_cast<size_t>(100));
532 size_t count = 0;
533 for (const TagAndArray &elem : array_moved) {
534 // Test the square bracket operator returns the same value as iteration.
535 EXPECT_EQ(&elem, &array_moved[count]);
536
537 EXPECT_EQ(elem.tag, count);
538 EXPECT_EQ(elem.array.size(), count);
539 for (size_t j = 0; j < count; j++) {
540 EXPECT_EQ(elem.array[j], j);
541 }
542 count++;
543 }
544}
545
David Benjamine11726a2017-04-23 12:14:28 -0400546TEST(SSLTest, CipherRules) {
547 for (const CipherTest &t : kCipherTests) {
548 SCOPED_TRACE(t.rule);
549 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
550 ASSERT_TRUE(ctx);
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700551
David Benjamine11726a2017-04-23 12:14:28 -0400552 // Test lax mode.
553 ASSERT_TRUE(SSL_CTX_set_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400554 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400555 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400556 << CipherListToString(ctx.get());
David Benjamine11726a2017-04-23 12:14:28 -0400557
558 // Test strict mode.
559 if (t.strict_fail) {
560 EXPECT_FALSE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
561 } else {
562 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400563 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400564 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400565 << CipherListToString(ctx.get());
David Benjaminbb0a17c2014-09-20 15:35:39 -0400566 }
567 }
568
David Benjaminfb974e62015-12-16 19:34:22 -0500569 for (const char *rule : kBadRules) {
David Benjamine11726a2017-04-23 12:14:28 -0400570 SCOPED_TRACE(rule);
571 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
572 ASSERT_TRUE(ctx);
573
574 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), rule));
David Benjaminbb0a17c2014-09-20 15:35:39 -0400575 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400576 }
577
David Benjaminfb974e62015-12-16 19:34:22 -0500578 for (const char *rule : kMustNotIncludeNull) {
David Benjamine11726a2017-04-23 12:14:28 -0400579 SCOPED_TRACE(rule);
580 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
581 ASSERT_TRUE(ctx);
582
583 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400584 for (const SSL_CIPHER *cipher : SSL_CTX_get_ciphers(ctx.get())) {
David Benjamine3bb51c2017-08-22 23:16:02 -0700585 EXPECT_NE(NID_undef, SSL_CIPHER_get_cipher_nid(cipher));
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700586 }
587 }
David Benjaminbb0a17c2014-09-20 15:35:39 -0400588}
David Benjamin2e521212014-07-16 14:37:51 -0400589
David Benjamine11726a2017-04-23 12:14:28 -0400590TEST(SSLTest, CurveRules) {
591 for (const CurveTest &t : kCurveTests) {
592 SCOPED_TRACE(t.rule);
593 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
594 ASSERT_TRUE(ctx);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100595
David Benjamine11726a2017-04-23 12:14:28 -0400596 ASSERT_TRUE(SSL_CTX_set1_curves_list(ctx.get(), t.rule));
David Benjamin0ce090a2018-07-02 20:24:40 -0400597 ASSERT_EQ(t.expected.size(), ctx->supported_group_list.size());
David Benjamine11726a2017-04-23 12:14:28 -0400598 for (size_t i = 0; i < t.expected.size(); i++) {
599 EXPECT_EQ(t.expected[i], ctx->supported_group_list[i]);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100600 }
601 }
602
603 for (const char *rule : kBadCurvesLists) {
David Benjamine11726a2017-04-23 12:14:28 -0400604 SCOPED_TRACE(rule);
605 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
606 ASSERT_TRUE(ctx);
607
608 EXPECT_FALSE(SSL_CTX_set1_curves_list(ctx.get(), rule));
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100609 ERR_clear_error();
610 }
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100611}
612
Adam Langley364f7a62016-12-12 10:51:00 -0800613// kOpenSSLSession is a serialized SSL_SESSION.
Adam Langley10f97f32016-07-12 08:09:33 -0700614static const char kOpenSSLSession[] =
Adam Langley364f7a62016-12-12 10:51:00 -0800615 "MIIFqgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700616 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
617 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
618 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
619 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
620 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
621 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
622 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
623 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
624 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
625 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
626 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
627 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
628 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
629 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
630 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
631 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
632 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
633 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
634 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
635 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
636 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
637 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
638 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
639 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
640 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
641 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
642 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
643 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
644 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
Adam Langley364f7a62016-12-12 10:51:00 -0800645 "i4gv7Y5oliyntgMBAQA=";
Adam Langley10f97f32016-07-12 08:09:33 -0700646
647// kCustomSession is a custom serialized SSL_SESSION generated by
648// filling in missing fields from |kOpenSSLSession|. This includes
649// providing |peer_sha256|, so |peer| is not serialized.
650static const char kCustomSession[] =
David Benjamina8614602017-09-06 15:40:19 -0400651 "MIIBZAIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700652 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
David Benjamina8614602017-09-06 15:40:19 -0400653 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUqAcEBXdvcmxkqQUCAwGJwKqBpwSB"
654 "pBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38"
655 "VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd"
656 "3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hg"
657 "b+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYGBgYGBgYGBgYGBgYGBgYGBgYG"
658 "BgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
Adam Langley10f97f32016-07-12 08:09:33 -0700659
660// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
661static const char kBoringSSLSession[] =
662 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
663 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
664 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
665 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
666 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
667 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
668 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
669 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
670 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
671 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
672 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
673 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
674 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
675 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
676 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
677 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
678 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
679 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
680 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
681 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
682 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
683 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
684 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
685 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
686 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
687 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
688 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
689 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
690 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
691 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
692 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
693 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
694 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
695 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
696 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
697 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
698 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
699 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
700 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
701 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
702 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
703 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
704 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
705 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
706 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
707 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
708 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
709 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
710 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
711 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
712 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
713 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
714 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
715 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
716 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
717 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
718 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
719 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
720 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
721 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
722 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
723 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
724 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
725 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
726 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
727 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
728 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
729 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
730 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
731 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
732 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
733 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
734 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
735 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
736 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
737 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
738 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
739 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
740 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
741 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
742 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
743 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
744 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
745 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
746 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
747 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
748 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
749 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
750 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
751 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
752 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
753 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
754 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
755 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
756 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
757
758// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
Steven Valdez51607f12020-08-05 10:46:05 -0400759// the final (optional) element of |kCustomSession| with tag number 99.
Adam Langley10f97f32016-07-12 08:09:33 -0700760static const char kBadSessionExtraField[] =
761 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
762 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
763 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
764 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
765 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
766 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
767 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
Steven Valdez51607f12020-08-05 10:46:05 -0400768 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBOMDBAEF";
Adam Langley10f97f32016-07-12 08:09:33 -0700769
770// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
771// the version of |kCustomSession| with 2.
772static const char kBadSessionVersion[] =
773 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
774 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
775 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
776 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
777 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
778 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
779 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
780 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
781
782// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
783// appended.
784static const char kBadSessionTrailingData[] =
785 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
786 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
787 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
788 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
789 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
790 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
791 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
792 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
793
David Benjamin1d77e562015-03-22 17:22:08 -0400794static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400795 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400796 if (!EVP_DecodedLength(&len, strlen(in))) {
797 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400798 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400799 }
800
David Benjamin1d77e562015-03-22 17:22:08 -0400801 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800802 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400803 strlen(in))) {
804 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400805 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400806 }
David Benjamin1d77e562015-03-22 17:22:08 -0400807 out->resize(len);
808 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400809}
810
David Benjamina486c6c2019-03-28 18:32:38 -0500811TEST(SSLTest, SessionEncoding) {
812 for (const char *input_b64 : {
813 kOpenSSLSession,
814 kCustomSession,
815 kBoringSSLSession,
816 }) {
817 SCOPED_TRACE(std::string(input_b64));
818 // Decode the input.
819 std::vector<uint8_t> input;
820 ASSERT_TRUE(DecodeBase64(&input, input_b64));
David Benjamin751e8892014-10-19 00:59:36 -0400821
David Benjamina486c6c2019-03-28 18:32:38 -0500822 // Verify the SSL_SESSION decodes.
823 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
824 ASSERT_TRUE(ssl_ctx);
825 bssl::UniquePtr<SSL_SESSION> session(
826 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
827 ASSERT_TRUE(session) << "SSL_SESSION_from_bytes failed";
828
829 // Verify the SSL_SESSION encoding round-trips.
830 size_t encoded_len;
831 bssl::UniquePtr<uint8_t> encoded;
832 uint8_t *encoded_raw;
833 ASSERT_TRUE(SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len))
834 << "SSL_SESSION_to_bytes failed";
835 encoded.reset(encoded_raw);
836 EXPECT_EQ(Bytes(encoded.get(), encoded_len), Bytes(input))
837 << "SSL_SESSION_to_bytes did not round-trip";
838
839 // Verify the SSL_SESSION also decodes with the legacy API.
840 const uint8_t *cptr = input.data();
841 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
842 ASSERT_TRUE(session) << "d2i_SSL_SESSION failed";
843 EXPECT_EQ(cptr, input.data() + input.size());
844
845 // Verify the SSL_SESSION encoding round-trips via the legacy API.
846 int len = i2d_SSL_SESSION(session.get(), NULL);
847 ASSERT_GT(len, 0) << "i2d_SSL_SESSION failed";
848 ASSERT_EQ(static_cast<size_t>(len), input.size())
849 << "i2d_SSL_SESSION(NULL) returned invalid length";
850
851 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
852 ASSERT_TRUE(encoded);
853
854 uint8_t *ptr = encoded.get();
855 len = i2d_SSL_SESSION(session.get(), &ptr);
856 ASSERT_GT(len, 0) << "i2d_SSL_SESSION failed";
857 ASSERT_EQ(static_cast<size_t>(len), input.size())
858 << "i2d_SSL_SESSION(NULL) returned invalid length";
859 ASSERT_EQ(ptr, encoded.get() + input.size())
860 << "i2d_SSL_SESSION did not advance ptr correctly";
861 EXPECT_EQ(Bytes(encoded.get(), encoded_len), Bytes(input))
862 << "SSL_SESSION_to_bytes did not round-trip";
David Benjamin751e8892014-10-19 00:59:36 -0400863 }
864
David Benjamina486c6c2019-03-28 18:32:38 -0500865 for (const char *input_b64 : {
866 kBadSessionExtraField,
867 kBadSessionVersion,
868 kBadSessionTrailingData,
869 }) {
870 SCOPED_TRACE(std::string(input_b64));
871 std::vector<uint8_t> input;
872 ASSERT_TRUE(DecodeBase64(&input, input_b64));
David Benjamin751e8892014-10-19 00:59:36 -0400873
David Benjamina486c6c2019-03-28 18:32:38 -0500874 // Verify that the SSL_SESSION fails to decode.
875 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
876 ASSERT_TRUE(ssl_ctx);
877 bssl::UniquePtr<SSL_SESSION> session(
878 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
879 EXPECT_FALSE(session) << "SSL_SESSION_from_bytes unexpectedly succeeded";
880 ERR_clear_error();
David Benjamin3cac4502014-10-21 01:46:30 -0400881 }
David Benjaminf297e022015-05-28 19:55:29 -0400882}
883
David Benjamin321fcdc2017-04-24 11:42:42 -0400884static void ExpectDefaultVersion(uint16_t min_version, uint16_t max_version,
885 const SSL_METHOD *(*method)(void)) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700886 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
David Benjamin321fcdc2017-04-24 11:42:42 -0400887 ASSERT_TRUE(ctx);
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -0700888 EXPECT_EQ(min_version, SSL_CTX_get_min_proto_version(ctx.get()));
889 EXPECT_EQ(max_version, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjamin321fcdc2017-04-24 11:42:42 -0400890}
891
892TEST(SSLTest, DefaultVersion) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -0800893 ExpectDefaultVersion(TLS1_VERSION, TLS1_3_VERSION, &TLS_method);
David Benjamin321fcdc2017-04-24 11:42:42 -0400894 ExpectDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method);
895 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method);
896 ExpectDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method);
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -0700897 ExpectDefaultVersion(DTLS1_VERSION, DTLS1_2_VERSION, &DTLS_method);
898 ExpectDefaultVersion(DTLS1_VERSION, DTLS1_VERSION, &DTLSv1_method);
899 ExpectDefaultVersion(DTLS1_2_VERSION, DTLS1_2_VERSION, &DTLSv1_2_method);
David Benjamin82c9e902014-12-12 15:55:27 -0500900}
901
David Benjamin348f0d82017-08-10 16:06:27 -0400902TEST(SSLTest, CipherProperties) {
David Benjamin6fff3862017-06-21 21:07:04 -0400903 static const struct {
904 int id;
905 const char *standard_name;
David Benjamin348f0d82017-08-10 16:06:27 -0400906 int cipher_nid;
907 int digest_nid;
908 int kx_nid;
909 int auth_nid;
David Benjaminb1b76ae2017-09-21 17:03:34 -0400910 int prf_nid;
David Benjamin6fff3862017-06-21 21:07:04 -0400911 } kTests[] = {
David Benjamin348f0d82017-08-10 16:06:27 -0400912 {
913 SSL3_CK_RSA_DES_192_CBC3_SHA,
914 "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
915 NID_des_ede3_cbc,
916 NID_sha1,
917 NID_kx_rsa,
918 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400919 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400920 },
921 {
922 TLS1_CK_RSA_WITH_AES_128_SHA,
923 "TLS_RSA_WITH_AES_128_CBC_SHA",
924 NID_aes_128_cbc,
925 NID_sha1,
926 NID_kx_rsa,
927 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400928 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400929 },
930 {
931 TLS1_CK_PSK_WITH_AES_256_CBC_SHA,
932 "TLS_PSK_WITH_AES_256_CBC_SHA",
933 NID_aes_256_cbc,
934 NID_sha1,
935 NID_kx_psk,
936 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400937 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400938 },
939 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400940 TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA,
941 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
David Benjamin348f0d82017-08-10 16:06:27 -0400942 NID_aes_128_cbc,
David Benjamin6e678ee2018-04-16 19:54:42 -0400943 NID_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400944 NID_kx_ecdhe,
945 NID_auth_rsa,
David Benjamin6e678ee2018-04-16 19:54:42 -0400946 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400947 },
948 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400949 TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA,
950 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
David Benjamin348f0d82017-08-10 16:06:27 -0400951 NID_aes_256_cbc,
David Benjamin6e678ee2018-04-16 19:54:42 -0400952 NID_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400953 NID_kx_ecdhe,
954 NID_auth_rsa,
David Benjamin6e678ee2018-04-16 19:54:42 -0400955 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400956 },
957 {
958 TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
959 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
960 NID_aes_128_gcm,
961 NID_undef,
962 NID_kx_ecdhe,
963 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400964 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400965 },
966 {
967 TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
968 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
969 NID_aes_128_gcm,
970 NID_undef,
971 NID_kx_ecdhe,
972 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400973 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400974 },
975 {
976 TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
977 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
978 NID_aes_256_gcm,
979 NID_undef,
980 NID_kx_ecdhe,
981 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400982 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -0400983 },
984 {
985 TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
986 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
987 NID_aes_128_cbc,
988 NID_sha1,
989 NID_kx_ecdhe,
990 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400991 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400992 },
993 {
994 TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
995 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
996 NID_chacha20_poly1305,
997 NID_undef,
998 NID_kx_ecdhe,
999 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001000 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -04001001 },
1002 {
1003 TLS1_CK_AES_256_GCM_SHA384,
1004 "TLS_AES_256_GCM_SHA384",
1005 NID_aes_256_gcm,
1006 NID_undef,
1007 NID_kx_any,
1008 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001009 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -04001010 },
1011 {
1012 TLS1_CK_AES_128_GCM_SHA256,
1013 "TLS_AES_128_GCM_SHA256",
1014 NID_aes_128_gcm,
1015 NID_undef,
1016 NID_kx_any,
1017 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001018 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -04001019 },
1020 {
1021 TLS1_CK_CHACHA20_POLY1305_SHA256,
1022 "TLS_CHACHA20_POLY1305_SHA256",
1023 NID_chacha20_poly1305,
1024 NID_undef,
1025 NID_kx_any,
1026 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001027 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -04001028 },
David Benjamin6fff3862017-06-21 21:07:04 -04001029 };
David Benjamin65226252015-02-05 16:49:47 -05001030
David Benjamin6fff3862017-06-21 21:07:04 -04001031 for (const auto &t : kTests) {
1032 SCOPED_TRACE(t.standard_name);
David Benjamine11726a2017-04-23 12:14:28 -04001033
1034 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(t.id & 0xffff);
1035 ASSERT_TRUE(cipher);
David Benjamin6fff3862017-06-21 21:07:04 -04001036 EXPECT_STREQ(t.standard_name, SSL_CIPHER_standard_name(cipher));
1037
David Benjamine11726a2017-04-23 12:14:28 -04001038 bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
1039 ASSERT_TRUE(rfc_name);
David Benjamin6fff3862017-06-21 21:07:04 -04001040 EXPECT_STREQ(t.standard_name, rfc_name.get());
David Benjamin348f0d82017-08-10 16:06:27 -04001041
1042 EXPECT_EQ(t.cipher_nid, SSL_CIPHER_get_cipher_nid(cipher));
1043 EXPECT_EQ(t.digest_nid, SSL_CIPHER_get_digest_nid(cipher));
1044 EXPECT_EQ(t.kx_nid, SSL_CIPHER_get_kx_nid(cipher));
1045 EXPECT_EQ(t.auth_nid, SSL_CIPHER_get_auth_nid(cipher));
David Benjaminb1b76ae2017-09-21 17:03:34 -04001046 EXPECT_EQ(t.prf_nid, SSL_CIPHER_get_prf_nid(cipher));
David Benjamin65226252015-02-05 16:49:47 -05001047 }
David Benjamin65226252015-02-05 16:49:47 -05001048}
1049
Steven Valdeza833c352016-11-01 13:39:36 -04001050// CreateSessionWithTicket returns a sample |SSL_SESSION| with the specified
1051// version and ticket length or nullptr on failure.
1052static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(uint16_t version,
1053 size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -04001054 std::vector<uint8_t> der;
1055 if (!DecodeBase64(&der, kOpenSSLSession)) {
1056 return nullptr;
1057 }
Adam Langley46db7af2017-02-01 15:49:37 -08001058
1059 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
1060 if (!ssl_ctx) {
1061 return nullptr;
1062 }
David Benjaminaaef8332018-06-29 16:45:49 -04001063 // Use a garbage ticket.
1064 std::vector<uint8_t> ticket(ticket_len, 'a');
Steven Valdeza833c352016-11-01 13:39:36 -04001065 bssl::UniquePtr<SSL_SESSION> session(
Adam Langley46db7af2017-02-01 15:49:37 -08001066 SSL_SESSION_from_bytes(der.data(), der.size(), ssl_ctx.get()));
David Benjaminaaef8332018-06-29 16:45:49 -04001067 if (!session ||
1068 !SSL_SESSION_set_protocol_version(session.get(), version) ||
1069 !SSL_SESSION_set_ticket(session.get(), ticket.data(), ticket.size())) {
David Benjamin422fe082015-07-21 22:03:43 -04001070 return nullptr;
1071 }
David Benjamin1269ddd2015-10-18 15:18:55 -04001072 // Fix up the timeout.
David Benjamin9b63f292016-11-15 00:44:05 -05001073#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
David Benjaminaaef8332018-06-29 16:45:49 -04001074 SSL_SESSION_set_time(session.get(), 1234);
David Benjamin9b63f292016-11-15 00:44:05 -05001075#else
David Benjaminaaef8332018-06-29 16:45:49 -04001076 SSL_SESSION_set_time(session.get(), time(nullptr));
David Benjamin9b63f292016-11-15 00:44:05 -05001077#endif
David Benjamin422fe082015-07-21 22:03:43 -04001078 return session;
1079}
1080
David Benjaminafc64de2016-07-19 17:12:41 +02001081static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001082 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +02001083 if (!bio) {
1084 return false;
1085 }
1086 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -04001087 BIO_up_ref(bio.get());
1088 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +02001089 int ret = SSL_connect(ssl);
1090 if (ret > 0) {
1091 // SSL_connect should fail without a BIO to write to.
1092 return false;
1093 }
1094 ERR_clear_error();
1095
1096 const uint8_t *client_hello;
1097 size_t client_hello_len;
1098 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
1099 return false;
1100 }
1101 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
1102 return true;
1103}
1104
Steven Valdeza833c352016-11-01 13:39:36 -04001105// GetClientHelloLen creates a client SSL connection with the specified version
1106// and ticket length. It returns the length of the ClientHello, not including
1107// the record header, on success and zero on error.
1108static size_t GetClientHelloLen(uint16_t max_version, uint16_t session_version,
1109 size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001110 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Steven Valdeza833c352016-11-01 13:39:36 -04001111 bssl::UniquePtr<SSL_SESSION> session =
1112 CreateSessionWithTicket(session_version, ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -04001113 if (!ctx || !session) {
1114 return 0;
1115 }
Steven Valdeza833c352016-11-01 13:39:36 -04001116
1117 // Set a one-element cipher list so the baseline ClientHello is unpadded.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001118 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
Steven Valdez2c62fe92016-10-14 12:08:12 -04001119 if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -08001120 !SSL_set_strict_cipher_list(ssl.get(), "ECDHE-RSA-AES128-GCM-SHA256") ||
Steven Valdeza833c352016-11-01 13:39:36 -04001121 !SSL_set_max_proto_version(ssl.get(), max_version)) {
David Benjamin422fe082015-07-21 22:03:43 -04001122 return 0;
1123 }
Steven Valdeza833c352016-11-01 13:39:36 -04001124
David Benjaminafc64de2016-07-19 17:12:41 +02001125 std::vector<uint8_t> client_hello;
1126 if (!GetClientHello(ssl.get(), &client_hello) ||
1127 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -04001128 return 0;
1129 }
Steven Valdeza833c352016-11-01 13:39:36 -04001130
David Benjaminafc64de2016-07-19 17:12:41 +02001131 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -04001132}
1133
David Benjamina486c6c2019-03-28 18:32:38 -05001134TEST(SSLTest, Padding) {
1135 struct PaddingVersions {
1136 uint16_t max_version, session_version;
1137 };
1138 static const PaddingVersions kPaddingVersions[] = {
1139 // Test the padding extension at TLS 1.2.
1140 {TLS1_2_VERSION, TLS1_2_VERSION},
1141 // Test the padding extension at TLS 1.3 with a TLS 1.2 session, so there
1142 // will be no PSK binder after the padding extension.
1143 {TLS1_3_VERSION, TLS1_2_VERSION},
1144 // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
1145 // will be a PSK binder after the padding extension.
1146 {TLS1_3_VERSION, TLS1_3_VERSION},
David Benjamin422fe082015-07-21 22:03:43 -04001147
David Benjamina486c6c2019-03-28 18:32:38 -05001148 };
David Benjamin422fe082015-07-21 22:03:43 -04001149
David Benjamina486c6c2019-03-28 18:32:38 -05001150 struct PaddingTest {
1151 size_t input_len, padded_len;
1152 };
1153 static const PaddingTest kPaddingTests[] = {
1154 // ClientHellos of length below 0x100 do not require padding.
1155 {0xfe, 0xfe},
1156 {0xff, 0xff},
1157 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
1158 {0x100, 0x200},
1159 {0x123, 0x200},
1160 {0x1fb, 0x200},
1161 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
1162 // padding extension takes a minimum of four bytes plus one required
1163 // content
1164 // byte. (To work around yet more server bugs, we avoid empty final
1165 // extensions.)
1166 {0x1fc, 0x201},
1167 {0x1fd, 0x202},
1168 {0x1fe, 0x203},
1169 {0x1ff, 0x204},
1170 // Finally, larger ClientHellos need no padding.
1171 {0x200, 0x200},
1172 {0x201, 0x201},
1173 };
David Benjamin422fe082015-07-21 22:03:43 -04001174
David Benjamina486c6c2019-03-28 18:32:38 -05001175 for (const PaddingVersions &versions : kPaddingVersions) {
1176 SCOPED_TRACE(versions.max_version);
1177 SCOPED_TRACE(versions.session_version);
David Benjamin422fe082015-07-21 22:03:43 -04001178
David Benjamina486c6c2019-03-28 18:32:38 -05001179 // Sample a baseline length.
1180 size_t base_len =
1181 GetClientHelloLen(versions.max_version, versions.session_version, 1);
1182 ASSERT_NE(base_len, 0u) << "Baseline length could not be sampled";
1183
1184 for (const PaddingTest &test : kPaddingTests) {
1185 SCOPED_TRACE(test.input_len);
1186 ASSERT_LE(base_len, test.input_len) << "Baseline ClientHello too long";
1187
1188 size_t padded_len =
1189 GetClientHelloLen(versions.max_version, versions.session_version,
1190 1 + test.input_len - base_len);
1191 EXPECT_EQ(padded_len, test.padded_len)
1192 << "ClientHello was not padded to expected length";
David Benjamin422fe082015-07-21 22:03:43 -04001193 }
1194 }
David Benjamin422fe082015-07-21 22:03:43 -04001195}
1196
David Benjamin2f3958a2021-04-16 11:55:23 -04001197static bssl::UniquePtr<X509> CertFromPEM(const char *pem) {
1198 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1199 if (!bio) {
1200 return nullptr;
1201 }
1202 return bssl::UniquePtr<X509>(
1203 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
1204}
1205
1206static bssl::UniquePtr<EVP_PKEY> KeyFromPEM(const char *pem) {
1207 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1208 if (!bio) {
1209 return nullptr;
1210 }
1211 return bssl::UniquePtr<EVP_PKEY>(
1212 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1213}
1214
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001215static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001216 static const char kCertPEM[] =
1217 "-----BEGIN CERTIFICATE-----\n"
1218 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1219 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1220 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1221 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1222 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1223 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1224 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1225 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1226 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1227 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1228 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1229 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1230 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1231 "-----END CERTIFICATE-----\n";
David Benjamin2f3958a2021-04-16 11:55:23 -04001232 return CertFromPEM(kCertPEM);
David Benjaminde942382016-02-11 12:02:01 -05001233}
1234
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001235static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001236 static const char kKeyPEM[] =
1237 "-----BEGIN RSA PRIVATE KEY-----\n"
1238 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1239 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1240 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1241 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1242 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1243 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1244 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1245 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1246 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1247 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1248 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1249 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1250 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1251 "-----END RSA PRIVATE KEY-----\n";
David Benjamin2f3958a2021-04-16 11:55:23 -04001252 return KeyFromPEM(kKeyPEM);
David Benjaminde942382016-02-11 12:02:01 -05001253}
1254
David Benjamin9b2cdb72021-04-01 23:21:53 -04001255static bssl::UniquePtr<SSL_CTX> CreateContextWithTestCertificate(
1256 const SSL_METHOD *method) {
1257 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1258 bssl::UniquePtr<X509> cert = GetTestCertificate();
1259 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
1260 if (!ctx || !cert || !key ||
1261 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1262 !SSL_CTX_use_PrivateKey(ctx.get(), key.get())) {
1263 return nullptr;
1264 }
1265 return ctx;
1266}
1267
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001268static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001269 static const char kCertPEM[] =
1270 "-----BEGIN CERTIFICATE-----\n"
1271 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1272 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1273 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1274 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1275 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1276 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1277 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1278 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1279 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1280 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1281 "-----END CERTIFICATE-----\n";
David Benjamin2f3958a2021-04-16 11:55:23 -04001282 return CertFromPEM(kCertPEM);
David Benjamin0fc37ef2016-08-17 15:29:46 -04001283}
1284
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001285static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001286 static const char kKeyPEM[] =
1287 "-----BEGIN PRIVATE KEY-----\n"
1288 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1289 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1290 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1291 "-----END PRIVATE KEY-----\n";
David Benjamin2f3958a2021-04-16 11:55:23 -04001292 return KeyFromPEM(kKeyPEM);
David Benjamin0fc37ef2016-08-17 15:29:46 -04001293}
1294
Adam Langleyd04ca952017-02-28 11:26:51 -08001295static bssl::UniquePtr<CRYPTO_BUFFER> BufferFromPEM(const char *pem) {
1296 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1297 char *name, *header;
1298 uint8_t *data;
1299 long data_len;
1300 if (!PEM_read_bio(bio.get(), &name, &header, &data,
1301 &data_len)) {
1302 return nullptr;
1303 }
1304 OPENSSL_free(name);
1305 OPENSSL_free(header);
1306
1307 auto ret = bssl::UniquePtr<CRYPTO_BUFFER>(
1308 CRYPTO_BUFFER_new(data, data_len, nullptr));
1309 OPENSSL_free(data);
1310 return ret;
1311}
1312
1313static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestCertificateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001314 static const char kCertPEM[] =
1315 "-----BEGIN CERTIFICATE-----\n"
1316 "MIIC0jCCAbqgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQiBD\n"
1317 "QTAeFw0xNjAyMjgyMDI3MDNaFw0yNjAyMjUyMDI3MDNaMBgxFjAUBgNVBAMMDUNs\n"
1318 "aWVudCBDZXJ0IEEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRvaz8\n"
1319 "CC/cshpCafJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/\n"
1320 "kLRcH89M/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3\n"
1321 "tHb+xs2PSs8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+c\n"
1322 "IDs2rQ+lP7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1\n"
1323 "z7C8jU50Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9V\n"
1324 "iLeXANgZi+Xx9KgfAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI\n"
1325 "KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBFEVbmYl+2RtNw\n"
1326 "rDftRDF1v2QUbcN2ouSnQDHxeDQdSgasLzT3ui8iYu0Rw2WWcZ0DV5e0ztGPhWq7\n"
1327 "AO0B120aFRMOY+4+bzu9Q2FFkQqc7/fKTvTDzIJI5wrMnFvUfzzvxh3OHWMYSs/w\n"
1328 "giq33hTKeHEq6Jyk3btCny0Ycecyc3yGXH10sizUfiHlhviCkDuESk8mFDwDDzqW\n"
1329 "ZF0IipzFbEDHoIxLlm3GQxpiLoEV4k8KYJp3R5KBLFyxM6UGPz8h72mIPCJp2RuK\n"
1330 "MYgF91UDvVzvnYm6TfseM2+ewKirC00GOrZ7rEcFvtxnKSqYf4ckqfNdSU1Y+RRC\n"
1331 "1ngWZ7Ih\n"
1332 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001333 return BufferFromPEM(kCertPEM);
David Benjamin1444c3a2016-12-20 17:23:11 -05001334}
1335
Adam Langleyd04ca952017-02-28 11:26:51 -08001336static bssl::UniquePtr<X509> X509FromBuffer(
1337 bssl::UniquePtr<CRYPTO_BUFFER> buffer) {
1338 if (!buffer) {
1339 return nullptr;
1340 }
1341 const uint8_t *derp = CRYPTO_BUFFER_data(buffer.get());
1342 return bssl::UniquePtr<X509>(
1343 d2i_X509(NULL, &derp, CRYPTO_BUFFER_len(buffer.get())));
1344}
1345
1346static bssl::UniquePtr<X509> GetChainTestCertificate() {
1347 return X509FromBuffer(GetChainTestCertificateBuffer());
1348}
1349
1350static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestIntermediateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001351 static const char kCertPEM[] =
1352 "-----BEGIN CERTIFICATE-----\n"
1353 "MIICwjCCAaqgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS\n"
1354 "b290IENBMB4XDTE2MDIyODIwMjcwM1oXDTI2MDIyNTIwMjcwM1owDzENMAsGA1UE\n"
1355 "AwwEQiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALsSCYmDip2D\n"
1356 "GkjFxw7ykz26JSjELkl6ArlYjFJ3aT/SCh8qbS4gln7RH8CPBd78oFdfhIKQrwtZ\n"
1357 "3/q21ykD9BAS3qHe2YdcJfm8/kWAy5DvXk6NXU4qX334KofBAEpgdA/igEFq1P1l\n"
1358 "HAuIfZCpMRfT+i5WohVsGi8f/NgpRvVaMONLNfgw57mz1lbtFeBEISmX0kbsuJxF\n"
1359 "Qj/Bwhi5/0HAEXG8e7zN4cEx0yPRvmOATRdVb/8dW2pwOHRJq9R5M0NUkIsTSnL7\n"
1360 "6N/z8hRAHMsV3IudC5Yd7GXW1AGu9a+iKU+Q4xcZCoj0DC99tL4VKujrV1kAeqsM\n"
1361 "cz5/dKzi6+cCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
1362 "AQYwDQYJKoZIhvcNAQELBQADggEBAIIeZiEeNhWWQ8Y4D+AGDwqUUeG8NjCbKrXQ\n"
1363 "BlHg5wZ8xftFaiP1Dp/UAezmx2LNazdmuwrYB8lm3FVTyaPDTKEGIPS4wJKHgqH1\n"
1364 "QPDhqNm85ey7TEtI9oYjsNim/Rb+iGkIAMXaxt58SzxbjvP0kMr1JfJIZbic9vye\n"
1365 "NwIspMFIpP3FB8ywyu0T0hWtCQgL4J47nigCHpOu58deP88fS/Nyz/fyGVWOZ76b\n"
1366 "WhWwgM3P3X95fQ3d7oFPR/bVh0YV+Cf861INwplokXgXQ3/TCQ+HNXeAMWn3JLWv\n"
1367 "XFwk8owk9dq/kQGdndGgy3KTEW4ctPX5GNhf3LJ9Q7dLji4ReQ4=\n"
1368 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001369 return BufferFromPEM(kCertPEM);
1370}
1371
1372static bssl::UniquePtr<X509> GetChainTestIntermediate() {
1373 return X509FromBuffer(GetChainTestIntermediateBuffer());
David Benjamin1444c3a2016-12-20 17:23:11 -05001374}
1375
1376static bssl::UniquePtr<EVP_PKEY> GetChainTestKey() {
1377 static const char kKeyPEM[] =
1378 "-----BEGIN PRIVATE KEY-----\n"
1379 "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRvaz8CC/cshpC\n"
1380 "afJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/kLRcH89M\n"
1381 "/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3tHb+xs2P\n"
1382 "Ss8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+cIDs2rQ+l\n"
1383 "P7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1z7C8jU50\n"
1384 "Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9ViLeXANgZ\n"
1385 "i+Xx9KgfAgMBAAECggEBAK0VjSJzkyPaamcyTVSWjo7GdaBGcK60lk657RjR+lK0\n"
1386 "YJ7pkej4oM2hdsVZFsP8Cs4E33nXLa/0pDsRov/qrp0WQm2skwqGMC1I/bZ0WRPk\n"
1387 "wHaDrBBfESWnJDX/AGpVtlyOjPmgmK6J2usMPihQUDkKdAYrVWJePrMIxt1q6BMe\n"
1388 "iczs3qriMmtY3bUc4UyUwJ5fhDLjshHvfuIpYQyI6EXZM6dZksn9LylXJnigY6QJ\n"
1389 "HxOYO0BDwOsZ8yQ8J8afLk88i0GizEkgE1z3REtQUwgWfxr1WV/ud+T6/ZhSAgH9\n"
1390 "042mQvSFZnIUSEsmCvjhWuAunfxHKCTcAoYISWfzWpkCgYEA7gpf3HHU5Tn+CgUn\n"
1391 "1X5uGpG3DmcMgfeGgs2r2f/IIg/5Ac1dfYILiybL1tN9zbyLCJfcbFpWBc9hJL6f\n"
1392 "CPc5hUiwWFJqBJewxQkC1Ae/HakHbip+IZ+Jr0842O4BAArvixk4Lb7/N2Ct9sTE\n"
1393 "NJO6RtK9lbEZ5uK61DglHy8CS2UCgYEA4ZC1o36kPAMQBggajgnucb2yuUEelk0f\n"
1394 "AEr+GI32MGE+93xMr7rAhBoqLg4AITyIfEnOSQ5HwagnIHonBbv1LV/Gf9ursx8Z\n"
1395 "YOGbvT8zzzC+SU1bkDzdjAYnFQVGIjMtKOBJ3K07++ypwX1fr4QsQ8uKL8WSOWwt\n"
1396 "Z3Bym6XiZzMCgYADnhy+2OwHX85AkLt+PyGlPbmuelpyTzS4IDAQbBa6jcuW/2wA\n"
1397 "UE2km75VUXmD+u2R/9zVuLm99NzhFhSMqlUxdV1YukfqMfP5yp1EY6m/5aW7QuIP\n"
1398 "2MDa7TVL9rIFMiVZ09RKvbBbQxjhuzPQKL6X/PPspnhiTefQ+dl2k9xREQKBgHDS\n"
1399 "fMfGNEeAEKezrfSVqxphE9/tXms3L+ZpnCaT+yu/uEr5dTIAawKoQ6i9f/sf1/Sy\n"
1400 "xedsqR+IB+oKrzIDDWMgoJybN4pkZ8E5lzhVQIjFjKgFdWLzzqyW9z1gYfABQPlN\n"
1401 "FiS20WX0vgP1vcKAjdNrHzc9zyHBpgQzDmAj3NZZAoGBAI8vKCKdH7w3aL5CNkZQ\n"
1402 "2buIeWNA2HZazVwAGG5F2TU/LmXfRKnG6dX5bkU+AkBZh56jNZy//hfFSewJB4Kk\n"
1403 "buB7ERSdaNbO21zXt9FEA3+z0RfMd/Zv2vlIWOSB5nzl/7UKti3sribK6s9ZVLfi\n"
1404 "SxpiPQ8d/hmSGwn4ksrWUsJD\n"
1405 "-----END PRIVATE KEY-----\n";
David Benjamin2f3958a2021-04-16 11:55:23 -04001406 return KeyFromPEM(kKeyPEM);
David Benjamin1444c3a2016-12-20 17:23:11 -05001407}
1408
David Benjamin83a49932021-05-20 15:57:09 -04001409static bool CompleteHandshakes(SSL *client, SSL *server) {
1410 // Drive both their handshakes to completion.
1411 for (;;) {
1412 int client_ret = SSL_do_handshake(client);
1413 int client_err = SSL_get_error(client, client_ret);
1414 if (client_err != SSL_ERROR_NONE &&
1415 client_err != SSL_ERROR_WANT_READ &&
1416 client_err != SSL_ERROR_WANT_WRITE &&
1417 client_err != SSL_ERROR_PENDING_TICKET) {
1418 fprintf(stderr, "Client error: %s\n", SSL_error_description(client_err));
1419 return false;
1420 }
1421
1422 int server_ret = SSL_do_handshake(server);
1423 int server_err = SSL_get_error(server, server_ret);
1424 if (server_err != SSL_ERROR_NONE &&
1425 server_err != SSL_ERROR_WANT_READ &&
1426 server_err != SSL_ERROR_WANT_WRITE &&
1427 server_err != SSL_ERROR_PENDING_TICKET) {
1428 fprintf(stderr, "Server error: %s\n", SSL_error_description(server_err));
1429 return false;
1430 }
1431
1432 if (client_ret == 1 && server_ret == 1) {
1433 break;
1434 }
1435 }
1436
1437 return true;
1438}
1439
1440static bool FlushNewSessionTickets(SSL *client, SSL *server) {
1441 // NewSessionTickets are deferred on the server to |SSL_write|, and clients do
1442 // not pick them up until |SSL_read|.
1443 for (;;) {
1444 int server_ret = SSL_write(server, nullptr, 0);
1445 int server_err = SSL_get_error(server, server_ret);
1446 // The server may either succeed (|server_ret| is zero) or block on write
1447 // (|server_ret| is -1 and |server_err| is |SSL_ERROR_WANT_WRITE|).
1448 if (server_ret > 0 ||
1449 (server_ret < 0 && server_err != SSL_ERROR_WANT_WRITE)) {
1450 fprintf(stderr, "Unexpected server result: %d %d\n", server_ret,
1451 server_err);
1452 return false;
1453 }
1454
1455 int client_ret = SSL_read(client, nullptr, 0);
1456 int client_err = SSL_get_error(client, client_ret);
1457 // The client must always block on read.
1458 if (client_ret != -1 || client_err != SSL_ERROR_WANT_READ) {
1459 fprintf(stderr, "Unexpected client result: %d %d\n", client_ret,
1460 client_err);
1461 return false;
1462 }
1463
1464 // The server flushed everything it had to write.
1465 if (server_ret == 0) {
1466 return true;
1467 }
1468 }
1469}
1470
1471// CreateClientAndServer creates a client and server |SSL| objects whose |BIO|s
1472// are paired with each other. It does not run the handshake. The caller is
1473// expected to configure the objects and drive the handshake as needed.
1474static bool CreateClientAndServer(bssl::UniquePtr<SSL> *out_client,
1475 bssl::UniquePtr<SSL> *out_server,
1476 SSL_CTX *client_ctx, SSL_CTX *server_ctx) {
1477 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
1478 if (!client || !server) {
1479 return false;
1480 }
1481 SSL_set_connect_state(client.get());
1482 SSL_set_accept_state(server.get());
1483
1484 BIO *bio1, *bio2;
1485 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1486 return false;
1487 }
1488 // SSL_set_bio takes ownership.
1489 SSL_set_bio(client.get(), bio1, bio1);
1490 SSL_set_bio(server.get(), bio2, bio2);
1491
1492 *out_client = std::move(client);
1493 *out_server = std::move(server);
1494 return true;
1495}
1496
1497struct ClientConfig {
1498 SSL_SESSION *session = nullptr;
1499 std::string servername;
1500 bool early_data = false;
1501};
1502
1503static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client,
1504 bssl::UniquePtr<SSL> *out_server,
1505 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1506 const ClientConfig &config = ClientConfig(),
1507 bool shed_handshake_config = true) {
1508 bssl::UniquePtr<SSL> client, server;
1509 if (!CreateClientAndServer(&client, &server, client_ctx, server_ctx)) {
1510 return false;
1511 }
1512 if (config.early_data) {
1513 SSL_set_early_data_enabled(client.get(), 1);
1514 }
1515 if (config.session) {
1516 SSL_set_session(client.get(), config.session);
1517 }
1518 if (!config.servername.empty() &&
1519 !SSL_set_tlsext_host_name(client.get(), config.servername.c_str())) {
1520 return false;
1521 }
1522
1523 SSL_set_shed_handshake_config(client.get(), shed_handshake_config);
1524 SSL_set_shed_handshake_config(server.get(), shed_handshake_config);
1525
1526 if (!CompleteHandshakes(client.get(), server.get())) {
1527 return false;
1528 }
1529
1530 *out_client = std::move(client);
1531 *out_server = std::move(server);
1532 return true;
1533}
1534
David Benjaminc79ae7a2017-08-29 16:09:44 -04001535// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
1536// before configuring as a server.
1537TEST(SSLTest, ClientCAList) {
1538 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1539 ASSERT_TRUE(ctx);
1540 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1541 ASSERT_TRUE(ssl);
1542
1543 bssl::UniquePtr<X509_NAME> name(X509_NAME_new());
1544 ASSERT_TRUE(name);
1545
1546 bssl::UniquePtr<X509_NAME> name_dup(X509_NAME_dup(name.get()));
1547 ASSERT_TRUE(name_dup);
1548
1549 bssl::UniquePtr<STACK_OF(X509_NAME)> stack(sk_X509_NAME_new_null());
1550 ASSERT_TRUE(stack);
David Benjamin2908dd12018-06-29 17:46:42 -04001551 ASSERT_TRUE(PushToStack(stack.get(), std::move(name_dup)));
David Benjaminc79ae7a2017-08-29 16:09:44 -04001552
1553 // |SSL_set_client_CA_list| takes ownership.
1554 SSL_set_client_CA_list(ssl.get(), stack.release());
1555
1556 STACK_OF(X509_NAME) *result = SSL_get_client_CA_list(ssl.get());
1557 ASSERT_TRUE(result);
1558 ASSERT_EQ(1u, sk_X509_NAME_num(result));
1559 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(result, 0), name.get()));
1560}
1561
1562TEST(SSLTest, AddClientCA) {
1563 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1564 ASSERT_TRUE(ctx);
1565 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1566 ASSERT_TRUE(ssl);
1567
1568 bssl::UniquePtr<X509> cert1 = GetTestCertificate();
1569 bssl::UniquePtr<X509> cert2 = GetChainTestCertificate();
1570 ASSERT_TRUE(cert1 && cert2);
1571 X509_NAME *name1 = X509_get_subject_name(cert1.get());
1572 X509_NAME *name2 = X509_get_subject_name(cert2.get());
1573
1574 EXPECT_EQ(0u, sk_X509_NAME_num(SSL_get_client_CA_list(ssl.get())));
1575
1576 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1577 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert2.get()));
1578
1579 STACK_OF(X509_NAME) *list = SSL_get_client_CA_list(ssl.get());
1580 ASSERT_EQ(2u, sk_X509_NAME_num(list));
1581 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1582 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1583
1584 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1585
1586 list = SSL_get_client_CA_list(ssl.get());
1587 ASSERT_EQ(3u, sk_X509_NAME_num(list));
1588 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1589 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1590 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 2), name1));
1591}
1592
David Benjamin24545c52021-06-07 16:05:07 -04001593struct ECHConfigParams {
1594 uint16_t version = TLSEXT_TYPE_encrypted_client_hello;
1595 uint16_t config_id = 1;
1596 std::string public_name = "example.com";
1597 const EVP_HPKE_KEY *key = nullptr;
1598 // kem_id, if zero, takes its value from |key|.
1599 uint16_t kem_id = 0;
1600 // public_key, if empty takes its value from |key|.
1601 std::vector<uint8_t> public_key;
1602 size_t max_name_len = 16;
1603 // cipher_suites is a list of code points which should contain pairs of KDF
1604 // and AEAD IDs.
1605 std::vector<uint16_t> cipher_suites = {EVP_HPKE_HKDF_SHA256,
1606 EVP_HPKE_AES_128_GCM};
1607 std::vector<uint8_t> extensions;
1608};
Daniel McArdle00e434d2021-02-18 11:47:18 -05001609
David Benjamin24545c52021-06-07 16:05:07 -04001610// MakeECHConfig serializes an ECHConfig from |params| and writes it to
1611// |*out|.
1612bool MakeECHConfig(std::vector<uint8_t> *out,
1613 const ECHConfigParams &params) {
1614 uint16_t kem_id = params.kem_id == 0
1615 ? EVP_HPKE_KEM_id(EVP_HPKE_KEY_kem(params.key))
1616 : params.kem_id;
1617 std::vector<uint8_t> public_key = params.public_key;
1618 if (public_key.empty()) {
1619 public_key.resize(EVP_HPKE_MAX_PUBLIC_KEY_LENGTH);
1620 size_t len;
1621 if (!EVP_HPKE_KEY_public_key(params.key, public_key.data(), &len,
1622 public_key.size())) {
1623 return false;
1624 }
1625 public_key.resize(len);
1626 }
Daniel McArdle00e434d2021-02-18 11:47:18 -05001627
Daniel McArdle00e434d2021-02-18 11:47:18 -05001628 bssl::ScopedCBB cbb;
1629 CBB contents, child;
Daniel McArdle00e434d2021-02-18 11:47:18 -05001630 if (!CBB_init(cbb.get(), 64) ||
David Benjamin24545c52021-06-07 16:05:07 -04001631 !CBB_add_u16(cbb.get(), params.version) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001632 !CBB_add_u16_length_prefixed(cbb.get(), &contents) ||
David Benjamin24545c52021-06-07 16:05:07 -04001633 !CBB_add_u8(&contents, params.config_id) ||
Steven Valdez94a63a52021-04-29 10:52:42 -04001634 !CBB_add_u16(&contents, kem_id) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001635 !CBB_add_u16_length_prefixed(&contents, &child) ||
1636 !CBB_add_bytes(&child, public_key.data(), public_key.size()) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001637 !CBB_add_u16_length_prefixed(&contents, &child)) {
1638 return false;
1639 }
David Benjamin24545c52021-06-07 16:05:07 -04001640 for (uint16_t cipher_suite : params.cipher_suites) {
Daniel McArdle00e434d2021-02-18 11:47:18 -05001641 if (!CBB_add_u16(&child, cipher_suite)) {
1642 return false;
1643 }
1644 }
David Benjamin24545c52021-06-07 16:05:07 -04001645 if (!CBB_add_u16(&contents, params.max_name_len) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001646 !CBB_add_u16_length_prefixed(&contents, &child) ||
David Benjamin24545c52021-06-07 16:05:07 -04001647 !CBB_add_bytes(
1648 &child, reinterpret_cast<const uint8_t *>(params.public_name.data()),
1649 params.public_name.size()) ||
Steven Valdez94a63a52021-04-29 10:52:42 -04001650 !CBB_add_u16_length_prefixed(&contents, &child) ||
David Benjamin24545c52021-06-07 16:05:07 -04001651 !CBB_add_bytes(&child, params.extensions.data(),
1652 params.extensions.size()) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001653 !CBB_flush(cbb.get())) {
1654 return false;
1655 }
1656
1657 out->assign(CBB_data(cbb.get()), CBB_data(cbb.get()) + CBB_len(cbb.get()));
1658 return true;
1659}
1660
David Benjamin83a49932021-05-20 15:57:09 -04001661static bssl::UniquePtr<SSL_ECH_KEYS> MakeTestECHKeys() {
1662 bssl::ScopedEVP_HPKE_KEY key;
1663 uint8_t *ech_config;
1664 size_t ech_config_len;
1665 if (!EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()) ||
1666 !SSL_marshal_ech_config(&ech_config, &ech_config_len,
1667 /*config_id=*/1, key.get(), "public.example",
1668 16)) {
1669 return nullptr;
1670 }
1671 bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
1672
1673 // Install a non-retry config.
1674 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1675 if (!keys || !SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config,
1676 ech_config_len, key.get())) {
1677 return nullptr;
1678 }
1679 return keys;
1680}
1681
1682static bool InstallECHConfigList(SSL *client, const SSL_ECH_KEYS *keys) {
1683 uint8_t *ech_config_list;
1684 size_t ech_config_list_len;
1685 if (!SSL_ECH_KEYS_marshal_retry_configs(keys, &ech_config_list,
1686 &ech_config_list_len)) {
1687 return false;
1688 }
1689 bssl::UniquePtr<uint8_t> free_ech_config_list(ech_config_list);
1690 return SSL_set1_ech_config_list(client, ech_config_list, ech_config_list_len);
1691}
1692
David Benjamin24545c52021-06-07 16:05:07 -04001693// Test that |SSL_marshal_ech_config| and |SSL_ECH_KEYS_marshal_retry_configs|
1694// output values as expected.
1695TEST(SSLTest, MarshalECHConfig) {
1696 static const uint8_t kPrivateKey[X25519_PRIVATE_KEY_LEN] = {
1697 0xbc, 0xb5, 0x51, 0x29, 0x31, 0x10, 0x30, 0xc9, 0xed, 0x26, 0xde,
1698 0xd4, 0xb3, 0xdf, 0x3a, 0xce, 0x06, 0x8a, 0xee, 0x17, 0xab, 0xce,
1699 0xd7, 0xdb, 0xf3, 0x11, 0xe5, 0xa8, 0xf3, 0xb1, 0x8e, 0x24};
1700 bssl::ScopedEVP_HPKE_KEY key;
1701 ASSERT_TRUE(EVP_HPKE_KEY_init(key.get(), EVP_hpke_x25519_hkdf_sha256(),
1702 kPrivateKey, sizeof(kPrivateKey)));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001703
David Benjamin24545c52021-06-07 16:05:07 -04001704 static const uint8_t kECHConfig[] = {
1705 // version
1706 0xfe, 0x0a,
1707 // length
1708 0x00, 0x43,
1709 // contents.config_id
1710 0x01,
1711 // contents.kem_id
1712 0x00, 0x20,
1713 // contents.public_key
1714 0x00, 0x20, 0xa6, 0x9a, 0x41, 0x48, 0x5d, 0x32, 0x96, 0xa4, 0xe0, 0xc3,
1715 0x6a, 0xee, 0xf6, 0x63, 0x0f, 0x59, 0x32, 0x6f, 0xdc, 0xff, 0x81, 0x29,
1716 0x59, 0xa5, 0x85, 0xd3, 0x9b, 0x3b, 0xde, 0x98, 0x55, 0x5c,
1717 // contents.cipher_suites
1718 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x03,
1719 // contents.maximum_name_length
1720 0x00, 0x10,
1721 // contents.public_name
1722 0x00, 0x0e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2e, 0x65, 0x78, 0x61,
1723 0x6d, 0x70, 0x6c, 0x65,
1724 // contents.extensions
1725 0x00, 0x00};
1726 uint8_t *ech_config;
1727 size_t ech_config_len;
1728 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config, &ech_config_len,
1729 /*config_id=*/1, key.get(),
1730 "public.example", 16));
1731 bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
1732 EXPECT_EQ(Bytes(kECHConfig), Bytes(ech_config, ech_config_len));
1733
1734 // Generate a second ECHConfig.
1735 bssl::ScopedEVP_HPKE_KEY key2;
1736 ASSERT_TRUE(EVP_HPKE_KEY_generate(key2.get(), EVP_hpke_x25519_hkdf_sha256()));
1737 uint8_t *ech_config2;
1738 size_t ech_config2_len;
1739 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config2, &ech_config2_len,
1740 /*config_id=*/2, key2.get(),
1741 "public.example", 16));
1742 bssl::UniquePtr<uint8_t> free_ech_config2(ech_config2);
1743
1744 // Install both ECHConfigs in an |SSL_ECH_KEYS|.
David Benjaminc3b373b2021-06-06 13:04:26 -04001745 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1746 ASSERT_TRUE(keys);
David Benjamin24545c52021-06-07 16:05:07 -04001747 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config,
1748 ech_config_len, key.get()));
1749 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config2,
1750 ech_config2_len, key2.get()));
1751
1752 // The ECHConfigList should be correctly serialized.
1753 uint8_t *ech_config_list;
1754 size_t ech_config_list_len;
1755 ASSERT_TRUE(SSL_ECH_KEYS_marshal_retry_configs(keys.get(), &ech_config_list,
1756 &ech_config_list_len));
1757 bssl::UniquePtr<uint8_t> free_ech_config_list(ech_config_list);
1758
1759 // ECHConfigList is just the concatenation with a length prefix.
1760 size_t len = ech_config_len + ech_config2_len;
1761 std::vector<uint8_t> expected = {uint8_t(len >> 8), uint8_t(len)};
1762 expected.insert(expected.end(), ech_config, ech_config + ech_config_len);
1763 expected.insert(expected.end(), ech_config2, ech_config2 + ech_config2_len);
1764 EXPECT_EQ(Bytes(expected), Bytes(ech_config_list, ech_config_list_len));
David Benjamin24545c52021-06-07 16:05:07 -04001765}
1766
1767TEST(SSLTest, ECHHasDuplicateConfigID) {
1768 const struct {
1769 std::vector<uint8_t> ids;
1770 bool has_duplicate;
1771 } kTests[] = {
1772 {{}, false},
1773 {{1}, false},
1774 {{1, 2, 3, 255}, false},
1775 {{1, 2, 3, 1}, true},
1776 };
1777 for (const auto &test : kTests) {
1778 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1779 ASSERT_TRUE(keys);
1780 for (const uint8_t id : test.ids) {
1781 bssl::ScopedEVP_HPKE_KEY key;
1782 ASSERT_TRUE(
1783 EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()));
1784 uint8_t *ech_config;
1785 size_t ech_config_len;
1786 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config, &ech_config_len, id,
1787 key.get(), "public.example", 16));
1788 bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
1789 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1790 ech_config, ech_config_len, key.get()));
1791 }
1792
1793 EXPECT_EQ(test.has_duplicate ? 1 : 0,
1794 SSL_ECH_KEYS_has_duplicate_config_id(keys.get()));
1795 }
1796}
1797
1798// Test that |SSL_ECH_KEYS_add| checks consistency between the public and
1799// private key.
1800TEST(SSLTest, ECHKeyConsistency) {
1801 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1802 ASSERT_TRUE(keys);
1803 bssl::ScopedEVP_HPKE_KEY key;
1804 ASSERT_TRUE(EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()));
1805 uint8_t public_key[EVP_HPKE_MAX_PUBLIC_KEY_LENGTH];
1806 size_t public_key_len;
1807 ASSERT_TRUE(EVP_HPKE_KEY_public_key(key.get(), public_key, &public_key_len,
1808 sizeof(public_key)));
1809
1810 // Adding an ECHConfig with the matching public key succeeds.
1811 ECHConfigParams params;
1812 params.key = key.get();
1813 std::vector<uint8_t> ech_config;
1814 ASSERT_TRUE(MakeECHConfig(&ech_config, params));
1815 EXPECT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1816 ech_config.data(), ech_config.size(),
1817 key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001818
David Benjaminc890ae52021-06-06 13:32:29 -04001819 // Adding an ECHConfig with the wrong public key is an error.
1820 bssl::ScopedEVP_HPKE_KEY wrong_key;
1821 ASSERT_TRUE(
1822 EVP_HPKE_KEY_generate(wrong_key.get(), EVP_hpke_x25519_hkdf_sha256()));
David Benjamin24545c52021-06-07 16:05:07 -04001823 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1824 ech_config.data(), ech_config.size(),
1825 wrong_key.get()));
1826
1827 // Adding an ECHConfig with a truncated public key is an error.
1828 ECHConfigParams truncated;
1829 truncated.key = key.get();
1830 truncated.public_key.assign(public_key, public_key + public_key_len - 1);
1831 ASSERT_TRUE(MakeECHConfig(&ech_config, truncated));
1832 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1833 ech_config.data(), ech_config.size(), key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001834
David Benjaminc890ae52021-06-06 13:32:29 -04001835 // Adding an ECHConfig with the right public key, but wrong KEM ID, is an
1836 // error.
David Benjamin24545c52021-06-07 16:05:07 -04001837 ECHConfigParams wrong_kem;
1838 wrong_kem.key = key.get();
1839 wrong_kem.kem_id = 0x0010; // DHKEM(P-256, HKDF-SHA256)
1840 ASSERT_TRUE(MakeECHConfig(&ech_config, wrong_kem));
David Benjaminc890ae52021-06-06 13:32:29 -04001841 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1842 ech_config.data(), ech_config.size(),
1843 key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001844}
1845
David Benjaminc3b373b2021-06-06 13:04:26 -04001846// Test that |SSL_CTX_set1_ech_keys| fails when the config list
Daniel McArdle00e434d2021-02-18 11:47:18 -05001847// has no retry configs.
1848TEST(SSLTest, ECHServerConfigsWithoutRetryConfigs) {
David Benjamin24545c52021-06-07 16:05:07 -04001849 bssl::ScopedEVP_HPKE_KEY key;
1850 ASSERT_TRUE(EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()));
1851 uint8_t *ech_config;
1852 size_t ech_config_len;
1853 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config, &ech_config_len,
1854 /*config_id=*/1, key.get(),
1855 "public.example", 16));
1856 bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
Daniel McArdle00e434d2021-02-18 11:47:18 -05001857
David Benjamin24545c52021-06-07 16:05:07 -04001858 // Install a non-retry config.
David Benjaminc3b373b2021-06-06 13:04:26 -04001859 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1860 ASSERT_TRUE(keys);
David Benjamin24545c52021-06-07 16:05:07 -04001861 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/0, ech_config,
1862 ech_config_len, key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001863
David Benjamin24545c52021-06-07 16:05:07 -04001864 // |keys| has no retry configs.
1865 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1866 ASSERT_TRUE(ctx);
1867 EXPECT_FALSE(SSL_CTX_set1_ech_keys(ctx.get(), keys.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001868
1869 // Add the same ECHConfig to the list, but this time mark it as a retry
1870 // config.
David Benjamin24545c52021-06-07 16:05:07 -04001871 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config,
1872 ech_config_len, key.get()));
1873 EXPECT_TRUE(SSL_CTX_set1_ech_keys(ctx.get(), keys.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001874}
1875
1876// Test that the server APIs reject ECHConfigs with unsupported features.
1877TEST(SSLTest, UnsupportedECHConfig) {
David Benjaminc3b373b2021-06-06 13:04:26 -04001878 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1879 ASSERT_TRUE(keys);
David Benjaminc890ae52021-06-06 13:32:29 -04001880 bssl::ScopedEVP_HPKE_KEY key;
David Benjamin24545c52021-06-07 16:05:07 -04001881 ASSERT_TRUE(EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001882
1883 // Unsupported versions are rejected.
David Benjamin24545c52021-06-07 16:05:07 -04001884 ECHConfigParams unsupported_version;
1885 unsupported_version.version = 0xffff;
1886 unsupported_version.key = key.get();
Daniel McArdle00e434d2021-02-18 11:47:18 -05001887 std::vector<uint8_t> ech_config;
David Benjamin24545c52021-06-07 16:05:07 -04001888 ASSERT_TRUE(MakeECHConfig(&ech_config, unsupported_version));
David Benjaminc3b373b2021-06-06 13:04:26 -04001889 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1890 ech_config.data(), ech_config.size(),
David Benjaminc890ae52021-06-06 13:32:29 -04001891 key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001892
David Benjamin24545c52021-06-07 16:05:07 -04001893 // Unsupported cipher suites are rejected. (We only support HKDF-SHA256.)
1894 ECHConfigParams unsupported_kdf;
1895 unsupported_kdf.key = key.get();
1896 unsupported_kdf.cipher_suites = {0x002 /* HKDF-SHA384 */,
1897 EVP_HPKE_AES_128_GCM};
1898 ASSERT_TRUE(MakeECHConfig(&ech_config, unsupported_kdf));
1899 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1900 ech_config.data(), ech_config.size(),
1901 key.get()));
1902 ECHConfigParams unsupported_aead;
1903 unsupported_aead.key = key.get();
1904 unsupported_aead.cipher_suites = {EVP_HPKE_HKDF_SHA256, 0xffff};
1905 ASSERT_TRUE(MakeECHConfig(&ech_config, unsupported_aead));
1906 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1907 ech_config.data(), ech_config.size(),
1908 key.get()));
1909
1910
Daniel McArdle00e434d2021-02-18 11:47:18 -05001911 // Unsupported extensions are rejected.
David Benjamin24545c52021-06-07 16:05:07 -04001912 ECHConfigParams extensions;
1913 extensions.key = key.get();
1914 extensions.extensions = {0x00, 0x01, 0x00, 0x00};
1915 ASSERT_TRUE(MakeECHConfig(&ech_config, extensions));
David Benjaminc3b373b2021-06-06 13:04:26 -04001916 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1917 ech_config.data(), ech_config.size(),
David Benjaminc890ae52021-06-06 13:32:29 -04001918 key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001919}
1920
David Benjamin83a49932021-05-20 15:57:09 -04001921// Test that |SSL_get_client_random| reports the correct value on both client
1922// and server in ECH. The client sends two different random values. When ECH is
1923// accepted, we should report the inner one.
1924TEST(SSLTest, ECHClientRandomsMatch) {
1925 bssl::UniquePtr<SSL_CTX> server_ctx =
1926 CreateContextWithTestCertificate(TLS_method());
1927 bssl::UniquePtr<SSL_ECH_KEYS> keys = MakeTestECHKeys();
1928 ASSERT_TRUE(keys);
1929 ASSERT_TRUE(SSL_CTX_set1_ech_keys(server_ctx.get(), keys.get()));
1930
1931 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1932 ASSERT_TRUE(client_ctx);
1933 bssl::UniquePtr<SSL> client, server;
1934 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
1935 server_ctx.get()));
1936 ASSERT_TRUE(InstallECHConfigList(client.get(), keys.get()));
1937 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
1938
1939 EXPECT_TRUE(SSL_ech_accepted(client.get()));
1940 EXPECT_TRUE(SSL_ech_accepted(server.get()));
1941
1942 // An ECH server will fairly naturally record the inner ClientHello random,
1943 // but an ECH client may forget to update the random once ClientHelloInner is
1944 // selected.
1945 uint8_t client_random1[SSL3_RANDOM_SIZE];
1946 uint8_t client_random2[SSL3_RANDOM_SIZE];
1947 ASSERT_EQ(sizeof(client_random1),
1948 SSL_get_client_random(client.get(), client_random1,
1949 sizeof(client_random1)));
1950 ASSERT_EQ(sizeof(client_random2),
1951 SSL_get_client_random(server.get(), client_random2,
1952 sizeof(client_random2)));
1953 EXPECT_EQ(Bytes(client_random1), Bytes(client_random2));
1954}
1955
1956// GetECHLength sets |*out_client_hello_len| and |*out_ech_len| to the lengths
1957// of the ClientHello and ECH extension, respectively, when a client created
1958// from |ctx| constructs a ClientHello with name |name| and an ECHConfig with
1959// maximum name length |max_name_len|.
1960static bool GetECHLength(SSL_CTX *ctx, size_t *out_client_hello_len,
1961 size_t *out_ech_len, size_t max_name_len,
1962 const char *name) {
1963 bssl::ScopedEVP_HPKE_KEY key;
1964 uint8_t *ech_config;
1965 size_t ech_config_len;
1966 if (!EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()) ||
1967 !SSL_marshal_ech_config(&ech_config, &ech_config_len,
1968 /*config_id=*/1, key.get(), "public.example",
1969 max_name_len)) {
1970 return false;
1971 }
1972 bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
1973
1974 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1975 if (!keys || !SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config,
1976 ech_config_len, key.get())) {
1977 return false;
1978 }
1979
1980 bssl::UniquePtr<SSL> ssl(SSL_new(ctx));
1981 if (!ssl || !InstallECHConfigList(ssl.get(), keys.get()) ||
1982 (name != nullptr && !SSL_set_tlsext_host_name(ssl.get(), name))) {
1983 return false;
1984 }
1985 SSL_set_connect_state(ssl.get());
1986
1987 std::vector<uint8_t> client_hello;
1988 SSL_CLIENT_HELLO parsed;
1989 const uint8_t *unused;
1990 if (!GetClientHello(ssl.get(), &client_hello) ||
1991 !ssl_client_hello_init(
1992 ssl.get(), &parsed,
1993 // Skip record and handshake headers. This assumes the ClientHello
1994 // fits in one record.
1995 MakeConstSpan(client_hello)
1996 .subspan(SSL3_RT_HEADER_LENGTH + SSL3_HM_HEADER_LENGTH)) ||
1997 !SSL_early_callback_ctx_extension_get(
1998 &parsed, TLSEXT_TYPE_encrypted_client_hello, &unused, out_ech_len)) {
1999 return false;
2000 }
2001 *out_client_hello_len = client_hello.size();
2002 return true;
2003}
2004
2005TEST(SSLTest, ECHPadding) {
2006 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2007 ASSERT_TRUE(ctx);
2008
2009 // Sample lengths with max_name_len = 128 as baseline.
2010 size_t client_hello_len_baseline, ech_len_baseline;
2011 ASSERT_TRUE(GetECHLength(ctx.get(), &client_hello_len_baseline,
2012 &ech_len_baseline, 128, "example.com"));
2013
2014 // Check that all name lengths under the server's maximum look the same.
2015 for (size_t name_len : {1, 2, 32, 64, 127, 128}) {
2016 SCOPED_TRACE(name_len);
2017 size_t client_hello_len, ech_len;
2018 ASSERT_TRUE(GetECHLength(ctx.get(), &client_hello_len, &ech_len, 128,
2019 std::string(name_len, 'a').c_str()));
2020 EXPECT_EQ(client_hello_len, client_hello_len_baseline);
2021 EXPECT_EQ(ech_len, ech_len_baseline);
2022 }
2023
2024 // When sending no SNI, we must still pad as if we are sending one.
2025 size_t client_hello_len, ech_len;
2026 ASSERT_TRUE(
2027 GetECHLength(ctx.get(), &client_hello_len, &ech_len, 128, nullptr));
2028 EXPECT_EQ(client_hello_len, client_hello_len_baseline);
2029 EXPECT_EQ(ech_len, ech_len_baseline);
2030
2031 size_t client_hello_len_129, ech_len_129;
2032 ASSERT_TRUE(GetECHLength(ctx.get(), &client_hello_len_129, &ech_len_129, 128,
2033 std::string(129, 'a').c_str()));
2034 // The padding calculation should not pad beyond the maximum.
2035 EXPECT_GT(ech_len_129, ech_len_baseline);
2036
2037 // If the SNI exceeds the maximum name length, we apply some generic padding,
2038 // so close name lengths still match.
2039 for (size_t name_len : {129, 130, 131, 132}) {
2040 SCOPED_TRACE(name_len);
2041 ASSERT_TRUE(GetECHLength(ctx.get(), &client_hello_len, &ech_len, 128,
2042 std::string(name_len, 'a').c_str()));
2043 EXPECT_EQ(client_hello_len, client_hello_len_129);
2044 EXPECT_EQ(ech_len, ech_len_129);
2045 }
2046}
2047
2048#if defined(OPENSSL_THREADS)
2049// Test that the server ECH config can be swapped out while the |SSL_CTX| is
2050// in use on other threads. This test is intended to be run with TSan.
2051TEST(SSLTest, ECHThreads) {
2052 // Generate a pair of ECHConfigs.
2053 bssl::ScopedEVP_HPKE_KEY key1;
2054 ASSERT_TRUE(EVP_HPKE_KEY_generate(key1.get(), EVP_hpke_x25519_hkdf_sha256()));
2055 uint8_t *ech_config1;
2056 size_t ech_config1_len;
2057 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config1, &ech_config1_len,
2058 /*config_id=*/1, key1.get(),
2059 "public.example", 16));
2060 bssl::UniquePtr<uint8_t> free_ech_config1(ech_config1);
2061 bssl::ScopedEVP_HPKE_KEY key2;
2062 ASSERT_TRUE(EVP_HPKE_KEY_generate(key2.get(), EVP_hpke_x25519_hkdf_sha256()));
2063 uint8_t *ech_config2;
2064 size_t ech_config2_len;
2065 ASSERT_TRUE(SSL_marshal_ech_config(&ech_config2, &ech_config2_len,
2066 /*config_id=*/2, key2.get(),
2067 "public.example", 16));
2068 bssl::UniquePtr<uint8_t> free_ech_config2(ech_config2);
2069
2070 // |keys1| contains the first config. |keys12| contains both.
2071 bssl::UniquePtr<SSL_ECH_KEYS> keys1(SSL_ECH_KEYS_new());
2072 ASSERT_TRUE(keys1);
2073 ASSERT_TRUE(SSL_ECH_KEYS_add(keys1.get(), /*is_retry_config=*/1, ech_config1,
2074 ech_config1_len, key1.get()));
2075 bssl::UniquePtr<SSL_ECH_KEYS> keys12(SSL_ECH_KEYS_new());
2076 ASSERT_TRUE(keys12);
2077 ASSERT_TRUE(SSL_ECH_KEYS_add(keys12.get(), /*is_retry_config=*/1, ech_config2,
2078 ech_config2_len, key2.get()));
2079 ASSERT_TRUE(SSL_ECH_KEYS_add(keys12.get(), /*is_retry_config=*/0, ech_config1,
2080 ech_config1_len, key1.get()));
2081
2082 bssl::UniquePtr<SSL_CTX> server_ctx =
2083 CreateContextWithTestCertificate(TLS_method());
2084 ASSERT_TRUE(SSL_CTX_set1_ech_keys(server_ctx.get(), keys1.get()));
2085
2086 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
2087 ASSERT_TRUE(client_ctx);
2088 bssl::UniquePtr<SSL> client, server;
2089 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
2090 server_ctx.get()));
2091 ASSERT_TRUE(InstallECHConfigList(client.get(), keys1.get()));
2092
2093 // In parallel, complete the connection and reconfigure the ECHConfig. Note
2094 // |keys12| supports all the keys in |keys1|, so the handshake should complete
2095 // the same whichever the server uses.
2096 std::vector<std::thread> threads;
2097 threads.emplace_back([&] {
2098 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
2099 EXPECT_TRUE(SSL_ech_accepted(client.get()));
2100 EXPECT_TRUE(SSL_ech_accepted(server.get()));
2101 });
2102 threads.emplace_back([&] {
2103 EXPECT_TRUE(SSL_CTX_set1_ech_keys(server_ctx.get(), keys12.get()));
2104 });
2105 for (auto &thread : threads) {
2106 thread.join();
2107 }
2108}
2109#endif // OPENSSL_THREADS
2110
David Benjaminc79ae7a2017-08-29 16:09:44 -04002111static void AppendSession(SSL_SESSION *session, void *arg) {
2112 std::vector<SSL_SESSION*> *out =
2113 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
2114 out->push_back(session);
2115}
2116
2117// CacheEquals returns true if |ctx|'s session cache consists of |expected|, in
2118// order.
2119static bool CacheEquals(SSL_CTX *ctx,
2120 const std::vector<SSL_SESSION*> &expected) {
2121 // Check the linked list.
2122 SSL_SESSION *ptr = ctx->session_cache_head;
2123 for (SSL_SESSION *session : expected) {
2124 if (ptr != session) {
2125 return false;
2126 }
2127 // TODO(davidben): This is an absurd way to denote the end of the list.
2128 if (ptr->next ==
2129 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
2130 ptr = nullptr;
2131 } else {
2132 ptr = ptr->next;
2133 }
2134 }
2135 if (ptr != nullptr) {
2136 return false;
2137 }
2138
2139 // Check the hash table.
2140 std::vector<SSL_SESSION*> actual, expected_copy;
David Benjamin9eaa3bd2017-09-27 17:03:54 -04002141 lh_SSL_SESSION_doall_arg(ctx->sessions, AppendSession, &actual);
David Benjaminc79ae7a2017-08-29 16:09:44 -04002142 expected_copy = expected;
2143
2144 std::sort(actual.begin(), actual.end());
2145 std::sort(expected_copy.begin(), expected_copy.end());
2146
2147 return actual == expected_copy;
2148}
2149
2150static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
2151 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
2152 if (!ssl_ctx) {
2153 return nullptr;
2154 }
2155 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new(ssl_ctx.get()));
2156 if (!ret) {
2157 return nullptr;
2158 }
2159
David Benjaminaaef8332018-06-29 16:45:49 -04002160 uint8_t id[SSL3_SSL_SESSION_ID_LENGTH] = {0};
2161 OPENSSL_memcpy(id, &number, sizeof(number));
2162 if (!SSL_SESSION_set1_id(ret.get(), id, sizeof(id))) {
2163 return nullptr;
2164 }
David Benjaminc79ae7a2017-08-29 16:09:44 -04002165 return ret;
2166}
2167
2168// Test that the internal session cache behaves as expected.
2169TEST(SSLTest, InternalSessionCache) {
2170 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2171 ASSERT_TRUE(ctx);
2172
2173 // Prepare 10 test sessions.
2174 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
2175 for (int i = 0; i < 10; i++) {
2176 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
2177 ASSERT_TRUE(session);
2178 sessions.push_back(std::move(session));
2179 }
2180
2181 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
2182
2183 // Insert all the test sessions.
2184 for (const auto &session : sessions) {
2185 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), session.get()));
2186 }
2187
2188 // Only the last five should be in the list.
2189 ASSERT_TRUE(CacheEquals(
2190 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
2191 sessions[6].get(), sessions[5].get()}));
2192
2193 // Inserting an element already in the cache should fail and leave the cache
2194 // unchanged.
2195 ASSERT_FALSE(SSL_CTX_add_session(ctx.get(), sessions[7].get()));
2196 ASSERT_TRUE(CacheEquals(
2197 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
2198 sessions[6].get(), sessions[5].get()}));
2199
2200 // Although collisions should be impossible (256-bit session IDs), the cache
2201 // must handle them gracefully.
2202 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
2203 ASSERT_TRUE(collision);
2204 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), collision.get()));
2205 ASSERT_TRUE(CacheEquals(
2206 ctx.get(), {collision.get(), sessions[9].get(), sessions[8].get(),
2207 sessions[6].get(), sessions[5].get()}));
2208
2209 // Removing sessions behaves correctly.
2210 ASSERT_TRUE(SSL_CTX_remove_session(ctx.get(), sessions[6].get()));
2211 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
2212 sessions[8].get(), sessions[5].get()}));
2213
2214 // Removing sessions requires an exact match.
2215 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[0].get()));
2216 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[7].get()));
2217
2218 // The cache remains unchanged.
2219 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
2220 sessions[8].get(), sessions[5].get()}));
2221}
2222
2223static uint16_t EpochFromSequence(uint64_t seq) {
2224 return static_cast<uint16_t>(seq >> 48);
2225}
2226
David Benjamin71dfad42017-07-16 17:27:39 -04002227static const uint8_t kTestName[] = {
2228 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
2229 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
2230 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
2231 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
2232 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
2233 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64,
2234};
2235
David Benjaminc11ea9422017-08-29 16:33:21 -04002236// SSLVersionTest executes its test cases under all available protocol versions.
2237// Test cases call |Connect| to create a connection using context objects with
2238// the protocol version fixed to the current version under test.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002239class SSLVersionTest : public ::testing::TestWithParam<VersionParam> {
2240 protected:
2241 SSLVersionTest() : cert_(GetTestCertificate()), key_(GetTestKey()) {}
2242
2243 void SetUp() { ResetContexts(); }
2244
2245 bssl::UniquePtr<SSL_CTX> CreateContext() const {
2246 const SSL_METHOD *method = is_dtls() ? DTLS_method() : TLS_method();
2247 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
2248 if (!ctx || !SSL_CTX_set_min_proto_version(ctx.get(), version()) ||
2249 !SSL_CTX_set_max_proto_version(ctx.get(), version())) {
2250 return nullptr;
2251 }
2252 return ctx;
David Benjamin0fef3052016-11-18 15:11:10 +09002253 }
David Benjamin686bb192016-05-10 15:15:41 -04002254
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002255 void ResetContexts() {
2256 ASSERT_TRUE(cert_);
2257 ASSERT_TRUE(key_);
2258 client_ctx_ = CreateContext();
2259 ASSERT_TRUE(client_ctx_);
2260 server_ctx_ = CreateContext();
2261 ASSERT_TRUE(server_ctx_);
2262 // Set up a server cert. Client certs can be set up explicitly.
2263 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09002264 }
David Benjamin686bb192016-05-10 15:15:41 -04002265
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002266 bool UseCertAndKey(SSL_CTX *ctx) const {
2267 return SSL_CTX_use_certificate(ctx, cert_.get()) &&
2268 SSL_CTX_use_PrivateKey(ctx, key_.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002269 }
David Benjamin686bb192016-05-10 15:15:41 -04002270
David Benjamina8614602017-09-06 15:40:19 -04002271 bool Connect(const ClientConfig &config = ClientConfig()) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002272 return ConnectClientAndServer(&client_, &server_, client_ctx_.get(),
David Benjamin9b2cdb72021-04-01 23:21:53 -04002273 server_ctx_.get(), config,
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07002274 shed_handshake_config_);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002275 }
2276
2277 uint16_t version() const { return GetParam().version; }
2278
2279 bool is_dtls() const {
2280 return GetParam().ssl_method == VersionParam::is_dtls;
2281 }
2282
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07002283 bool shed_handshake_config_ = true;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002284 bssl::UniquePtr<SSL> client_, server_;
2285 bssl::UniquePtr<SSL_CTX> server_ctx_, client_ctx_;
2286 bssl::UniquePtr<X509> cert_;
2287 bssl::UniquePtr<EVP_PKEY> key_;
2288};
2289
David Benjaminbe7006a2019-04-09 18:05:02 -05002290INSTANTIATE_TEST_SUITE_P(WithVersion, SSLVersionTest,
2291 testing::ValuesIn(kAllVersions),
2292 [](const testing::TestParamInfo<VersionParam> &i) {
2293 return i.param.name;
2294 });
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002295
2296TEST_P(SSLVersionTest, SequenceNumber) {
2297 ASSERT_TRUE(Connect());
2298
David Benjamin0fef3052016-11-18 15:11:10 +09002299 // Drain any post-handshake messages to ensure there are no unread records
2300 // on either end.
Steven Valdez777a2392019-02-21 11:30:47 -05002301 ASSERT_TRUE(FlushNewSessionTickets(client_.get(), server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05002302
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002303 uint64_t client_read_seq = SSL_get_read_sequence(client_.get());
2304 uint64_t client_write_seq = SSL_get_write_sequence(client_.get());
2305 uint64_t server_read_seq = SSL_get_read_sequence(server_.get());
2306 uint64_t server_write_seq = SSL_get_write_sequence(server_.get());
Steven Valdez2c62fe92016-10-14 12:08:12 -04002307
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002308 if (is_dtls()) {
David Benjamin0fef3052016-11-18 15:11:10 +09002309 // Both client and server must be at epoch 1.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002310 EXPECT_EQ(EpochFromSequence(client_read_seq), 1);
2311 EXPECT_EQ(EpochFromSequence(client_write_seq), 1);
2312 EXPECT_EQ(EpochFromSequence(server_read_seq), 1);
2313 EXPECT_EQ(EpochFromSequence(server_write_seq), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09002314
2315 // The next record to be written should exceed the largest received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002316 EXPECT_GT(client_write_seq, server_read_seq);
2317 EXPECT_GT(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09002318 } else {
2319 // The next record to be written should equal the next to be received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002320 EXPECT_EQ(client_write_seq, server_read_seq);
2321 EXPECT_EQ(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09002322 }
2323
2324 // Send a record from client to server.
Steven Valdez777a2392019-02-21 11:30:47 -05002325 uint8_t byte = 0;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002326 EXPECT_EQ(SSL_write(client_.get(), &byte, 1), 1);
2327 EXPECT_EQ(SSL_read(server_.get(), &byte, 1), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09002328
2329 // The client write and server read sequence numbers should have
2330 // incremented.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002331 EXPECT_EQ(client_write_seq + 1, SSL_get_write_sequence(client_.get()));
2332 EXPECT_EQ(server_read_seq + 1, SSL_get_read_sequence(server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05002333}
2334
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002335TEST_P(SSLVersionTest, OneSidedShutdown) {
David Benjamin68f37b72016-11-18 15:14:42 +09002336 // SSL_shutdown is a no-op in DTLS.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002337 if (is_dtls()) {
2338 return;
David Benjamin686bb192016-05-10 15:15:41 -04002339 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002340 ASSERT_TRUE(Connect());
David Benjamin686bb192016-05-10 15:15:41 -04002341
2342 // Shut down half the connection. SSL_shutdown will return 0 to signal only
2343 // one side has shut down.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002344 ASSERT_EQ(SSL_shutdown(client_.get()), 0);
David Benjamin686bb192016-05-10 15:15:41 -04002345
2346 // Reading from the server should consume the EOF.
2347 uint8_t byte;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002348 ASSERT_EQ(SSL_read(server_.get(), &byte, 1), 0);
2349 ASSERT_EQ(SSL_get_error(server_.get(), 0), SSL_ERROR_ZERO_RETURN);
David Benjamin686bb192016-05-10 15:15:41 -04002350
2351 // However, the server may continue to write data and then shut down the
2352 // connection.
2353 byte = 42;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002354 ASSERT_EQ(SSL_write(server_.get(), &byte, 1), 1);
2355 ASSERT_EQ(SSL_read(client_.get(), &byte, 1), 1);
2356 ASSERT_EQ(byte, 42);
David Benjamin686bb192016-05-10 15:15:41 -04002357
2358 // The server may then shutdown the connection.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002359 EXPECT_EQ(SSL_shutdown(server_.get()), 1);
2360 EXPECT_EQ(SSL_shutdown(client_.get()), 1);
David Benjamin686bb192016-05-10 15:15:41 -04002361}
David Benjamin68f37b72016-11-18 15:14:42 +09002362
David Benjaminf0d8e222017-02-04 10:58:26 -05002363TEST(SSLTest, SessionDuplication) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002364 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04002365 bssl::UniquePtr<SSL_CTX> server_ctx =
2366 CreateContextWithTestCertificate(TLS_method());
David Benjaminf0d8e222017-02-04 10:58:26 -05002367 ASSERT_TRUE(client_ctx);
2368 ASSERT_TRUE(server_ctx);
Steven Valdez87eab492016-06-27 16:34:59 -04002369
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002370 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05002371 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04002372 server_ctx.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04002373
2374 SSL_SESSION *session0 = SSL_get_session(client.get());
David Benjamin31b0c9b2017-07-20 14:49:15 -04002375 bssl::UniquePtr<SSL_SESSION> session1 =
2376 bssl::SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL);
David Benjaminf0d8e222017-02-04 10:58:26 -05002377 ASSERT_TRUE(session1);
David Benjamin4501bd52016-08-01 13:39:41 -04002378
David Benjamina3a71e92018-06-29 13:24:45 -04002379 session1->not_resumable = false;
Steven Valdez84b5c002016-08-25 16:30:58 -04002380
Steven Valdez87eab492016-06-27 16:34:59 -04002381 uint8_t *s0_bytes, *s1_bytes;
2382 size_t s0_len, s1_len;
2383
David Benjaminf0d8e222017-02-04 10:58:26 -05002384 ASSERT_TRUE(SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002385 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04002386
David Benjaminf0d8e222017-02-04 10:58:26 -05002387 ASSERT_TRUE(SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002388 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04002389
David Benjamin7d7554b2017-02-04 11:48:59 -05002390 EXPECT_EQ(Bytes(s0_bytes, s0_len), Bytes(s1_bytes, s1_len));
Steven Valdez87eab492016-06-27 16:34:59 -04002391}
David Benjamin686bb192016-05-10 15:15:41 -04002392
David Benjaminf0d8e222017-02-04 10:58:26 -05002393static void ExpectFDs(const SSL *ssl, int rfd, int wfd) {
David Benjaminca743582017-06-15 17:51:35 -04002394 EXPECT_EQ(rfd, SSL_get_fd(ssl));
David Benjaminf0d8e222017-02-04 10:58:26 -05002395 EXPECT_EQ(rfd, SSL_get_rfd(ssl));
2396 EXPECT_EQ(wfd, SSL_get_wfd(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04002397
2398 // The wrapper BIOs are always equal when fds are equal, even if set
2399 // individually.
David Benjaminf0d8e222017-02-04 10:58:26 -05002400 if (rfd == wfd) {
2401 EXPECT_EQ(SSL_get_rbio(ssl), SSL_get_wbio(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04002402 }
David Benjamin5c0fb882016-06-14 14:03:51 -04002403}
2404
David Benjaminf0d8e222017-02-04 10:58:26 -05002405TEST(SSLTest, SetFD) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002406 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002407 ASSERT_TRUE(ctx);
David Benjamin5c0fb882016-06-14 14:03:51 -04002408
2409 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002410 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002411 ASSERT_TRUE(ssl);
2412 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2413 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
2414 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04002415
2416 // Test setting the same FD.
2417 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002418 ASSERT_TRUE(ssl);
2419 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2420 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002421
2422 // Test setting the same FD one side at a time.
2423 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002424 ASSERT_TRUE(ssl);
2425 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2426 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
2427 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002428
2429 // Test setting the same FD in the other order.
2430 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002431 ASSERT_TRUE(ssl);
2432 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
2433 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2434 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002435
David Benjamin5c0fb882016-06-14 14:03:51 -04002436 // Test changing the read FD partway through.
2437 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002438 ASSERT_TRUE(ssl);
2439 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2440 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 2));
2441 ExpectFDs(ssl.get(), 2, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002442
2443 // Test changing the write FD partway through.
2444 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002445 ASSERT_TRUE(ssl);
2446 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2447 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
2448 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04002449
2450 // Test a no-op change to the read FD partway through.
2451 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002452 ASSERT_TRUE(ssl);
2453 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2454 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2455 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002456
2457 // Test a no-op change to the write FD partway through.
2458 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002459 ASSERT_TRUE(ssl);
2460 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2461 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
2462 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002463
2464 // ASan builds will implicitly test that the internal |BIO| reference-counting
2465 // is correct.
David Benjamin5c0fb882016-06-14 14:03:51 -04002466}
2467
David Benjaminf0d8e222017-02-04 10:58:26 -05002468TEST(SSLTest, SetBIO) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002469 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002470 ASSERT_TRUE(ctx);
David Benjamin4501bd52016-08-01 13:39:41 -04002471
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002472 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
2473 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04002474 bio3(BIO_new(BIO_s_mem()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002475 ASSERT_TRUE(ssl);
2476 ASSERT_TRUE(bio1);
2477 ASSERT_TRUE(bio2);
2478 ASSERT_TRUE(bio3);
David Benjamin4501bd52016-08-01 13:39:41 -04002479
2480 // SSL_set_bio takes one reference when the parameters are the same.
2481 BIO_up_ref(bio1.get());
2482 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
2483
2484 // Repeating the call does nothing.
2485 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
2486
2487 // It takes one reference each when the parameters are different.
2488 BIO_up_ref(bio2.get());
2489 BIO_up_ref(bio3.get());
2490 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
2491
2492 // Repeating the call does nothing.
2493 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
2494
2495 // It takes one reference when changing only wbio.
2496 BIO_up_ref(bio1.get());
2497 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
2498
2499 // It takes one reference when changing only rbio and the two are different.
2500 BIO_up_ref(bio3.get());
2501 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
2502
2503 // If setting wbio to rbio, it takes no additional references.
2504 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
2505
2506 // From there, wbio may be switched to something else.
2507 BIO_up_ref(bio1.get());
2508 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
2509
2510 // If setting rbio to wbio, it takes no additional references.
2511 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
2512
2513 // From there, rbio may be switched to something else, but, for historical
2514 // reasons, it takes a reference to both parameters.
2515 BIO_up_ref(bio1.get());
2516 BIO_up_ref(bio2.get());
2517 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
2518
2519 // ASAN builds will implicitly test that the internal |BIO| reference-counting
2520 // is correct.
David Benjamin4501bd52016-08-01 13:39:41 -04002521}
2522
David Benjamin25490f22016-07-14 00:22:54 -04002523static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
2524
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002525TEST_P(SSLVersionTest, GetPeerCertificate) {
2526 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04002527
David Benjamin0fef3052016-11-18 15:11:10 +09002528 // Configure both client and server to accept any certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002529 SSL_CTX_set_verify(client_ctx_.get(),
2530 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2531 nullptr);
2532 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
2533 SSL_CTX_set_verify(server_ctx_.get(),
2534 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2535 nullptr);
2536 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjaminadd5e522016-07-14 00:33:24 -04002537
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002538 ASSERT_TRUE(Connect());
David Benjaminadd5e522016-07-14 00:33:24 -04002539
David Benjamin0fef3052016-11-18 15:11:10 +09002540 // Client and server should both see the leaf certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002541 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
2542 ASSERT_TRUE(peer);
2543 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04002544
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002545 peer.reset(SSL_get_peer_certificate(client_.get()));
2546 ASSERT_TRUE(peer);
2547 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04002548
David Benjamine664a532017-07-20 20:19:36 -04002549 // However, for historical reasons, the X509 chain includes the leaf on the
David Benjamin0fef3052016-11-18 15:11:10 +09002550 // client, but does not on the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002551 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(client_.get())), 1u);
2552 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(client_.get())),
2553 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04002554
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002555 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(server_.get())), 0u);
2556 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(server_.get())),
2557 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04002558}
2559
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002560TEST_P(SSLVersionTest, NoPeerCertificate) {
2561 SSL_CTX_set_verify(server_ctx_.get(), SSL_VERIFY_PEER, nullptr);
2562 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
2563 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
David Benjamine664a532017-07-20 20:19:36 -04002564
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002565 ASSERT_TRUE(Connect());
David Benjamine664a532017-07-20 20:19:36 -04002566
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002567 // Server should not see a peer certificate.
2568 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
2569 ASSERT_FALSE(peer);
2570 ASSERT_FALSE(SSL_get0_peer_certificates(server_.get()));
David Benjamine664a532017-07-20 20:19:36 -04002571}
2572
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002573TEST_P(SSLVersionTest, RetainOnlySHA256OfCerts) {
David Benjamin25490f22016-07-14 00:22:54 -04002574 uint8_t *cert_der = NULL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002575 int cert_der_len = i2d_X509(cert_.get(), &cert_der);
2576 ASSERT_GE(cert_der_len, 0);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002577 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04002578
2579 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
2580 SHA256(cert_der, cert_der_len, cert_sha256);
2581
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002582 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2583
David Benjamin0fef3052016-11-18 15:11:10 +09002584 // Configure both client and server to accept any certificate, but the
2585 // server must retain only the SHA-256 of the peer.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002586 SSL_CTX_set_verify(client_ctx_.get(),
2587 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2588 nullptr);
2589 SSL_CTX_set_verify(server_ctx_.get(),
2590 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2591 nullptr);
2592 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
2593 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
2594 SSL_CTX_set_retain_only_sha256_of_client_certs(server_ctx_.get(), 1);
David Benjamin25490f22016-07-14 00:22:54 -04002595
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002596 ASSERT_TRUE(Connect());
David Benjamin25490f22016-07-14 00:22:54 -04002597
David Benjamin0fef3052016-11-18 15:11:10 +09002598 // The peer certificate has been dropped.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002599 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
2600 EXPECT_FALSE(peer);
David Benjamin25490f22016-07-14 00:22:54 -04002601
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002602 SSL_SESSION *session = SSL_get_session(server_.get());
David Benjamin02de7bd2018-05-08 18:13:54 -04002603 EXPECT_TRUE(SSL_SESSION_has_peer_sha256(session));
David Benjamin25490f22016-07-14 00:22:54 -04002604
David Benjamin02de7bd2018-05-08 18:13:54 -04002605 const uint8_t *peer_sha256;
2606 size_t peer_sha256_len;
2607 SSL_SESSION_get0_peer_sha256(session, &peer_sha256, &peer_sha256_len);
2608 EXPECT_EQ(Bytes(cert_sha256), Bytes(peer_sha256, peer_sha256_len));
David Benjamin25490f22016-07-14 00:22:54 -04002609}
2610
David Benjamin737d2df2017-09-25 15:05:19 -04002611// Tests that our ClientHellos do not change unexpectedly. These are purely
2612// change detection tests. If they fail as part of an intentional ClientHello
2613// change, update the test vector.
2614TEST(SSLTest, ClientHello) {
2615 struct {
2616 uint16_t max_version;
2617 std::vector<uint8_t> expected;
2618 } kTests[] = {
David Benjamin737d2df2017-09-25 15:05:19 -04002619 {TLS1_VERSION,
2620 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x01, 0x00,
2621 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2622 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2623 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
2624 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
Adam Langleyd6680952018-08-23 08:01:23 -07002625 0x01, 0x00, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01,
2626 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
2627 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
David Benjamin737d2df2017-09-25 15:05:19 -04002628 {TLS1_1_VERSION,
2629 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x02, 0x00,
2630 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2631 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2632 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
2633 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
Adam Langleyd6680952018-08-23 08:01:23 -07002634 0x01, 0x00, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01,
2635 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
2636 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
David Benjamin737d2df2017-09-25 15:05:19 -04002637 {TLS1_2_VERSION,
David Benjamin6e678ee2018-04-16 19:54:42 -04002638 {0x16, 0x03, 0x01, 0x00, 0x82, 0x01, 0x00, 0x00, 0x7e, 0x03, 0x03, 0x00,
David Benjamin737d2df2017-09-25 15:05:19 -04002639 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2640 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
David Benjamin6e678ee2018-04-16 19:54:42 -04002641 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xcc, 0xa9,
David Benjamin737d2df2017-09-25 15:05:19 -04002642 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xc0, 0x09,
David Benjamin6e678ee2018-04-16 19:54:42 -04002643 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
Adam Langleyd6680952018-08-23 08:01:23 -07002644 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37, 0x00, 0x17, 0x00, 0x00,
2645 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00,
2646 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
2647 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04, 0x03, 0x08,
2648 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06,
2649 0x01, 0x02, 0x01}},
David Benjamin737d2df2017-09-25 15:05:19 -04002650 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
2651 // implementation has settled enough that it won't change.
David Benjaminafc64de2016-07-19 17:12:41 +02002652 };
David Benjamin737d2df2017-09-25 15:05:19 -04002653
2654 for (const auto &t : kTests) {
2655 SCOPED_TRACE(t.max_version);
2656
2657 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2658 ASSERT_TRUE(ctx);
2659 // Our default cipher list varies by CPU capabilities, so manually place the
2660 // ChaCha20 ciphers in front.
2661 const char *cipher_list = "CHACHA20:ALL";
David Benjamin737d2df2017-09-25 15:05:19 -04002662 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), t.max_version));
2663 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list));
2664
2665 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
2666 ASSERT_TRUE(ssl);
2667 std::vector<uint8_t> client_hello;
2668 ASSERT_TRUE(GetClientHello(ssl.get(), &client_hello));
2669
2670 // Zero the client_random.
2671 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
2672 1 + 3 + // handshake message header
2673 2; // client_version
2674 ASSERT_GE(client_hello.size(), kRandomOffset + SSL3_RANDOM_SIZE);
2675 OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
2676
2677 if (client_hello != t.expected) {
2678 ADD_FAILURE() << "ClientHellos did not match.";
2679 // Print the value manually so it is easier to update the test vector.
2680 for (size_t i = 0; i < client_hello.size(); i += 12) {
2681 printf(" %c", i == 0 ? '{' : ' ');
2682 for (size_t j = i; j < client_hello.size() && j < i + 12; j++) {
2683 if (j > i) {
2684 printf(" ");
2685 }
2686 printf("0x%02x", client_hello[j]);
2687 if (j < client_hello.size() - 1) {
2688 printf(",");
2689 }
2690 }
2691 if (i + 12 >= client_hello.size()) {
Adam Langleyd6680952018-08-23 08:01:23 -07002692 printf("}},");
David Benjamin737d2df2017-09-25 15:05:19 -04002693 }
2694 printf("\n");
2695 }
2696 }
David Benjaminafc64de2016-07-19 17:12:41 +02002697 }
David Benjaminafc64de2016-07-19 17:12:41 +02002698}
2699
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002700static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04002701
2702static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
2703 // Save the most recent session.
2704 g_last_session.reset(session);
2705 return 1;
2706}
2707
David Benjamina8614602017-09-06 15:40:19 -04002708static bssl::UniquePtr<SSL_SESSION> CreateClientSession(
2709 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2710 const ClientConfig &config = ClientConfig()) {
David Benjamina20e5352016-08-02 19:09:41 -04002711 g_last_session = nullptr;
2712 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2713
2714 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002715 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04002716 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
Steven Valdez777a2392019-02-21 11:30:47 -05002717 config) ||
2718 !FlushNewSessionTickets(client.get(), server.get())) {
David Benjamina20e5352016-08-02 19:09:41 -04002719 fprintf(stderr, "Failed to connect client and server.\n");
2720 return nullptr;
2721 }
2722
David Benjamina20e5352016-08-02 19:09:41 -04002723 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2724
2725 if (!g_last_session) {
2726 fprintf(stderr, "Client did not receive a session.\n");
2727 return nullptr;
2728 }
2729 return std::move(g_last_session);
2730}
2731
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002732static void ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2733 SSL_SESSION *session, bool want_reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002734 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002735 ClientConfig config;
2736 config.session = session;
2737 EXPECT_TRUE(
2738 ConnectClientAndServer(&client, &server, client_ctx, server_ctx, config));
David Benjamina20e5352016-08-02 19:09:41 -04002739
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002740 EXPECT_EQ(SSL_session_reused(client.get()), SSL_session_reused(server.get()));
David Benjamina20e5352016-08-02 19:09:41 -04002741
2742 bool was_reused = !!SSL_session_reused(client.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002743 EXPECT_EQ(was_reused, want_reused);
David Benjamina20e5352016-08-02 19:09:41 -04002744}
2745
David Benjamin3c51d9b2016-11-01 17:50:42 -04002746static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
2747 SSL_CTX *server_ctx,
2748 SSL_SESSION *session) {
2749 g_last_session = nullptr;
2750 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2751
2752 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002753 ClientConfig config;
2754 config.session = session;
2755 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
Steven Valdez777a2392019-02-21 11:30:47 -05002756 config) ||
2757 !FlushNewSessionTickets(client.get(), server.get())) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002758 fprintf(stderr, "Failed to connect client and server.\n");
2759 return nullptr;
2760 }
2761
2762 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2763 fprintf(stderr, "Client and server were inconsistent.\n");
2764 return nullptr;
2765 }
2766
2767 if (!SSL_session_reused(client.get())) {
2768 fprintf(stderr, "Session was not reused.\n");
2769 return nullptr;
2770 }
2771
David Benjamin3c51d9b2016-11-01 17:50:42 -04002772 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2773
2774 if (!g_last_session) {
2775 fprintf(stderr, "Client did not receive a renewed session.\n");
2776 return nullptr;
2777 }
2778 return std::move(g_last_session);
2779}
2780
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002781static void ExpectTicketKeyChanged(SSL_CTX *ctx, uint8_t *inout_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002782 bool changed) {
2783 uint8_t new_key[kTicketKeyLen];
David Benjaminc11ea9422017-08-29 16:33:21 -04002784 // May return 0, 1 or 48.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002785 ASSERT_EQ(SSL_CTX_get_tlsext_ticket_keys(ctx, new_key, kTicketKeyLen), 1);
2786 if (changed) {
2787 ASSERT_NE(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
2788 } else {
2789 ASSERT_EQ(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002790 }
2791 OPENSSL_memcpy(inout_key, new_key, kTicketKeyLen);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002792}
2793
David Benjamina933c382016-10-28 00:10:03 -04002794static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
2795 static const uint8_t kContext[] = {3};
2796
2797 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
2798 return SSL_TLSEXT_ERR_ALERT_FATAL;
2799 }
2800
2801 return SSL_TLSEXT_ERR_OK;
2802}
2803
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002804TEST_P(SSLVersionTest, SessionIDContext) {
David Benjamina20e5352016-08-02 19:09:41 -04002805 static const uint8_t kContext1[] = {1};
2806 static const uint8_t kContext2[] = {2};
2807
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002808 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2809 sizeof(kContext1)));
David Benjamina20e5352016-08-02 19:09:41 -04002810
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002811 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2812 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002813
David Benjamin0fef3052016-11-18 15:11:10 +09002814 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002815 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2816 ASSERT_TRUE(session);
David Benjamina20e5352016-08-02 19:09:41 -04002817
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002818 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2819 session.get(),
2820 true /* expect session reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002821
David Benjamin0fef3052016-11-18 15:11:10 +09002822 // Change the session ID context.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002823 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext2,
2824 sizeof(kContext2)));
David Benjamina20e5352016-08-02 19:09:41 -04002825
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002826 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2827 session.get(),
2828 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002829
David Benjamin0fef3052016-11-18 15:11:10 +09002830 // Change the session ID context back and install an SNI callback to switch
2831 // it.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002832 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2833 sizeof(kContext1)));
David Benjamina933c382016-10-28 00:10:03 -04002834
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002835 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09002836 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04002837
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002838 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2839 session.get(),
2840 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002841
David Benjamin0fef3052016-11-18 15:11:10 +09002842 // Switch the session ID context with the early callback instead.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002843 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), nullptr);
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002844 SSL_CTX_set_select_certificate_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002845 server_ctx_.get(),
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002846 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
2847 static const uint8_t kContext[] = {3};
2848
2849 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
2850 sizeof(kContext))) {
2851 return ssl_select_cert_error;
2852 }
2853
2854 return ssl_select_cert_success;
2855 });
David Benjamina933c382016-10-28 00:10:03 -04002856
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002857 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2858 session.get(),
2859 false /* expect session not reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002860}
2861
David Benjamin721e8b72016-08-03 13:13:17 -04002862static timeval g_current_time;
2863
2864static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2865 *out_clock = g_current_time;
2866}
2867
David Benjamin17b30832017-01-28 14:00:32 -05002868static void FrozenTimeCallback(const SSL *ssl, timeval *out_clock) {
2869 out_clock->tv_sec = 1000;
2870 out_clock->tv_usec = 0;
2871}
2872
David Benjamin3c51d9b2016-11-01 17:50:42 -04002873static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
2874 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
2875 int encrypt) {
2876 static const uint8_t kZeros[16] = {0};
2877
2878 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -05002879 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamin3c51d9b2016-11-01 17:50:42 -04002880 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -05002881 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002882 return 0;
2883 }
2884
2885 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
2886 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
2887 return -1;
2888 }
2889
2890 // Returning two from the callback in decrypt mode renews the
2891 // session in TLS 1.2 and below.
2892 return encrypt ? 1 : 2;
2893}
2894
David Benjamin123db572016-11-03 16:59:25 -04002895static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjaminaaef8332018-06-29 16:45:49 -04002896 const uint8_t *ticket;
2897 size_t ticket_len;
2898 SSL_SESSION_get0_ticket(session, &ticket, &ticket_len);
2899 if (ticket_len < 16 + 16 + SHA256_DIGEST_LENGTH) {
David Benjamin123db572016-11-03 16:59:25 -04002900 return false;
2901 }
2902
David Benjaminaaef8332018-06-29 16:45:49 -04002903 const uint8_t *ciphertext = ticket + 16 + 16;
2904 size_t len = ticket_len - 16 - 16 - SHA256_DIGEST_LENGTH;
David Benjamin123db572016-11-03 16:59:25 -04002905 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
2906
David Benjamin9b63f292016-11-15 00:44:05 -05002907#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
2908 // Fuzzer-mode tickets are unencrypted.
David Benjamin17cf2cb2016-12-13 01:07:13 -05002909 OPENSSL_memcpy(plaintext.get(), ciphertext, len);
David Benjamin9b63f292016-11-15 00:44:05 -05002910#else
2911 static const uint8_t kZeros[16] = {0};
David Benjaminaaef8332018-06-29 16:45:49 -04002912 const uint8_t *iv = ticket + 16;
David Benjamin123db572016-11-03 16:59:25 -04002913 bssl::ScopedEVP_CIPHER_CTX ctx;
2914 int len1, len2;
2915 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
2916 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
2917 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
2918 return false;
2919 }
2920
2921 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05002922#endif
David Benjamin123db572016-11-03 16:59:25 -04002923
Adam Langley46db7af2017-02-01 15:49:37 -08002924 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
2925 if (!ssl_ctx) {
2926 return false;
2927 }
David Benjamin123db572016-11-03 16:59:25 -04002928 bssl::UniquePtr<SSL_SESSION> server_session(
Adam Langley46db7af2017-02-01 15:49:37 -08002929 SSL_SESSION_from_bytes(plaintext.get(), len, ssl_ctx.get()));
David Benjamin123db572016-11-03 16:59:25 -04002930 if (!server_session) {
2931 return false;
2932 }
2933
David Benjaminaaef8332018-06-29 16:45:49 -04002934 *out = SSL_SESSION_get_time(server_session.get());
David Benjamin123db572016-11-03 16:59:25 -04002935 return true;
2936}
2937
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002938TEST_P(SSLVersionTest, SessionTimeout) {
2939 for (bool server_test : {false, true}) {
2940 SCOPED_TRACE(server_test);
David Benjamin721e8b72016-08-03 13:13:17 -04002941
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002942 ResetContexts();
2943 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2944 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
2945
David Benjamin17b30832017-01-28 14:00:32 -05002946 static const time_t kStartTime = 1000;
David Benjamin0fef3052016-11-18 15:11:10 +09002947 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002948
David Benjamin17b30832017-01-28 14:00:32 -05002949 // We are willing to use a longer lifetime for TLS 1.3 sessions as
2950 // resumptions still perform ECDHE.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002951 const time_t timeout = version() == TLS1_3_VERSION
David Benjamin17b30832017-01-28 14:00:32 -05002952 ? SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT
2953 : SSL_DEFAULT_SESSION_TIMEOUT;
2954
David Benjamin17b30832017-01-28 14:00:32 -05002955 // Both client and server must enforce session timeouts. We configure the
2956 // other side with a frozen clock so it never expires tickets.
David Benjamin0fef3052016-11-18 15:11:10 +09002957 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002958 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2959 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002960 } else {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002961 SSL_CTX_set_current_time_cb(client_ctx_.get(), CurrentTimeCallback);
2962 SSL_CTX_set_current_time_cb(server_ctx_.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002963 }
2964
2965 // Configure a ticket callback which renews tickets.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002966 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002967
2968 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002969 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2970 ASSERT_TRUE(session);
David Benjamin0fef3052016-11-18 15:11:10 +09002971
2972 // Advance the clock just behind the timeout.
David Benjamin17b30832017-01-28 14:00:32 -05002973 g_current_time.tv_sec += timeout - 1;
David Benjamin0fef3052016-11-18 15:11:10 +09002974
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002975 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2976 session.get(),
2977 true /* expect session reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002978
2979 // Advance the clock one more second.
2980 g_current_time.tv_sec++;
2981
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002982 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2983 session.get(),
2984 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002985
2986 // Rewind the clock to before the session was minted.
2987 g_current_time.tv_sec = kStartTime - 1;
2988
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002989 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2990 session.get(),
2991 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002992
David Benjamin0fef3052016-11-18 15:11:10 +09002993 // Renew the session 10 seconds before expiration.
David Benjamin17b30832017-01-28 14:00:32 -05002994 time_t new_start_time = kStartTime + timeout - 10;
2995 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002996 bssl::UniquePtr<SSL_SESSION> new_session = ExpectSessionRenewed(
2997 client_ctx_.get(), server_ctx_.get(), session.get());
2998 ASSERT_TRUE(new_session);
David Benjamin0fef3052016-11-18 15:11:10 +09002999
3000 // This new session is not the same object as before.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003001 EXPECT_NE(session.get(), new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09003002
3003 // Check the sessions have timestamps measured from issuance.
3004 long session_time = 0;
3005 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003006 ASSERT_TRUE(GetServerTicketTime(&session_time, new_session.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09003007 } else {
David Benjaminaaef8332018-06-29 16:45:49 -04003008 session_time = SSL_SESSION_get_time(new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09003009 }
David Benjamin721e8b72016-08-03 13:13:17 -04003010
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003011 ASSERT_EQ(session_time, g_current_time.tv_sec);
David Benjamin721e8b72016-08-03 13:13:17 -04003012
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003013 if (version() == TLS1_3_VERSION) {
David Benjamin17b30832017-01-28 14:00:32 -05003014 // Renewal incorporates fresh key material in TLS 1.3, so we extend the
3015 // lifetime TLS 1.3.
3016 g_current_time.tv_sec = new_start_time + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003017 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3018 new_session.get(),
3019 true /* expect session reused */));
David Benjamin721e8b72016-08-03 13:13:17 -04003020
David Benjamin17b30832017-01-28 14:00:32 -05003021 // The new session expires after the new timeout.
3022 g_current_time.tv_sec = new_start_time + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003023 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3024 new_session.get(),
3025 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05003026
3027 // Renew the session until it begins just past the auth timeout.
3028 time_t auth_end_time = kStartTime + SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
3029 while (new_start_time < auth_end_time - 1000) {
3030 // Get as close as possible to target start time.
3031 new_start_time =
3032 std::min(auth_end_time - 1000, new_start_time + timeout - 1);
3033 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003034 new_session = ExpectSessionRenewed(client_ctx_.get(), server_ctx_.get(),
David Benjamin17b30832017-01-28 14:00:32 -05003035 new_session.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003036 ASSERT_TRUE(new_session);
David Benjamin17b30832017-01-28 14:00:32 -05003037 }
3038
3039 // Now the session's lifetime is bound by the auth timeout.
3040 g_current_time.tv_sec = auth_end_time - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003041 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3042 new_session.get(),
3043 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05003044
3045 g_current_time.tv_sec = auth_end_time + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003046 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3047 new_session.get(),
3048 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05003049 } else {
3050 // The new session is usable just before the old expiration.
3051 g_current_time.tv_sec = kStartTime + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003052 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3053 new_session.get(),
3054 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05003055
3056 // Renewal does not extend the lifetime, so it is not usable beyond the
3057 // old expiration.
3058 g_current_time.tv_sec = kStartTime + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003059 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3060 new_session.get(),
3061 false /* expect session not reused */));
David Benjamin1b22f852016-10-27 16:36:32 -04003062 }
David Benjamin721e8b72016-08-03 13:13:17 -04003063 }
David Benjamin721e8b72016-08-03 13:13:17 -04003064}
3065
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003066TEST_P(SSLVersionTest, DefaultTicketKeyInitialization) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003067 static const uint8_t kZeroKey[kTicketKeyLen] = {};
3068 uint8_t ticket_key[kTicketKeyLen];
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003069 ASSERT_EQ(1, SSL_CTX_get_tlsext_ticket_keys(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003070 kTicketKeyLen));
3071 ASSERT_NE(0, OPENSSL_memcmp(ticket_key, kZeroKey, kTicketKeyLen));
3072}
3073
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003074TEST_P(SSLVersionTest, DefaultTicketKeyRotation) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003075 static const time_t kStartTime = 1001;
3076 g_current_time.tv_sec = kStartTime;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003077
David Benjaminc11ea9422017-08-29 16:33:21 -04003078 // We use session reuse as a proxy for ticket decryption success, hence
3079 // disable session timeouts.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003080 SSL_CTX_set_timeout(server_ctx_.get(), std::numeric_limits<uint32_t>::max());
3081 SSL_CTX_set_session_psk_dhe_timeout(server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003082 std::numeric_limits<uint32_t>::max());
3083
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003084 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
3085 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003086
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003087 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3088 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_OFF);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003089
David Benjamin1f0d54b2018-08-09 16:19:13 -05003090 // Initialize ticket_key with the current key and check that it was
3091 // initialized to something, not all zeros.
3092 uint8_t ticket_key[kTicketKeyLen] = {0};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003093 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
3094 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003095
David Benjaminc11ea9422017-08-29 16:33:21 -04003096 // Verify ticket resumption actually works.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003097 bssl::UniquePtr<SSL> client, server;
3098 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003099 CreateClientSession(client_ctx_.get(), server_ctx_.get());
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003100 ASSERT_TRUE(session);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003101 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003102 session.get(), true /* reused */));
3103
David Benjaminc11ea9422017-08-29 16:33:21 -04003104 // Advance time to just before key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003105 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003106 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003107 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003108 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003109 false /* NOT changed */));
3110
David Benjaminc11ea9422017-08-29 16:33:21 -04003111 // Force key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003112 g_current_time.tv_sec += 1;
3113 bssl::UniquePtr<SSL_SESSION> new_session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003114 CreateClientSession(client_ctx_.get(), server_ctx_.get());
3115 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
3116 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003117
David Benjaminc11ea9422017-08-29 16:33:21 -04003118 // Resumption with both old and new ticket should work.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003119 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003120 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003121 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003122 new_session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003123 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003124 false /* NOT changed */));
3125
David Benjaminc11ea9422017-08-29 16:33:21 -04003126 // Force key rotation again. Resumption with the old ticket now fails.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003127 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003128 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003129 session.get(), false /* NOT reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003130 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
3131 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003132
David Benjaminc11ea9422017-08-29 16:33:21 -04003133 // But resumption with the newer session still works.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003134 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003135 new_session.get(), true /* reused */));
3136}
3137
David Benjamin0fc37ef2016-08-17 15:29:46 -04003138static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003139 SSL_CTX *ctx = reinterpret_cast<SSL_CTX *>(arg);
David Benjamin0fc37ef2016-08-17 15:29:46 -04003140 SSL_set_SSL_CTX(ssl, ctx);
3141 return SSL_TLSEXT_ERR_OK;
3142}
3143
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003144TEST_P(SSLVersionTest, SNICallback) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003145 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003146 ASSERT_TRUE(cert2);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003147 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003148 ASSERT_TRUE(key2);
David Benjamin0fc37ef2016-08-17 15:29:46 -04003149
David Benjamin0fef3052016-11-18 15:11:10 +09003150 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
3151 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04003152
David Benjamin83a32122017-02-14 18:34:54 -05003153 static const uint8_t kSCTList[] = {0, 6, 0, 4, 5, 6, 7, 8};
3154 static const uint8_t kOCSPResponse[] = {1, 2, 3, 4};
3155
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003156 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
3157 ASSERT_TRUE(server_ctx2);
3158 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()));
3159 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()));
3160 ASSERT_TRUE(SSL_CTX_set_signed_cert_timestamp_list(
3161 server_ctx2.get(), kSCTList, sizeof(kSCTList)));
3162 ASSERT_TRUE(SSL_CTX_set_ocsp_response(server_ctx2.get(), kOCSPResponse,
3163 sizeof(kOCSPResponse)));
3164 // Historically signing preferences would be lost in some cases with the
3165 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
3166 // this doesn't happen when |version| is TLS 1.2, configure the private
3167 // key to only sign SHA-256.
3168 ASSERT_TRUE(SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
3169 &kECDSAWithSHA256, 1));
David Benjamin0fc37ef2016-08-17 15:29:46 -04003170
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003171 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), SwitchContext);
3172 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04003173
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003174 SSL_CTX_enable_signed_cert_timestamps(client_ctx_.get());
3175 SSL_CTX_enable_ocsp_stapling(client_ctx_.get());
David Benjamin83a32122017-02-14 18:34:54 -05003176
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003177 ASSERT_TRUE(Connect());
David Benjamin0fc37ef2016-08-17 15:29:46 -04003178
David Benjamin0fef3052016-11-18 15:11:10 +09003179 // The client should have received |cert2|.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003180 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client_.get()));
3181 ASSERT_TRUE(peer);
3182 EXPECT_EQ(X509_cmp(peer.get(), cert2.get()), 0);
David Benjamin0fc37ef2016-08-17 15:29:46 -04003183
David Benjamin83a32122017-02-14 18:34:54 -05003184 // The client should have received |server_ctx2|'s SCT list.
3185 const uint8_t *data;
3186 size_t len;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003187 SSL_get0_signed_cert_timestamp_list(client_.get(), &data, &len);
3188 EXPECT_EQ(Bytes(kSCTList), Bytes(data, len));
David Benjamin83a32122017-02-14 18:34:54 -05003189
3190 // The client should have received |server_ctx2|'s OCSP response.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003191 SSL_get0_ocsp_response(client_.get(), &data, &len);
3192 EXPECT_EQ(Bytes(kOCSPResponse), Bytes(data, len));
David Benjamin0fc37ef2016-08-17 15:29:46 -04003193}
3194
David Benjaminf0d8e222017-02-04 10:58:26 -05003195// Test that the early callback can swap the maximum version.
3196TEST(SSLTest, EarlyCallbackVersionSwitch) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04003197 bssl::UniquePtr<SSL_CTX> server_ctx =
3198 CreateContextWithTestCertificate(TLS_method());
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003199 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003200 ASSERT_TRUE(server_ctx);
3201 ASSERT_TRUE(client_ctx);
David Benjaminf0d8e222017-02-04 10:58:26 -05003202 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
3203 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
David Benjamin99620572016-08-30 00:35:36 -04003204
David Benjaminf0d8e222017-02-04 10:58:26 -05003205 SSL_CTX_set_select_certificate_cb(
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00003206 server_ctx.get(),
3207 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
David Benjaminf0d8e222017-02-04 10:58:26 -05003208 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00003209 return ssl_select_cert_error;
David Benjaminf0d8e222017-02-04 10:58:26 -05003210 }
3211
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00003212 return ssl_select_cert_success;
David Benjaminf0d8e222017-02-04 10:58:26 -05003213 });
David Benjamin99620572016-08-30 00:35:36 -04003214
Matt Braithwaited17d74d2016-08-17 20:10:28 -07003215 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05003216 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003217 server_ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003218 EXPECT_EQ(TLS1_2_VERSION, SSL_version(client.get()));
David Benjamin99620572016-08-30 00:35:36 -04003219}
3220
David Benjaminf0d8e222017-02-04 10:58:26 -05003221TEST(SSLTest, SetVersion) {
David Benjamin2dc02042016-09-19 19:57:37 -04003222 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003223 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04003224
David Benjaminf0d8e222017-02-04 10:58:26 -05003225 // Set valid TLS versions.
3226 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
3227 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
3228 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
3229 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04003230
David Benjaminf0d8e222017-02-04 10:58:26 -05003231 // Invalid TLS versions are rejected.
3232 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
3233 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x0200));
3234 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
3235 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
3236 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x0200));
3237 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04003238
David Benjaminf0d8e222017-02-04 10:58:26 -05003239 // Zero is the default version.
3240 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08003241 EXPECT_EQ(TLS1_3_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003242 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07003243 EXPECT_EQ(TLS1_VERSION, SSL_CTX_get_min_proto_version(ctx.get()));
David Benjamin3cfeb952017-03-01 16:48:38 -05003244
David Benjamin9bb15f52018-06-26 00:07:40 -04003245 // TLS 1.3 is available, but not by default.
David Benjamin3cfeb952017-03-01 16:48:38 -05003246 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07003247 EXPECT_EQ(TLS1_3_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjamine34bcc92016-09-21 16:53:09 -04003248
David Benjamin9bb15f52018-06-26 00:07:40 -04003249 // SSL 3.0 is not available.
3250 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION));
3251
David Benjamin2dc02042016-09-19 19:57:37 -04003252 ctx.reset(SSL_CTX_new(DTLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003253 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04003254
David Benjaminf0d8e222017-02-04 10:58:26 -05003255 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
3256 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION));
3257 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
3258 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04003259
David Benjaminf0d8e222017-02-04 10:58:26 -05003260 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
3261 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
3262 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
3263 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
3264 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
3265 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
3266 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
3267 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04003268
David Benjaminf0d8e222017-02-04 10:58:26 -05003269 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07003270 EXPECT_EQ(DTLS1_2_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05003271 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07003272 EXPECT_EQ(DTLS1_VERSION, SSL_CTX_get_min_proto_version(ctx.get()));
David Benjamin2dc02042016-09-19 19:57:37 -04003273}
3274
David Benjamin458334a2016-12-15 13:53:25 -05003275static const char *GetVersionName(uint16_t version) {
3276 switch (version) {
David Benjamin458334a2016-12-15 13:53:25 -05003277 case TLS1_VERSION:
3278 return "TLSv1";
3279 case TLS1_1_VERSION:
3280 return "TLSv1.1";
3281 case TLS1_2_VERSION:
3282 return "TLSv1.2";
3283 case TLS1_3_VERSION:
3284 return "TLSv1.3";
3285 case DTLS1_VERSION:
3286 return "DTLSv1";
3287 case DTLS1_2_VERSION:
3288 return "DTLSv1.2";
3289 default:
3290 return "???";
3291 }
3292}
3293
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003294TEST_P(SSLVersionTest, Version) {
3295 ASSERT_TRUE(Connect());
David Benjamincb18ac22016-09-27 14:09:15 -04003296
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003297 EXPECT_EQ(SSL_version(client_.get()), version());
3298 EXPECT_EQ(SSL_version(server_.get()), version());
David Benjamincb18ac22016-09-27 14:09:15 -04003299
David Benjamin458334a2016-12-15 13:53:25 -05003300 // Test the version name is reported as expected.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003301 const char *version_name = GetVersionName(version());
3302 EXPECT_EQ(strcmp(version_name, SSL_get_version(client_.get())), 0);
3303 EXPECT_EQ(strcmp(version_name, SSL_get_version(server_.get())), 0);
David Benjamin458334a2016-12-15 13:53:25 -05003304
3305 // Test SSL_SESSION reports the same name.
3306 const char *client_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003307 SSL_SESSION_get_version(SSL_get_session(client_.get()));
David Benjamin458334a2016-12-15 13:53:25 -05003308 const char *server_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003309 SSL_SESSION_get_version(SSL_get_session(server_.get()));
3310 EXPECT_EQ(strcmp(version_name, client_name), 0);
3311 EXPECT_EQ(strcmp(version_name, server_name), 0);
David Benjamincb18ac22016-09-27 14:09:15 -04003312}
3313
David Benjamin9ef31f02016-10-31 18:01:13 -04003314// Tests that that |SSL_get_pending_cipher| is available during the ALPN
3315// selection callback.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003316TEST_P(SSLVersionTest, ALPNCipherAvailable) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003317 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
3318
David Benjamin9ef31f02016-10-31 18:01:13 -04003319 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003320 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
3321 sizeof(kALPNProtos)),
3322 0);
David Benjamin0fef3052016-11-18 15:11:10 +09003323
3324 // The ALPN callback does not fail the handshake on error, so have the
3325 // callback write a boolean.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003326 std::pair<uint16_t, bool> callback_state(version(), false);
David Benjamin0fef3052016-11-18 15:11:10 +09003327 SSL_CTX_set_alpn_select_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003328 server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09003329 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
3330 unsigned in_len, void *arg) -> int {
3331 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
3332 if (SSL_get_pending_cipher(ssl) != nullptr &&
3333 SSL_version(ssl) == state->first) {
3334 state->second = true;
3335 }
3336 return SSL_TLSEXT_ERR_NOACK;
3337 },
3338 &callback_state);
3339
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003340 ASSERT_TRUE(Connect());
David Benjamin0fef3052016-11-18 15:11:10 +09003341
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003342 ASSERT_TRUE(callback_state.second);
David Benjamin0fef3052016-11-18 15:11:10 +09003343}
3344
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003345TEST_P(SSLVersionTest, SSLClearSessionResumption) {
David Benjaminb79cc842016-12-07 15:57:14 -05003346 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
3347 // API pattern.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003348 if (version() == TLS1_3_VERSION) {
3349 return;
David Benjaminb79cc842016-12-07 15:57:14 -05003350 }
3351
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07003352 shed_handshake_config_ = false;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003353 ASSERT_TRUE(Connect());
David Benjaminb79cc842016-12-07 15:57:14 -05003354
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003355 EXPECT_FALSE(SSL_session_reused(client_.get()));
3356 EXPECT_FALSE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003357
3358 // Reset everything.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003359 ASSERT_TRUE(SSL_clear(client_.get()));
3360 ASSERT_TRUE(SSL_clear(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003361
3362 // Attempt to connect a second time.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003363 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003364
3365 // |SSL_clear| should implicitly offer the previous session to the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003366 EXPECT_TRUE(SSL_session_reused(client_.get()));
3367 EXPECT_TRUE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003368}
3369
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07003370TEST_P(SSLVersionTest, SSLClearFailsWithShedding) {
3371 shed_handshake_config_ = false;
3372 ASSERT_TRUE(Connect());
3373 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
3374
3375 // Reset everything.
3376 ASSERT_TRUE(SSL_clear(client_.get()));
3377 ASSERT_TRUE(SSL_clear(server_.get()));
3378
3379 // Now enable shedding, and connect a second time.
3380 shed_handshake_config_ = true;
3381 ASSERT_TRUE(Connect());
3382 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
3383
3384 // |SSL_clear| should now fail.
3385 ASSERT_FALSE(SSL_clear(client_.get()));
3386 ASSERT_FALSE(SSL_clear(server_.get()));
3387}
3388
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003389static bool ChainsEqual(STACK_OF(X509) * chain,
3390 const std::vector<X509 *> &expected) {
David Benjamin1444c3a2016-12-20 17:23:11 -05003391 if (sk_X509_num(chain) != expected.size()) {
3392 return false;
3393 }
3394
3395 for (size_t i = 0; i < expected.size(); i++) {
3396 if (X509_cmp(sk_X509_value(chain, i), expected[i]) != 0) {
3397 return false;
3398 }
3399 }
3400
3401 return true;
3402}
3403
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003404TEST_P(SSLVersionTest, AutoChain) {
3405 cert_ = GetChainTestCertificate();
3406 ASSERT_TRUE(cert_);
3407 key_ = GetChainTestKey();
3408 ASSERT_TRUE(key_);
David Benjamin1444c3a2016-12-20 17:23:11 -05003409 bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003410 ASSERT_TRUE(intermediate);
3411
3412 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
3413 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin1444c3a2016-12-20 17:23:11 -05003414
3415 // Configure both client and server to accept any certificate. Add
3416 // |intermediate| to the cert store.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003417 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx_.get()),
3418 intermediate.get()));
3419 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(server_ctx_.get()),
3420 intermediate.get()));
3421 SSL_CTX_set_verify(client_ctx_.get(),
3422 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3423 nullptr);
3424 SSL_CTX_set_verify(server_ctx_.get(),
3425 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3426 nullptr);
3427 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
3428 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjamin1444c3a2016-12-20 17:23:11 -05003429
3430 // By default, the client and server should each only send the leaf.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003431 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05003432
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003433 EXPECT_TRUE(
3434 ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()), {cert_.get()}));
3435 EXPECT_TRUE(
3436 ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()), {cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003437
3438 // If auto-chaining is enabled, then the intermediate is sent.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003439 SSL_CTX_clear_mode(client_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
3440 SSL_CTX_clear_mode(server_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
3441 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05003442
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003443 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
3444 {cert_.get(), intermediate.get()}));
3445 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
3446 {cert_.get(), intermediate.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003447
3448 // Auto-chaining does not override explicitly-configured intermediates.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003449 ASSERT_TRUE(SSL_CTX_add1_chain_cert(client_ctx_.get(), cert_.get()));
3450 ASSERT_TRUE(SSL_CTX_add1_chain_cert(server_ctx_.get(), cert_.get()));
3451 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05003452
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003453 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
3454 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003455
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003456 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
3457 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003458}
3459
David Benjamin48063c22017-01-01 23:56:36 -05003460static bool ExpectBadWriteRetry() {
3461 int err = ERR_get_error();
3462 if (ERR_GET_LIB(err) != ERR_LIB_SSL ||
3463 ERR_GET_REASON(err) != SSL_R_BAD_WRITE_RETRY) {
3464 char buf[ERR_ERROR_STRING_BUF_LEN];
3465 ERR_error_string_n(err, buf, sizeof(buf));
3466 fprintf(stderr, "Wanted SSL_R_BAD_WRITE_RETRY, got: %s.\n", buf);
3467 return false;
3468 }
3469
3470 if (ERR_peek_error() != 0) {
3471 fprintf(stderr, "Unexpected error following SSL_R_BAD_WRITE_RETRY.\n");
3472 return false;
3473 }
3474
3475 return true;
3476}
3477
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003478TEST_P(SSLVersionTest, SSLWriteRetry) {
3479 if (is_dtls()) {
3480 return;
David Benjamin48063c22017-01-01 23:56:36 -05003481 }
3482
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003483 for (bool enable_partial_write : {false, true}) {
3484 SCOPED_TRACE(enable_partial_write);
3485
David Benjamin48063c22017-01-01 23:56:36 -05003486 // Connect a client and server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003487 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
3488
3489 ASSERT_TRUE(Connect());
David Benjamin48063c22017-01-01 23:56:36 -05003490
3491 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003492 SSL_set_mode(client_.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003493 }
3494
3495 // Write without reading until the buffer is full and we have an unfinished
3496 // write. Keep a count so we may reread it again later. "hello!" will be
3497 // written in two chunks, "hello" and "!".
3498 char data[] = "hello!";
3499 static const int kChunkLen = 5; // The length of "hello".
3500 unsigned count = 0;
3501 for (;;) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003502 int ret = SSL_write(client_.get(), data, kChunkLen);
David Benjamin48063c22017-01-01 23:56:36 -05003503 if (ret <= 0) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003504 ASSERT_EQ(SSL_get_error(client_.get(), ret), SSL_ERROR_WANT_WRITE);
3505 break;
David Benjamin48063c22017-01-01 23:56:36 -05003506 }
3507
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003508 ASSERT_EQ(ret, 5);
David Benjamin48063c22017-01-01 23:56:36 -05003509
3510 count++;
3511 }
3512
3513 // Retrying with the same parameters is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003514 ASSERT_EQ(
3515 SSL_get_error(client_.get(), SSL_write(client_.get(), data, kChunkLen)),
3516 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003517
3518 // Retrying with the same buffer but shorter length is not legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003519 ASSERT_EQ(SSL_get_error(client_.get(),
3520 SSL_write(client_.get(), data, kChunkLen - 1)),
3521 SSL_ERROR_SSL);
3522 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05003523
3524 // Retrying with a different buffer pointer is not legal.
3525 char data2[] = "hello";
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003526 ASSERT_EQ(SSL_get_error(client_.get(),
3527 SSL_write(client_.get(), data2, kChunkLen)),
3528 SSL_ERROR_SSL);
3529 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05003530
3531 // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003532 SSL_set_mode(client_.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
3533 ASSERT_EQ(SSL_get_error(client_.get(),
3534 SSL_write(client_.get(), data2, kChunkLen)),
3535 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003536
3537 // |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| does not disable length checks.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003538 ASSERT_EQ(SSL_get_error(client_.get(),
3539 SSL_write(client_.get(), data2, kChunkLen - 1)),
3540 SSL_ERROR_SSL);
3541 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05003542
3543 // Retrying with a larger buffer is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003544 ASSERT_EQ(SSL_get_error(client_.get(),
3545 SSL_write(client_.get(), data, kChunkLen + 1)),
3546 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003547
3548 // Drain the buffer.
3549 char buf[20];
3550 for (unsigned i = 0; i < count; i++) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003551 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
3552 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
David Benjamin48063c22017-01-01 23:56:36 -05003553 }
3554
3555 // Now that there is space, a retry with a larger buffer should flush the
3556 // pending record, skip over that many bytes of input (on assumption they
3557 // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE
3558 // is set, this will complete in two steps.
3559 char data3[] = "_____!";
3560 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003561 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen);
3562 ASSERT_EQ(SSL_write(client_.get(), data3 + kChunkLen, 1), 1);
3563 } else {
3564 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen + 1);
David Benjamin48063c22017-01-01 23:56:36 -05003565 }
3566
3567 // Check the last write was correct. The data will be spread over two
3568 // records, so SSL_read returns twice.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003569 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
3570 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
3571 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), 1);
3572 ASSERT_EQ(buf[0], '!');
David Benjamin48063c22017-01-01 23:56:36 -05003573 }
David Benjamin48063c22017-01-01 23:56:36 -05003574}
3575
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003576TEST_P(SSLVersionTest, RecordCallback) {
3577 for (bool test_server : {true, false}) {
3578 SCOPED_TRACE(test_server);
3579 ResetContexts();
David Benjamin5df5be12017-06-22 19:43:11 -04003580
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003581 bool read_seen = false;
3582 bool write_seen = false;
3583 auto cb = [&](int is_write, int cb_version, int cb_type, const void *buf,
3584 size_t len, SSL *ssl) {
3585 if (cb_type != SSL3_RT_HEADER) {
3586 return;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003587 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003588
3589 // The callback does not report a version for records.
3590 EXPECT_EQ(0, cb_version);
3591
3592 if (is_write) {
3593 write_seen = true;
3594 } else {
3595 read_seen = true;
3596 }
3597
3598 // Sanity-check that the record header is plausible.
3599 CBS cbs;
3600 CBS_init(&cbs, reinterpret_cast<const uint8_t *>(buf), len);
3601 uint8_t type;
3602 uint16_t record_version, length;
3603 ASSERT_TRUE(CBS_get_u8(&cbs, &type));
3604 ASSERT_TRUE(CBS_get_u16(&cbs, &record_version));
Steven Valdez64cc1212017-12-04 11:15:37 -05003605 EXPECT_EQ(record_version & 0xff00, version() & 0xff00);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003606 if (is_dtls()) {
3607 uint16_t epoch;
3608 ASSERT_TRUE(CBS_get_u16(&cbs, &epoch));
3609 EXPECT_TRUE(epoch == 0 || epoch == 1) << "Invalid epoch: " << epoch;
3610 ASSERT_TRUE(CBS_skip(&cbs, 6));
3611 }
3612 ASSERT_TRUE(CBS_get_u16(&cbs, &length));
3613 EXPECT_EQ(0u, CBS_len(&cbs));
3614 };
3615 using CallbackType = decltype(cb);
3616 SSL_CTX *ctx = test_server ? server_ctx_.get() : client_ctx_.get();
3617 SSL_CTX_set_msg_callback(
3618 ctx, [](int is_write, int cb_version, int cb_type, const void *buf,
3619 size_t len, SSL *ssl, void *arg) {
3620 CallbackType *cb_ptr = reinterpret_cast<CallbackType *>(arg);
3621 (*cb_ptr)(is_write, cb_version, cb_type, buf, len, ssl);
3622 });
3623 SSL_CTX_set_msg_callback_arg(ctx, &cb);
3624
3625 ASSERT_TRUE(Connect());
3626
3627 EXPECT_TRUE(read_seen);
3628 EXPECT_TRUE(write_seen);
David Benjamin0fef3052016-11-18 15:11:10 +09003629 }
David Benjamin9ef31f02016-10-31 18:01:13 -04003630}
3631
David Benjamina8614602017-09-06 15:40:19 -04003632TEST_P(SSLVersionTest, GetServerName) {
David Benjamina8614602017-09-06 15:40:19 -04003633 ClientConfig config;
3634 config.servername = "host1";
3635
3636 SSL_CTX_set_tlsext_servername_callback(
3637 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
3638 // During the handshake, |SSL_get_servername| must match |config|.
3639 ClientConfig *config_p = reinterpret_cast<ClientConfig *>(arg);
3640 EXPECT_STREQ(config_p->servername.c_str(),
3641 SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name));
3642 return SSL_TLSEXT_ERR_OK;
3643 });
3644 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), &config);
3645
3646 ASSERT_TRUE(Connect(config));
3647 // After the handshake, it must also be available.
3648 EXPECT_STREQ(config.servername.c_str(),
3649 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3650
3651 // Establish a session under host1.
3652 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3653 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3654 bssl::UniquePtr<SSL_SESSION> session =
3655 CreateClientSession(client_ctx_.get(), server_ctx_.get(), config);
3656
3657 // If the client resumes a session with a different name, |SSL_get_servername|
3658 // must return the new name.
3659 ASSERT_TRUE(session);
3660 config.session = session.get();
3661 config.servername = "host2";
3662 ASSERT_TRUE(Connect(config));
3663 EXPECT_STREQ(config.servername.c_str(),
3664 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3665}
3666
David Benjamin3d8f0802017-09-06 16:12:52 -04003667// Test that session cache mode bits are honored in the client session callback.
3668TEST_P(SSLVersionTest, ClientSessionCacheMode) {
3669 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_OFF);
3670 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3671
3672 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_CLIENT);
3673 EXPECT_TRUE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3674
3675 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_SERVER);
3676 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3677}
3678
Steven Valdez777a2392019-02-21 11:30:47 -05003679// Test that all versions survive tiny write buffers. In particular, TLS 1.3
3680// NewSessionTickets are written post-handshake. Servers that block
3681// |SSL_do_handshake| on writing them will deadlock if clients are not draining
3682// the buffer. Test that we do not do this.
3683TEST_P(SSLVersionTest, SmallBuffer) {
3684 // DTLS is a datagram protocol and requires packet-sized buffers.
3685 if (is_dtls()) {
3686 return;
3687 }
3688
3689 // Test both flushing NewSessionTickets with a zero-sized write and
3690 // non-zero-sized write.
3691 for (bool use_zero_write : {false, true}) {
3692 SCOPED_TRACE(use_zero_write);
3693
3694 g_last_session = nullptr;
3695 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3696 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
3697
3698 bssl::UniquePtr<SSL> client(SSL_new(client_ctx_.get())),
3699 server(SSL_new(server_ctx_.get()));
3700 ASSERT_TRUE(client);
3701 ASSERT_TRUE(server);
3702 SSL_set_connect_state(client.get());
3703 SSL_set_accept_state(server.get());
3704
3705 // Use a tiny buffer.
3706 BIO *bio1, *bio2;
3707 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 1, &bio2, 1));
3708
3709 // SSL_set_bio takes ownership.
3710 SSL_set_bio(client.get(), bio1, bio1);
3711 SSL_set_bio(server.get(), bio2, bio2);
3712
3713 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
3714 if (version() >= TLS1_3_VERSION) {
3715 // The post-handshake ticket should not have been processed yet.
3716 EXPECT_FALSE(g_last_session);
3717 }
3718
3719 if (use_zero_write) {
3720 ASSERT_TRUE(FlushNewSessionTickets(client.get(), server.get()));
3721 EXPECT_TRUE(g_last_session);
3722 }
3723
3724 // Send some data from server to client. If |use_zero_write| is false, this
3725 // will also flush the NewSessionTickets.
3726 static const char kMessage[] = "hello world";
3727 char buf[sizeof(kMessage)];
3728 for (;;) {
3729 int server_ret = SSL_write(server.get(), kMessage, sizeof(kMessage));
3730 int server_err = SSL_get_error(server.get(), server_ret);
3731 int client_ret = SSL_read(client.get(), buf, sizeof(buf));
3732 int client_err = SSL_get_error(client.get(), client_ret);
3733
3734 // The server will write a single record, so every iteration should see
3735 // |SSL_ERROR_WANT_WRITE| and |SSL_ERROR_WANT_READ|, until the final
3736 // iteration, where both will complete.
3737 if (server_ret > 0) {
3738 EXPECT_EQ(server_ret, static_cast<int>(sizeof(kMessage)));
3739 EXPECT_EQ(client_ret, static_cast<int>(sizeof(kMessage)));
3740 EXPECT_EQ(Bytes(buf), Bytes(kMessage));
3741 break;
3742 }
3743
3744 ASSERT_EQ(server_ret, -1);
3745 ASSERT_EQ(server_err, SSL_ERROR_WANT_WRITE);
3746 ASSERT_EQ(client_ret, -1);
3747 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
3748 }
3749
3750 // The NewSessionTickets should have been flushed and processed.
3751 EXPECT_TRUE(g_last_session);
3752 }
3753}
3754
Adam Langleye1e78132017-01-31 15:24:31 -08003755TEST(SSLTest, AddChainCertHack) {
3756 // Ensure that we don't accidently break the hack that we have in place to
3757 // keep curl and serf happy when they use an |X509| even after transfering
3758 // ownership.
3759
3760 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3761 ASSERT_TRUE(ctx);
3762 X509 *cert = GetTestCertificate().release();
3763 ASSERT_TRUE(cert);
3764 SSL_CTX_add0_chain_cert(ctx.get(), cert);
3765
3766 // This should not trigger a use-after-free.
3767 X509_cmp(cert, cert);
3768}
3769
David Benjaminb2ff2622017-02-03 17:06:18 -05003770TEST(SSLTest, GetCertificate) {
3771 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3772 ASSERT_TRUE(ctx);
3773 bssl::UniquePtr<X509> cert = GetTestCertificate();
3774 ASSERT_TRUE(cert);
3775 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
3776 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3777 ASSERT_TRUE(ssl);
3778
3779 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
3780 ASSERT_TRUE(cert2);
3781 X509 *cert3 = SSL_get_certificate(ssl.get());
3782 ASSERT_TRUE(cert3);
3783
3784 // The old and new certificates must be identical.
3785 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
3786 EXPECT_EQ(0, X509_cmp(cert.get(), cert3));
3787
3788 uint8_t *der = nullptr;
3789 long der_len = i2d_X509(cert.get(), &der);
3790 ASSERT_LT(0, der_len);
3791 bssl::UniquePtr<uint8_t> free_der(der);
3792
3793 uint8_t *der2 = nullptr;
3794 long der2_len = i2d_X509(cert2, &der2);
3795 ASSERT_LT(0, der2_len);
3796 bssl::UniquePtr<uint8_t> free_der2(der2);
3797
3798 uint8_t *der3 = nullptr;
3799 long der3_len = i2d_X509(cert3, &der3);
3800 ASSERT_LT(0, der3_len);
3801 bssl::UniquePtr<uint8_t> free_der3(der3);
3802
3803 // They must also encode identically.
David Benjamin7d7554b2017-02-04 11:48:59 -05003804 EXPECT_EQ(Bytes(der, der_len), Bytes(der2, der2_len));
3805 EXPECT_EQ(Bytes(der, der_len), Bytes(der3, der3_len));
David Benjaminb2ff2622017-02-03 17:06:18 -05003806}
3807
Adam Langleyd04ca952017-02-28 11:26:51 -08003808TEST(SSLTest, SetChainAndKeyMismatch) {
3809 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_with_buffers_method()));
3810 ASSERT_TRUE(ctx);
3811
3812 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3813 ASSERT_TRUE(key);
3814 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3815 ASSERT_TRUE(leaf);
3816 std::vector<CRYPTO_BUFFER*> chain = {
3817 leaf.get(),
3818 };
3819
3820 // Should fail because |GetTestKey| doesn't match the chain-test certificate.
3821 ASSERT_FALSE(SSL_CTX_set_chain_and_key(ctx.get(), &chain[0], chain.size(),
3822 key.get(), nullptr));
3823 ERR_clear_error();
3824}
3825
3826TEST(SSLTest, SetChainAndKey) {
3827 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3828 ASSERT_TRUE(client_ctx);
3829 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3830 ASSERT_TRUE(server_ctx);
3831
Adam Langley964256d2020-03-19 11:57:12 -07003832 ASSERT_EQ(nullptr, SSL_CTX_get0_chain(server_ctx.get()));
3833
Adam Langleyd04ca952017-02-28 11:26:51 -08003834 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3835 ASSERT_TRUE(key);
3836 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3837 ASSERT_TRUE(leaf);
3838 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3839 GetChainTestIntermediateBuffer();
3840 ASSERT_TRUE(intermediate);
3841 std::vector<CRYPTO_BUFFER*> chain = {
3842 leaf.get(), intermediate.get(),
3843 };
3844 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3845 chain.size(), key.get(), nullptr));
3846
Adam Langley964256d2020-03-19 11:57:12 -07003847 ASSERT_EQ(chain.size(),
3848 sk_CRYPTO_BUFFER_num(SSL_CTX_get0_chain(server_ctx.get())));
3849
David Benjamin3a1dd462017-07-11 16:13:10 -04003850 SSL_CTX_set_custom_verify(
3851 client_ctx.get(), SSL_VERIFY_PEER,
3852 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3853 return ssl_verify_ok;
3854 });
Adam Langleyd04ca952017-02-28 11:26:51 -08003855
3856 bssl::UniquePtr<SSL> client, server;
3857 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003858 server_ctx.get()));
Adam Langleyd04ca952017-02-28 11:26:51 -08003859}
3860
Matthew Braithwaite5301c102018-01-23 12:08:55 -08003861TEST(SSLTest, BuffersFailWithoutCustomVerify) {
3862 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3863 ASSERT_TRUE(client_ctx);
3864 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3865 ASSERT_TRUE(server_ctx);
3866
3867 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3868 ASSERT_TRUE(key);
3869 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3870 ASSERT_TRUE(leaf);
3871 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
3872 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3873 chain.size(), key.get(), nullptr));
3874
3875 // Without SSL_CTX_set_custom_verify(), i.e. with everything in the default
3876 // configuration, certificate verification should fail.
3877 bssl::UniquePtr<SSL> client, server;
3878 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3879 server_ctx.get()));
3880
3881 // Whereas with a verifier, the connection should succeed.
3882 SSL_CTX_set_custom_verify(
3883 client_ctx.get(), SSL_VERIFY_PEER,
3884 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3885 return ssl_verify_ok;
3886 });
3887 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3888 server_ctx.get()));
3889}
3890
3891TEST(SSLTest, CustomVerify) {
3892 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3893 ASSERT_TRUE(client_ctx);
3894 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3895 ASSERT_TRUE(server_ctx);
3896
3897 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3898 ASSERT_TRUE(key);
3899 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3900 ASSERT_TRUE(leaf);
3901 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
3902 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3903 chain.size(), key.get(), nullptr));
3904
3905 SSL_CTX_set_custom_verify(
3906 client_ctx.get(), SSL_VERIFY_PEER,
3907 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3908 return ssl_verify_ok;
3909 });
3910
3911 bssl::UniquePtr<SSL> client, server;
3912 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3913 server_ctx.get()));
3914
3915 // With SSL_VERIFY_PEER, ssl_verify_invalid should result in a dropped
3916 // connection.
3917 SSL_CTX_set_custom_verify(
3918 client_ctx.get(), SSL_VERIFY_PEER,
3919 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3920 return ssl_verify_invalid;
3921 });
3922
3923 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3924 server_ctx.get()));
3925
3926 // But with SSL_VERIFY_NONE, ssl_verify_invalid should not cause a dropped
3927 // connection.
3928 SSL_CTX_set_custom_verify(
3929 client_ctx.get(), SSL_VERIFY_NONE,
3930 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3931 return ssl_verify_invalid;
3932 });
3933
3934 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3935 server_ctx.get()));
3936}
3937
David Benjamin71dfad42017-07-16 17:27:39 -04003938TEST(SSLTest, ClientCABuffers) {
3939 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3940 ASSERT_TRUE(client_ctx);
3941 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3942 ASSERT_TRUE(server_ctx);
3943
3944 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3945 ASSERT_TRUE(key);
3946 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3947 ASSERT_TRUE(leaf);
3948 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3949 GetChainTestIntermediateBuffer();
3950 ASSERT_TRUE(intermediate);
3951 std::vector<CRYPTO_BUFFER *> chain = {
3952 leaf.get(),
3953 intermediate.get(),
3954 };
3955 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3956 chain.size(), key.get(), nullptr));
3957
3958 bssl::UniquePtr<CRYPTO_BUFFER> ca_name(
3959 CRYPTO_BUFFER_new(kTestName, sizeof(kTestName), nullptr));
3960 ASSERT_TRUE(ca_name);
3961 bssl::UniquePtr<STACK_OF(CRYPTO_BUFFER)> ca_names(
3962 sk_CRYPTO_BUFFER_new_null());
3963 ASSERT_TRUE(ca_names);
David Benjamin2908dd12018-06-29 17:46:42 -04003964 ASSERT_TRUE(PushToStack(ca_names.get(), std::move(ca_name)));
David Benjamin71dfad42017-07-16 17:27:39 -04003965 SSL_CTX_set0_client_CAs(server_ctx.get(), ca_names.release());
3966
3967 // Configure client and server to accept all certificates.
3968 SSL_CTX_set_custom_verify(
3969 client_ctx.get(), SSL_VERIFY_PEER,
3970 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3971 return ssl_verify_ok;
3972 });
3973 SSL_CTX_set_custom_verify(
3974 server_ctx.get(), SSL_VERIFY_PEER,
3975 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3976 return ssl_verify_ok;
3977 });
3978
3979 bool cert_cb_called = false;
3980 SSL_CTX_set_cert_cb(
3981 client_ctx.get(),
3982 [](SSL *ssl, void *arg) -> int {
David Benjamin5f001d12018-05-08 16:46:48 -04003983 const STACK_OF(CRYPTO_BUFFER) *peer_names =
David Benjamin71dfad42017-07-16 17:27:39 -04003984 SSL_get0_server_requested_CAs(ssl);
3985 EXPECT_EQ(1u, sk_CRYPTO_BUFFER_num(peer_names));
3986 CRYPTO_BUFFER *peer_name = sk_CRYPTO_BUFFER_value(peer_names, 0);
3987 EXPECT_EQ(Bytes(kTestName), Bytes(CRYPTO_BUFFER_data(peer_name),
3988 CRYPTO_BUFFER_len(peer_name)));
3989 *reinterpret_cast<bool *>(arg) = true;
3990 return 1;
3991 },
3992 &cert_cb_called);
3993
3994 bssl::UniquePtr<SSL> client, server;
3995 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003996 server_ctx.get()));
David Benjamin71dfad42017-07-16 17:27:39 -04003997 EXPECT_TRUE(cert_cb_called);
3998}
3999
David Benjamin91222b82017-03-09 20:10:56 -05004000// Configuring the empty cipher list, though an error, should still modify the
4001// configuration.
4002TEST(SSLTest, EmptyCipherList) {
4003 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4004 ASSERT_TRUE(ctx);
4005
4006 // Initially, the cipher list is not empty.
4007 EXPECT_NE(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
4008
4009 // Configuring the empty cipher list fails.
4010 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), ""));
4011 ERR_clear_error();
4012
4013 // But the cipher list is still updated to empty.
4014 EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
4015}
4016
Adam Langley4c341d02017-03-08 19:33:21 -08004017// ssl_test_ticket_aead_failure_mode enumerates the possible ways in which the
4018// test |SSL_TICKET_AEAD_METHOD| can fail.
4019enum ssl_test_ticket_aead_failure_mode {
4020 ssl_test_ticket_aead_ok = 0,
4021 ssl_test_ticket_aead_seal_fail,
4022 ssl_test_ticket_aead_open_soft_fail,
4023 ssl_test_ticket_aead_open_hard_fail,
4024};
4025
4026struct ssl_test_ticket_aead_state {
4027 unsigned retry_count;
4028 ssl_test_ticket_aead_failure_mode failure_mode;
4029};
4030
4031static int ssl_test_ticket_aead_ex_index_dup(CRYPTO_EX_DATA *to,
4032 const CRYPTO_EX_DATA *from,
4033 void **from_d, int index,
4034 long argl, void *argp) {
4035 abort();
4036}
4037
4038static void ssl_test_ticket_aead_ex_index_free(void *parent, void *ptr,
4039 CRYPTO_EX_DATA *ad, int index,
4040 long argl, void *argp) {
4041 auto state = reinterpret_cast<ssl_test_ticket_aead_state*>(ptr);
4042 if (state == nullptr) {
4043 return;
4044 }
4045
4046 OPENSSL_free(state);
4047}
4048
4049static CRYPTO_once_t g_ssl_test_ticket_aead_ex_index_once = CRYPTO_ONCE_INIT;
4050static int g_ssl_test_ticket_aead_ex_index;
4051
4052static int ssl_test_ticket_aead_get_ex_index() {
4053 CRYPTO_once(&g_ssl_test_ticket_aead_ex_index_once, [] {
4054 g_ssl_test_ticket_aead_ex_index = SSL_get_ex_new_index(
4055 0, nullptr, nullptr, ssl_test_ticket_aead_ex_index_dup,
4056 ssl_test_ticket_aead_ex_index_free);
4057 });
4058 return g_ssl_test_ticket_aead_ex_index;
4059}
4060
4061static size_t ssl_test_ticket_aead_max_overhead(SSL *ssl) {
4062 return 1;
4063}
4064
4065static int ssl_test_ticket_aead_seal(SSL *ssl, uint8_t *out, size_t *out_len,
4066 size_t max_out_len, const uint8_t *in,
4067 size_t in_len) {
4068 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
4069 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
4070
4071 if (state->failure_mode == ssl_test_ticket_aead_seal_fail ||
4072 max_out_len < in_len + 1) {
4073 return 0;
4074 }
4075
4076 OPENSSL_memmove(out, in, in_len);
4077 out[in_len] = 0xff;
4078 *out_len = in_len + 1;
4079
4080 return 1;
4081}
4082
4083static ssl_ticket_aead_result_t ssl_test_ticket_aead_open(
4084 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len,
4085 const uint8_t *in, size_t in_len) {
4086 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
4087 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
4088
4089 if (state->retry_count > 0) {
4090 state->retry_count--;
4091 return ssl_ticket_aead_retry;
4092 }
4093
4094 switch (state->failure_mode) {
4095 case ssl_test_ticket_aead_ok:
4096 break;
4097 case ssl_test_ticket_aead_seal_fail:
4098 // If |seal| failed then there shouldn't be any ticket to try and
4099 // decrypt.
4100 abort();
4101 break;
4102 case ssl_test_ticket_aead_open_soft_fail:
4103 return ssl_ticket_aead_ignore_ticket;
4104 case ssl_test_ticket_aead_open_hard_fail:
4105 return ssl_ticket_aead_error;
4106 }
4107
4108 if (in_len == 0 || in[in_len - 1] != 0xff) {
4109 return ssl_ticket_aead_ignore_ticket;
4110 }
4111
4112 if (max_out_len < in_len - 1) {
4113 return ssl_ticket_aead_error;
4114 }
4115
4116 OPENSSL_memmove(out, in, in_len - 1);
4117 *out_len = in_len - 1;
4118 return ssl_ticket_aead_success;
4119}
4120
4121static const SSL_TICKET_AEAD_METHOD kSSLTestTicketMethod = {
4122 ssl_test_ticket_aead_max_overhead,
4123 ssl_test_ticket_aead_seal,
4124 ssl_test_ticket_aead_open,
4125};
4126
4127static void ConnectClientAndServerWithTicketMethod(
4128 bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
4129 SSL_CTX *client_ctx, SSL_CTX *server_ctx, unsigned retry_count,
4130 ssl_test_ticket_aead_failure_mode failure_mode, SSL_SESSION *session) {
4131 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
4132 ASSERT_TRUE(client);
4133 ASSERT_TRUE(server);
4134 SSL_set_connect_state(client.get());
4135 SSL_set_accept_state(server.get());
4136
4137 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
4138 OPENSSL_malloc(sizeof(ssl_test_ticket_aead_state)));
4139 ASSERT_TRUE(state);
4140 OPENSSL_memset(state, 0, sizeof(ssl_test_ticket_aead_state));
4141 state->retry_count = retry_count;
4142 state->failure_mode = failure_mode;
4143
4144 ASSERT_TRUE(SSL_set_ex_data(server.get(), ssl_test_ticket_aead_get_ex_index(),
4145 state));
4146
4147 SSL_set_session(client.get(), session);
4148
4149 BIO *bio1, *bio2;
4150 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
4151
4152 // SSL_set_bio takes ownership.
4153 SSL_set_bio(client.get(), bio1, bio1);
4154 SSL_set_bio(server.get(), bio2, bio2);
4155
4156 if (CompleteHandshakes(client.get(), server.get())) {
4157 *out_client = std::move(client);
4158 *out_server = std::move(server);
4159 } else {
4160 out_client->reset();
4161 out_server->reset();
4162 }
4163}
4164
David Benjaminc9775322018-04-13 16:39:12 -04004165using TicketAEADMethodParam =
4166 testing::tuple<uint16_t, unsigned, ssl_test_ticket_aead_failure_mode>;
4167
Adam Langley4c341d02017-03-08 19:33:21 -08004168class TicketAEADMethodTest
David Benjaminc9775322018-04-13 16:39:12 -04004169 : public ::testing::TestWithParam<TicketAEADMethodParam> {};
Adam Langley4c341d02017-03-08 19:33:21 -08004170
4171TEST_P(TicketAEADMethodTest, Resume) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04004172 bssl::UniquePtr<SSL_CTX> server_ctx =
4173 CreateContextWithTestCertificate(TLS_method());
Adam Langley4c341d02017-03-08 19:33:21 -08004174 ASSERT_TRUE(server_ctx);
4175 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4176 ASSERT_TRUE(client_ctx);
4177
4178 const uint16_t version = testing::get<0>(GetParam());
4179 const unsigned retry_count = testing::get<1>(GetParam());
4180 const ssl_test_ticket_aead_failure_mode failure_mode =
4181 testing::get<2>(GetParam());
4182
Adam Langley4c341d02017-03-08 19:33:21 -08004183 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), version));
4184 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), version));
4185 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), version));
4186 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), version));
4187
4188 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
4189 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
4190 SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
4191 SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
David Benjamin707af292017-03-10 17:47:18 -05004192 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langley4c341d02017-03-08 19:33:21 -08004193
4194 SSL_CTX_set_ticket_aead_method(server_ctx.get(), &kSSLTestTicketMethod);
4195
4196 bssl::UniquePtr<SSL> client, server;
4197 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
4198 server_ctx.get(), retry_count,
4199 failure_mode, nullptr);
4200 switch (failure_mode) {
4201 case ssl_test_ticket_aead_ok:
4202 case ssl_test_ticket_aead_open_hard_fail:
4203 case ssl_test_ticket_aead_open_soft_fail:
4204 ASSERT_TRUE(client);
4205 break;
4206 case ssl_test_ticket_aead_seal_fail:
4207 EXPECT_FALSE(client);
4208 return;
4209 }
4210 EXPECT_FALSE(SSL_session_reused(client.get()));
4211 EXPECT_FALSE(SSL_session_reused(server.get()));
4212
Steven Valdez777a2392019-02-21 11:30:47 -05004213 ASSERT_TRUE(FlushNewSessionTickets(client.get(), server.get()));
David Benjamin707af292017-03-10 17:47:18 -05004214 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
Adam Langley4c341d02017-03-08 19:33:21 -08004215 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
4216 server_ctx.get(), retry_count,
David Benjamin707af292017-03-10 17:47:18 -05004217 failure_mode, session.get());
Adam Langley4c341d02017-03-08 19:33:21 -08004218 switch (failure_mode) {
4219 case ssl_test_ticket_aead_ok:
4220 ASSERT_TRUE(client);
4221 EXPECT_TRUE(SSL_session_reused(client.get()));
4222 EXPECT_TRUE(SSL_session_reused(server.get()));
4223 break;
4224 case ssl_test_ticket_aead_seal_fail:
4225 abort();
4226 break;
4227 case ssl_test_ticket_aead_open_hard_fail:
4228 EXPECT_FALSE(client);
4229 break;
4230 case ssl_test_ticket_aead_open_soft_fail:
4231 ASSERT_TRUE(client);
4232 EXPECT_FALSE(SSL_session_reused(client.get()));
4233 EXPECT_FALSE(SSL_session_reused(server.get()));
4234 }
4235}
4236
David Benjaminc9775322018-04-13 16:39:12 -04004237std::string TicketAEADMethodParamToString(
4238 const testing::TestParamInfo<TicketAEADMethodParam> &params) {
4239 std::string ret = GetVersionName(std::get<0>(params.param));
4240 // GTest only allows alphanumeric characters and '_' in the parameter
4241 // string. Additionally filter out the 'v' to get "TLS13" over "TLSv13".
4242 for (auto it = ret.begin(); it != ret.end();) {
4243 if (*it == '.' || *it == 'v') {
4244 it = ret.erase(it);
4245 } else {
4246 ++it;
4247 }
4248 }
4249 char retry_count[256];
4250 snprintf(retry_count, sizeof(retry_count), "%d", std::get<1>(params.param));
4251 ret += "_";
4252 ret += retry_count;
4253 ret += "Retries_";
4254 switch (std::get<2>(params.param)) {
4255 case ssl_test_ticket_aead_ok:
4256 ret += "OK";
4257 break;
4258 case ssl_test_ticket_aead_seal_fail:
4259 ret += "SealFail";
4260 break;
4261 case ssl_test_ticket_aead_open_soft_fail:
4262 ret += "OpenSoftFail";
4263 break;
4264 case ssl_test_ticket_aead_open_hard_fail:
4265 ret += "OpenHardFail";
4266 break;
4267 }
4268 return ret;
4269}
4270
David Benjaminbe7006a2019-04-09 18:05:02 -05004271INSTANTIATE_TEST_SUITE_P(
Adam Langley4c341d02017-03-08 19:33:21 -08004272 TicketAEADMethodTests, TicketAEADMethodTest,
David Benjaminc9775322018-04-13 16:39:12 -04004273 testing::Combine(testing::Values(TLS1_2_VERSION, TLS1_3_VERSION),
4274 testing::Values(0, 1, 2),
4275 testing::Values(ssl_test_ticket_aead_ok,
4276 ssl_test_ticket_aead_seal_fail,
4277 ssl_test_ticket_aead_open_soft_fail,
4278 ssl_test_ticket_aead_open_hard_fail)),
4279 TicketAEADMethodParamToString);
Adam Langley4c341d02017-03-08 19:33:21 -08004280
David Benjaminca743582017-06-15 17:51:35 -04004281TEST(SSLTest, SelectNextProto) {
4282 uint8_t *result;
4283 uint8_t result_len;
4284
4285 // If there is an overlap, it should be returned.
4286 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
4287 SSL_select_next_proto(&result, &result_len,
4288 (const uint8_t *)"\1a\2bb\3ccc", 9,
4289 (const uint8_t *)"\1x\1y\1a\1z", 8));
4290 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
4291
4292 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
4293 SSL_select_next_proto(&result, &result_len,
4294 (const uint8_t *)"\1a\2bb\3ccc", 9,
4295 (const uint8_t *)"\1x\1y\2bb\1z", 9));
4296 EXPECT_EQ(Bytes("bb"), Bytes(result, result_len));
4297
4298 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
4299 SSL_select_next_proto(&result, &result_len,
4300 (const uint8_t *)"\1a\2bb\3ccc", 9,
4301 (const uint8_t *)"\1x\1y\3ccc\1z", 10));
4302 EXPECT_EQ(Bytes("ccc"), Bytes(result, result_len));
4303
4304 // Peer preference order takes precedence over local.
4305 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
4306 SSL_select_next_proto(&result, &result_len,
4307 (const uint8_t *)"\1a\2bb\3ccc", 9,
4308 (const uint8_t *)"\3ccc\2bb\1a", 9));
4309 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
4310
4311 // If there is no overlap, return the first local protocol.
4312 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
4313 SSL_select_next_proto(&result, &result_len,
4314 (const uint8_t *)"\1a\2bb\3ccc", 9,
4315 (const uint8_t *)"\1x\2yy\3zzz", 9));
4316 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
4317
4318 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
4319 SSL_select_next_proto(&result, &result_len, nullptr, 0,
4320 (const uint8_t *)"\1x\2yy\3zzz", 9));
4321 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
4322}
4323
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004324TEST(SSLTest, SealRecord) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004325 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004326 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004327 ASSERT_TRUE(client_ctx);
4328 ASSERT_TRUE(server_ctx);
4329
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004330 bssl::UniquePtr<SSL> client, server;
4331 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004332 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004333
4334 const std::vector<uint8_t> record = {1, 2, 3, 4, 5};
4335 std::vector<uint8_t> prefix(
4336 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004337 body(record.size()),
4338 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004339 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4340 bssl::MakeSpan(body), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004341 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004342
4343 std::vector<uint8_t> sealed;
4344 sealed.insert(sealed.end(), prefix.begin(), prefix.end());
4345 sealed.insert(sealed.end(), body.begin(), body.end());
4346 sealed.insert(sealed.end(), suffix.begin(), suffix.end());
4347 std::vector<uint8_t> sealed_copy = sealed;
4348
4349 bssl::Span<uint8_t> plaintext;
4350 size_t record_len;
4351 uint8_t alert = 255;
4352 EXPECT_EQ(bssl::OpenRecord(server.get(), &plaintext, &record_len, &alert,
4353 bssl::MakeSpan(sealed)),
4354 bssl::OpenRecordResult::kOK);
4355 EXPECT_EQ(record_len, sealed.size());
4356 EXPECT_EQ(plaintext, record);
4357 EXPECT_EQ(255, alert);
4358}
4359
4360TEST(SSLTest, SealRecordInPlace) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004361 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004362 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004363 ASSERT_TRUE(client_ctx);
4364 ASSERT_TRUE(server_ctx);
4365
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004366 bssl::UniquePtr<SSL> client, server;
4367 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004368 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004369
4370 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
4371 std::vector<uint8_t> record = plaintext;
4372 std::vector<uint8_t> prefix(
4373 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004374 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004375 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4376 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004377 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004378 record.insert(record.begin(), prefix.begin(), prefix.end());
4379 record.insert(record.end(), suffix.begin(), suffix.end());
4380
4381 bssl::Span<uint8_t> result;
4382 size_t record_len;
4383 uint8_t alert;
4384 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
4385 bssl::MakeSpan(record)),
4386 bssl::OpenRecordResult::kOK);
4387 EXPECT_EQ(record_len, record.size());
4388 EXPECT_EQ(plaintext, result);
4389}
4390
4391TEST(SSLTest, SealRecordTrailingData) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004392 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004393 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004394 ASSERT_TRUE(client_ctx);
4395 ASSERT_TRUE(server_ctx);
4396
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004397 bssl::UniquePtr<SSL> client, server;
4398 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004399 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004400
4401 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
4402 std::vector<uint8_t> record = plaintext;
4403 std::vector<uint8_t> prefix(
4404 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004405 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004406 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4407 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004408 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004409 record.insert(record.begin(), prefix.begin(), prefix.end());
4410 record.insert(record.end(), suffix.begin(), suffix.end());
4411 record.insert(record.end(), {5, 4, 3, 2, 1});
4412
4413 bssl::Span<uint8_t> result;
4414 size_t record_len;
4415 uint8_t alert;
4416 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
4417 bssl::MakeSpan(record)),
4418 bssl::OpenRecordResult::kOK);
4419 EXPECT_EQ(record_len, record.size() - 5);
4420 EXPECT_EQ(plaintext, result);
4421}
4422
4423TEST(SSLTest, SealRecordInvalidSpanSize) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004424 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004425 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004426 ASSERT_TRUE(client_ctx);
4427 ASSERT_TRUE(server_ctx);
4428
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004429 bssl::UniquePtr<SSL> client, server;
4430 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004431 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004432
4433 std::vector<uint8_t> record = {1, 2, 3, 4, 5};
4434 std::vector<uint8_t> prefix(
4435 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004436 body(record.size()),
4437 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004438
4439 auto expect_err = []() {
4440 int err = ERR_get_error();
4441 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
4442 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_BUFFER_TOO_SMALL);
4443 ERR_clear_error();
4444 };
4445 EXPECT_FALSE(bssl::SealRecord(
4446 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004447 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004448 expect_err();
4449 EXPECT_FALSE(bssl::SealRecord(
4450 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004451 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004452 expect_err();
4453
4454 EXPECT_FALSE(
4455 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4456 bssl::MakeSpan(record.data(), record.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004457 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004458 expect_err();
4459 EXPECT_FALSE(
4460 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4461 bssl::MakeSpan(record.data(), record.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004462 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004463 expect_err();
4464
4465 EXPECT_FALSE(bssl::SealRecord(
4466 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004467 bssl::MakeSpan(suffix.data(), suffix.size() - 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004468 expect_err();
4469 EXPECT_FALSE(bssl::SealRecord(
4470 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004471 bssl::MakeSpan(suffix.data(), suffix.size() + 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004472 expect_err();
4473}
4474
David Benjamin617b8182017-08-29 15:33:10 -04004475// The client should gracefully handle no suitable ciphers being enabled.
4476TEST(SSLTest, NoCiphersAvailable) {
4477 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4478 ASSERT_TRUE(ctx);
4479
4480 // Configure |client_ctx| with a cipher list that does not intersect with its
4481 // version configuration.
4482 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
4483 ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
4484 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
4485
4486 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
4487 ASSERT_TRUE(ssl);
4488 SSL_set_connect_state(ssl.get());
4489
4490 UniquePtr<BIO> rbio(BIO_new(BIO_s_mem())), wbio(BIO_new(BIO_s_mem()));
4491 ASSERT_TRUE(rbio);
4492 ASSERT_TRUE(wbio);
4493 SSL_set0_rbio(ssl.get(), rbio.release());
4494 SSL_set0_wbio(ssl.get(), wbio.release());
4495
4496 int ret = SSL_do_handshake(ssl.get());
4497 EXPECT_EQ(-1, ret);
4498 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), ret));
4499 uint32_t err = ERR_get_error();
4500 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
4501 EXPECT_EQ(SSL_R_NO_CIPHERS_AVAILABLE, ERR_GET_REASON(err));
4502}
4503
David Benjamina4bafd32017-10-03 15:06:29 -04004504TEST_P(SSLVersionTest, SessionVersion) {
4505 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4506 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4507
4508 bssl::UniquePtr<SSL_SESSION> session =
4509 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4510 ASSERT_TRUE(session);
4511 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
4512
4513 // Sessions in TLS 1.3 and later should be single-use.
4514 EXPECT_EQ(version() == TLS1_3_VERSION,
4515 !!SSL_SESSION_should_be_single_use(session.get()));
4516
4517 // Making fake sessions for testing works.
4518 session.reset(SSL_SESSION_new(client_ctx_.get()));
4519 ASSERT_TRUE(session);
4520 ASSERT_TRUE(SSL_SESSION_set_protocol_version(session.get(), version()));
4521 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
4522}
4523
David Benjaminfdb7a352017-10-12 17:34:18 -04004524TEST_P(SSLVersionTest, SSLPending) {
4525 UniquePtr<SSL> ssl(SSL_new(client_ctx_.get()));
4526 ASSERT_TRUE(ssl);
4527 EXPECT_EQ(0, SSL_pending(ssl.get()));
4528
4529 ASSERT_TRUE(Connect());
4530 EXPECT_EQ(0, SSL_pending(client_.get()));
4531
4532 ASSERT_EQ(5, SSL_write(server_.get(), "hello", 5));
4533 ASSERT_EQ(5, SSL_write(server_.get(), "world", 5));
4534 EXPECT_EQ(0, SSL_pending(client_.get()));
4535
4536 char buf[10];
4537 ASSERT_EQ(1, SSL_peek(client_.get(), buf, 1));
4538 EXPECT_EQ(5, SSL_pending(client_.get()));
4539
4540 ASSERT_EQ(1, SSL_read(client_.get(), buf, 1));
4541 EXPECT_EQ(4, SSL_pending(client_.get()));
4542
4543 ASSERT_EQ(4, SSL_read(client_.get(), buf, 10));
4544 EXPECT_EQ(0, SSL_pending(client_.get()));
4545
4546 ASSERT_EQ(2, SSL_read(client_.get(), buf, 2));
4547 EXPECT_EQ(3, SSL_pending(client_.get()));
4548}
4549
David Benjamina031b612017-10-11 20:48:25 -04004550// Test that post-handshake tickets consumed by |SSL_shutdown| are ignored.
4551TEST(SSLTest, ShutdownIgnoresTickets) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04004552 bssl::UniquePtr<SSL_CTX> ctx(CreateContextWithTestCertificate(TLS_method()));
David Benjamina031b612017-10-11 20:48:25 -04004553 ASSERT_TRUE(ctx);
4554 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_3_VERSION));
4555 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
4556
David Benjamina031b612017-10-11 20:48:25 -04004557 SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_BOTH);
4558
4559 bssl::UniquePtr<SSL> client, server;
4560 ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
4561
4562 SSL_CTX_sess_set_new_cb(ctx.get(), [](SSL *ssl, SSL_SESSION *session) -> int {
4563 ADD_FAILURE() << "New session callback called during SSL_shutdown";
4564 return 0;
4565 });
4566
4567 // Send close_notify.
4568 EXPECT_EQ(0, SSL_shutdown(server.get()));
4569 EXPECT_EQ(0, SSL_shutdown(client.get()));
4570
4571 // Receive close_notify.
4572 EXPECT_EQ(1, SSL_shutdown(server.get()));
4573 EXPECT_EQ(1, SSL_shutdown(client.get()));
4574}
4575
David Benjamin6cc352e2017-11-02 17:21:39 -04004576TEST(SSLTest, SignatureAlgorithmProperties) {
4577 EXPECT_EQ(EVP_PKEY_NONE, SSL_get_signature_algorithm_key_type(0x1234));
4578 EXPECT_EQ(nullptr, SSL_get_signature_algorithm_digest(0x1234));
4579 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(0x1234));
4580
4581 EXPECT_EQ(EVP_PKEY_RSA,
4582 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4583 EXPECT_EQ(EVP_md5_sha1(),
4584 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4585 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4586
4587 EXPECT_EQ(EVP_PKEY_EC, SSL_get_signature_algorithm_key_type(
4588 SSL_SIGN_ECDSA_SECP256R1_SHA256));
4589 EXPECT_EQ(EVP_sha256(), SSL_get_signature_algorithm_digest(
4590 SSL_SIGN_ECDSA_SECP256R1_SHA256));
4591 EXPECT_FALSE(
4592 SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_ECDSA_SECP256R1_SHA256));
4593
4594 EXPECT_EQ(EVP_PKEY_RSA,
David Benjamin6879e192018-04-13 16:01:02 -04004595 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04004596 EXPECT_EQ(EVP_sha384(),
David Benjamin6879e192018-04-13 16:01:02 -04004597 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PSS_RSAE_SHA384));
4598 EXPECT_TRUE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04004599}
4600
Adam Langley85967952018-07-03 08:04:58 -07004601static int XORCompressFunc(SSL *ssl, CBB *out, const uint8_t *in,
4602 size_t in_len) {
4603 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07004604 if (!CBB_add_u8(out, in[i] ^ 0x55)) {
Adam Langley85967952018-07-03 08:04:58 -07004605 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07004606 }
4607 }
4608
4609 SSL_set_app_data(ssl, XORCompressFunc);
4610
Adam Langley85967952018-07-03 08:04:58 -07004611 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07004612}
4613
Adam Langley85967952018-07-03 08:04:58 -07004614static int XORDecompressFunc(SSL *ssl, CRYPTO_BUFFER **out,
4615 size_t uncompressed_len, const uint8_t *in,
4616 size_t in_len) {
4617 if (in_len != uncompressed_len) {
4618 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07004619 }
4620
4621 uint8_t *data;
Adam Langley85967952018-07-03 08:04:58 -07004622 *out = CRYPTO_BUFFER_alloc(&data, uncompressed_len);
4623 if (*out == nullptr) {
4624 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07004625 }
4626
Adam Langley85967952018-07-03 08:04:58 -07004627 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07004628 data[i] = in[i] ^ 0x55;
4629 }
4630
4631 SSL_set_app_data(ssl, XORDecompressFunc);
4632
Adam Langley85967952018-07-03 08:04:58 -07004633 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07004634}
4635
4636TEST(SSLTest, CertCompression) {
4637 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04004638 bssl::UniquePtr<SSL_CTX> server_ctx(
4639 CreateContextWithTestCertificate(TLS_method()));
Adam Langley0080d832018-06-07 16:39:49 -07004640 ASSERT_TRUE(client_ctx);
4641 ASSERT_TRUE(server_ctx);
4642
Adam Langley0080d832018-06-07 16:39:49 -07004643 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
4644 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
4645 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
4646 client_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
4647 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
4648 server_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
4649
4650 bssl::UniquePtr<SSL> client, server;
4651 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4652 server_ctx.get()));
4653
4654 EXPECT_TRUE(SSL_get_app_data(client.get()) == XORDecompressFunc);
4655 EXPECT_TRUE(SSL_get_app_data(server.get()) == XORCompressFunc);
4656}
4657
Adam Langleyddb57cf2018-01-26 09:17:53 -08004658void MoveBIOs(SSL *dest, SSL *src) {
4659 BIO *rbio = SSL_get_rbio(src);
4660 BIO_up_ref(rbio);
4661 SSL_set0_rbio(dest, rbio);
4662
4663 BIO *wbio = SSL_get_wbio(src);
4664 BIO_up_ref(wbio);
4665 SSL_set0_wbio(dest, wbio);
4666
4667 SSL_set0_rbio(src, nullptr);
4668 SSL_set0_wbio(src, nullptr);
4669}
4670
4671TEST(SSLTest, Handoff) {
4672 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4673 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04004674 bssl::UniquePtr<SSL_CTX> handshaker_ctx(
4675 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004676 ASSERT_TRUE(client_ctx);
4677 ASSERT_TRUE(server_ctx);
4678 ASSERT_TRUE(handshaker_ctx);
4679
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004680 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_CLIENT);
4681 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langleyddb57cf2018-01-26 09:17:53 -08004682 SSL_CTX_set_handoff_mode(server_ctx.get(), 1);
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004683 uint8_t keys[48];
David Benjamin243b5cc2019-12-04 11:23:50 -05004684 SSL_CTX_get_tlsext_ticket_keys(server_ctx.get(), &keys, sizeof(keys));
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004685 SSL_CTX_set_tlsext_ticket_keys(handshaker_ctx.get(), &keys, sizeof(keys));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004686
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004687 for (bool early_data : {false, true}) {
4688 SCOPED_TRACE(early_data);
4689 for (bool is_resume : {false, true}) {
4690 SCOPED_TRACE(is_resume);
4691 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04004692 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
4693 server_ctx.get()));
4694 SSL_set_early_data_enabled(client.get(), early_data);
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004695 if (is_resume) {
4696 ASSERT_TRUE(g_last_session);
David Benjamin9b2cdb72021-04-01 23:21:53 -04004697 SSL_set_session(client.get(), g_last_session.get());
4698 if (early_data) {
4699 EXPECT_GT(g_last_session->ticket_max_early_data, 0u);
4700 }
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004701 }
David Benjamin9b2cdb72021-04-01 23:21:53 -04004702
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004703
4704 int client_ret = SSL_do_handshake(client.get());
4705 int client_err = SSL_get_error(client.get(), client_ret);
4706
4707 uint8_t byte_written;
David Benjamin9b2cdb72021-04-01 23:21:53 -04004708 if (early_data && is_resume) {
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004709 ASSERT_EQ(client_err, 0);
4710 EXPECT_TRUE(SSL_in_early_data(client.get()));
4711 // Attempt to write early data.
4712 byte_written = 43;
4713 EXPECT_EQ(SSL_write(client.get(), &byte_written, 1), 1);
4714 } else {
4715 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4716 }
4717
4718 int server_ret = SSL_do_handshake(server.get());
4719 int server_err = SSL_get_error(server.get(), server_ret);
4720 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
4721
4722 ScopedCBB cbb;
4723 Array<uint8_t> handoff;
4724 SSL_CLIENT_HELLO hello;
4725 ASSERT_TRUE(CBB_init(cbb.get(), 256));
4726 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
4727 ASSERT_TRUE(CBBFinishArray(cbb.get(), &handoff));
4728
4729 bssl::UniquePtr<SSL> handshaker(SSL_new(handshaker_ctx.get()));
4730 // Note split handshakes determines 0-RTT support, for both the current
4731 // handshake and newly-issued tickets, entirely by |handshaker|. There is
4732 // no need to call |SSL_set_early_data_enabled| on |server|.
4733 SSL_set_early_data_enabled(handshaker.get(), 1);
4734 ASSERT_TRUE(SSL_apply_handoff(handshaker.get(), handoff));
4735
4736 MoveBIOs(handshaker.get(), server.get());
4737
4738 int handshake_ret = SSL_do_handshake(handshaker.get());
4739 int handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
4740 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
4741
4742 // Double-check that additional calls to |SSL_do_handshake| continue
Adam Langley472d91c2020-02-18 12:12:35 -08004743 // to get |SSL_ERROR_HANDBACK|.
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004744 handshake_ret = SSL_do_handshake(handshaker.get());
4745 handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
4746 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
4747
4748 ScopedCBB cbb_handback;
4749 Array<uint8_t> handback;
4750 ASSERT_TRUE(CBB_init(cbb_handback.get(), 1024));
4751 ASSERT_TRUE(SSL_serialize_handback(handshaker.get(), cbb_handback.get()));
4752 ASSERT_TRUE(CBBFinishArray(cbb_handback.get(), &handback));
4753
4754 bssl::UniquePtr<SSL> server2(SSL_new(server_ctx.get()));
4755 ASSERT_TRUE(SSL_apply_handback(server2.get(), handback));
4756
4757 MoveBIOs(server2.get(), handshaker.get());
4758 ASSERT_TRUE(CompleteHandshakes(client.get(), server2.get()));
4759 EXPECT_EQ(is_resume, SSL_session_reused(client.get()));
4760
David Benjamin9b2cdb72021-04-01 23:21:53 -04004761 if (early_data && is_resume) {
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004762 // In this case, one byte of early data has already been written above.
4763 EXPECT_TRUE(SSL_early_data_accepted(client.get()));
4764 } else {
4765 byte_written = 42;
4766 EXPECT_EQ(SSL_write(client.get(), &byte_written, 1), 1);
4767 }
4768 uint8_t byte;
4769 EXPECT_EQ(SSL_read(server2.get(), &byte, 1), 1);
4770 EXPECT_EQ(byte_written, byte);
4771
4772 byte = 44;
4773 EXPECT_EQ(SSL_write(server2.get(), &byte, 1), 1);
4774 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
4775 EXPECT_EQ(44, byte);
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004776 }
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004777 }
Adam Langleyddb57cf2018-01-26 09:17:53 -08004778}
4779
4780TEST(SSLTest, HandoffDeclined) {
4781 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04004782 bssl::UniquePtr<SSL_CTX> server_ctx(
4783 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004784 ASSERT_TRUE(client_ctx);
4785 ASSERT_TRUE(server_ctx);
4786
4787 SSL_CTX_set_handoff_mode(server_ctx.get(), 1);
4788 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
4789
Adam Langleyddb57cf2018-01-26 09:17:53 -08004790 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04004791 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
4792 server_ctx.get()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004793
4794 int client_ret = SSL_do_handshake(client.get());
4795 int client_err = SSL_get_error(client.get(), client_ret);
4796 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4797
4798 int server_ret = SSL_do_handshake(server.get());
4799 int server_err = SSL_get_error(server.get(), server_ret);
4800 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
4801
4802 ScopedCBB cbb;
Adam Langleyc9827e02019-04-12 14:46:50 -07004803 SSL_CLIENT_HELLO hello;
Adam Langleyddb57cf2018-01-26 09:17:53 -08004804 ASSERT_TRUE(CBB_init(cbb.get(), 256));
Adam Langleyc9827e02019-04-12 14:46:50 -07004805 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004806
4807 ASSERT_TRUE(SSL_decline_handoff(server.get()));
4808
4809 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
4810
4811 uint8_t byte = 42;
4812 EXPECT_EQ(SSL_write(client.get(), &byte, 1), 1);
4813 EXPECT_EQ(SSL_read(server.get(), &byte, 1), 1);
4814 EXPECT_EQ(42, byte);
4815
4816 byte = 43;
4817 EXPECT_EQ(SSL_write(server.get(), &byte, 1), 1);
4818 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
4819 EXPECT_EQ(43, byte);
4820}
4821
Adam Langley826ce152018-08-03 10:31:21 -07004822static std::string SigAlgsToString(Span<const uint16_t> sigalgs) {
4823 std::string ret = "{";
4824
4825 for (uint16_t v : sigalgs) {
4826 if (ret.size() > 1) {
4827 ret += ", ";
4828 }
4829
4830 char buf[8];
4831 snprintf(buf, sizeof(buf) - 1, "0x%02x", v);
4832 buf[sizeof(buf)-1] = 0;
4833 ret += std::string(buf);
4834 }
4835
4836 ret += "}";
4837 return ret;
4838}
4839
4840void ExpectSigAlgsEqual(Span<const uint16_t> expected,
4841 Span<const uint16_t> actual) {
4842 bool matches = false;
4843 if (expected.size() == actual.size()) {
4844 matches = true;
4845
4846 for (size_t i = 0; i < expected.size(); i++) {
4847 if (expected[i] != actual[i]) {
4848 matches = false;
4849 break;
4850 }
4851 }
4852 }
4853
4854 if (!matches) {
4855 ADD_FAILURE() << "expected: " << SigAlgsToString(expected)
4856 << " got: " << SigAlgsToString(actual);
4857 }
4858}
4859
4860TEST(SSLTest, SigAlgs) {
4861 static const struct {
4862 std::vector<int> input;
4863 bool ok;
4864 std::vector<uint16_t> expected;
4865 } kTests[] = {
4866 {{}, true, {}},
4867 {{1}, false, {}},
4868 {{1, 2, 3}, false, {}},
4869 {{NID_sha256, EVP_PKEY_ED25519}, false, {}},
4870 {{NID_sha256, EVP_PKEY_RSA, NID_sha256, EVP_PKEY_RSA}, false, {}},
4871
4872 {{NID_sha256, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA256}},
4873 {{NID_sha512, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA512}},
4874 {{NID_sha256, EVP_PKEY_RSA_PSS}, true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4875 {{NID_undef, EVP_PKEY_ED25519}, true, {SSL_SIGN_ED25519}},
4876 {{NID_undef, EVP_PKEY_ED25519, NID_sha384, EVP_PKEY_EC},
4877 true,
4878 {SSL_SIGN_ED25519, SSL_SIGN_ECDSA_SECP384R1_SHA384}},
4879 };
4880
4881 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4882
4883 unsigned n = 1;
4884 for (const auto &test : kTests) {
4885 SCOPED_TRACE(n++);
4886
4887 const bool ok =
4888 SSL_CTX_set1_sigalgs(ctx.get(), test.input.data(), test.input.size());
4889 EXPECT_EQ(ok, test.ok);
4890
4891 if (!ok) {
4892 ERR_clear_error();
4893 }
4894
4895 if (!test.ok) {
4896 continue;
4897 }
4898
4899 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
4900 }
4901}
4902
4903TEST(SSLTest, SigAlgsList) {
4904 static const struct {
4905 const char *input;
4906 bool ok;
4907 std::vector<uint16_t> expected;
4908 } kTests[] = {
4909 {"", false, {}},
4910 {":", false, {}},
4911 {"+", false, {}},
4912 {"RSA", false, {}},
4913 {"RSA+", false, {}},
4914 {"RSA+SHA256:", false, {}},
4915 {":RSA+SHA256:", false, {}},
4916 {":RSA+SHA256+:", false, {}},
4917 {"!", false, {}},
4918 {"\x01", false, {}},
4919 {"RSA+SHA256:RSA+SHA384:RSA+SHA256", false, {}},
4920 {"RSA-PSS+SHA256:rsa_pss_rsae_sha256", false, {}},
4921
4922 {"RSA+SHA256", true, {SSL_SIGN_RSA_PKCS1_SHA256}},
4923 {"RSA+SHA256:ed25519",
4924 true,
4925 {SSL_SIGN_RSA_PKCS1_SHA256, SSL_SIGN_ED25519}},
4926 {"ECDSA+SHA256:RSA+SHA512",
4927 true,
4928 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PKCS1_SHA512}},
4929 {"ecdsa_secp256r1_sha256:rsa_pss_rsae_sha256",
4930 true,
4931 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4932 {"RSA-PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4933 {"PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4934 };
4935
4936 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4937
4938 unsigned n = 1;
4939 for (const auto &test : kTests) {
4940 SCOPED_TRACE(n++);
4941
4942 const bool ok = SSL_CTX_set1_sigalgs_list(ctx.get(), test.input);
4943 EXPECT_EQ(ok, test.ok);
4944
4945 if (!ok) {
4946 if (test.ok) {
4947 ERR_print_errors_fp(stderr);
4948 }
4949 ERR_clear_error();
4950 }
4951
4952 if (!test.ok) {
4953 continue;
4954 }
4955
4956 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
4957 }
4958}
4959
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004960TEST(SSLTest, ApplyHandoffRemovesUnsupportedCiphers) {
4961 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4962 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
4963
4964 // handoff is a handoff message that has been artificially modified to pretend
4965 // that only cipher 0x0A is supported. When it is applied to |server|, all
4966 // ciphers but that one should be removed.
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004967 //
4968 // To make a new one of these, try sticking this in the |Handoff| test above:
4969 //
4970 // hexdump(stderr, "", handoff.data(), handoff.size());
4971 // sed -e 's/\(..\)/0x\1, /g'
4972 //
4973 // and modify serialize_features() to emit only cipher 0x0A.
4974
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004975 uint8_t handoff[] = {
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004976 0x30, 0x81, 0x9a, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
4977 0x00, 0x00, 0x7e, 0x03, 0x03, 0x30, 0x8e, 0x8f, 0x79, 0xd2, 0x87, 0x39,
4978 0xc2, 0x23, 0x23, 0x13, 0xca, 0x3c, 0x80, 0x44, 0xfd, 0x80, 0x83, 0x62,
4979 0x3c, 0xcc, 0xf8, 0x76, 0xd3, 0x62, 0xbb, 0x54, 0xe3, 0xc4, 0x39, 0x24,
4980 0xa5, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004981 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
4982 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004983 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
4984 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
4985 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
4986 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
4987 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x02, 0x00,
4988 0x0a, 0x04, 0x0a, 0x00, 0x15, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00,
4989 0x1d,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004990 };
4991
4992 EXPECT_EQ(20u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
4993 ASSERT_TRUE(
4994 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
4995 EXPECT_EQ(1u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
4996}
4997
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004998TEST(SSLTest, ApplyHandoffRemovesUnsupportedCurves) {
4999 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
5000 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
5001
5002 // handoff is a handoff message that has been artificially modified to pretend
5003 // that only one curve is supported. When it is applied to |server|, all
5004 // curves but that one should be removed.
5005 //
5006 // See |ApplyHandoffRemovesUnsupportedCiphers| for how to make a new one of
5007 // these.
5008 uint8_t handoff[] = {
5009 0x30, 0x81, 0xc0, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
5010 0x00, 0x00, 0x7e, 0x03, 0x03, 0x98, 0x30, 0xce, 0xd9, 0xb0, 0xdf, 0x5f,
5011 0x82, 0x05, 0x4a, 0x43, 0x67, 0x7e, 0xdb, 0x6a, 0x4f, 0x21, 0x18, 0x4e,
5012 0x0d, 0x94, 0x63, 0x18, 0x8b, 0x54, 0x89, 0xdb, 0x8b, 0x1d, 0x84, 0xbc,
5013 0x09, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
5014 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
5015 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
5016 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
5017 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
5018 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
5019 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
5020 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x30, 0x00,
5021 0x02, 0x00, 0x0a, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x8c, 0x00, 0x8d, 0x00,
5022 0x9c, 0x00, 0x9d, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xc0, 0x09, 0xc0,
5023 0x0a, 0xc0, 0x13, 0xc0, 0x14, 0xc0, 0x2b, 0xc0, 0x2c, 0xc0, 0x2f, 0xc0,
5024 0x30, 0xc0, 0x35, 0xc0, 0x36, 0xcc, 0xa8, 0xcc, 0xa9, 0xcc, 0xac, 0x04,
5025 0x02, 0x00, 0x17,
5026 };
5027
5028 // The zero length means that the default list of groups is used.
5029 EXPECT_EQ(0u, server->config->supported_group_list.size());
5030 ASSERT_TRUE(
5031 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
5032 EXPECT_EQ(1u, server->config->supported_group_list.size());
5033}
5034
Adam Langleyba9ad662018-12-17 13:59:38 -08005035TEST(SSLTest, ZeroSizedWiteFlushesHandshakeMessages) {
5036 // If there are pending handshake mesages, an |SSL_write| of zero bytes should
5037 // flush them.
David Benjamin9b2cdb72021-04-01 23:21:53 -04005038 bssl::UniquePtr<SSL_CTX> server_ctx(
5039 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyba9ad662018-12-17 13:59:38 -08005040 EXPECT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
5041 EXPECT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
Adam Langleyba9ad662018-12-17 13:59:38 -08005042
5043 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
5044 EXPECT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
5045 EXPECT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
5046
5047 bssl::UniquePtr<SSL> client, server;
5048 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
5049 server_ctx.get()));
5050
5051 BIO *client_wbio = SSL_get_wbio(client.get());
5052 EXPECT_EQ(0u, BIO_wpending(client_wbio));
5053 EXPECT_TRUE(SSL_key_update(client.get(), SSL_KEY_UPDATE_NOT_REQUESTED));
5054 EXPECT_EQ(0u, BIO_wpending(client_wbio));
5055 EXPECT_EQ(0, SSL_write(client.get(), nullptr, 0));
5056 EXPECT_NE(0u, BIO_wpending(client_wbio));
5057}
5058
David Benjamin5869eb32018-07-17 00:59:45 -04005059TEST_P(SSLVersionTest, VerifyBeforeCertRequest) {
5060 // Configure the server to request client certificates.
5061 SSL_CTX_set_custom_verify(
5062 server_ctx_.get(), SSL_VERIFY_PEER,
5063 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
5064
5065 // Configure the client to reject the server certificate.
5066 SSL_CTX_set_custom_verify(
5067 client_ctx_.get(), SSL_VERIFY_PEER,
5068 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_invalid; });
5069
5070 // cert_cb should not be called. Verification should fail first.
5071 SSL_CTX_set_cert_cb(client_ctx_.get(),
5072 [](SSL *ssl, void *arg) {
5073 ADD_FAILURE() << "cert_cb unexpectedly called";
5074 return 0;
5075 },
5076 nullptr);
5077
5078 bssl::UniquePtr<SSL> client, server;
5079 EXPECT_FALSE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
5080 server_ctx_.get()));
5081}
5082
David Benjamin492c9aa2018-08-31 16:35:22 -05005083// Test that ticket-based sessions on the client get fake session IDs.
5084TEST_P(SSLVersionTest, FakeIDsForTickets) {
5085 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5086 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5087
5088 bssl::UniquePtr<SSL_SESSION> session =
5089 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5090 ASSERT_TRUE(session);
5091
5092 EXPECT_TRUE(SSL_SESSION_has_ticket(session.get()));
5093 unsigned session_id_length;
5094 SSL_SESSION_get_id(session.get(), &session_id_length);
5095 EXPECT_NE(session_id_length, 0u);
5096}
5097
David Benjamin6c04bd12018-07-19 18:13:09 -04005098// These tests test multi-threaded behavior. They are intended to run with
5099// ThreadSanitizer.
David Benjamin5b33eff2018-09-22 16:52:48 -07005100#if defined(OPENSSL_THREADS)
David Benjamin6c04bd12018-07-19 18:13:09 -04005101TEST_P(SSLVersionTest, SessionCacheThreads) {
5102 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
5103 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5104 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5105
5106 if (version() == TLS1_3_VERSION) {
5107 // Our TLS 1.3 implementation does not support stateful resumption.
5108 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
5109 return;
5110 }
5111
5112 // Establish two client sessions to test with.
5113 bssl::UniquePtr<SSL_SESSION> session1 =
5114 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5115 ASSERT_TRUE(session1);
5116 bssl::UniquePtr<SSL_SESSION> session2 =
5117 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5118 ASSERT_TRUE(session2);
5119
5120 auto connect_with_session = [&](SSL_SESSION *session) {
5121 ClientConfig config;
5122 config.session = session;
5123 UniquePtr<SSL> client, server;
5124 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
5125 server_ctx_.get(), config));
5126 };
5127
5128 // Resume sessions in parallel with establishing new ones.
5129 {
5130 std::vector<std::thread> threads;
5131 threads.emplace_back([&] { connect_with_session(nullptr); });
5132 threads.emplace_back([&] { connect_with_session(nullptr); });
5133 threads.emplace_back([&] { connect_with_session(session1.get()); });
5134 threads.emplace_back([&] { connect_with_session(session1.get()); });
5135 threads.emplace_back([&] { connect_with_session(session2.get()); });
5136 threads.emplace_back([&] { connect_with_session(session2.get()); });
5137 for (auto &thread : threads) {
5138 thread.join();
5139 }
5140 }
5141
5142 // Hit the maximum session cache size across multiple threads
5143 size_t limit = SSL_CTX_sess_number(server_ctx_.get()) + 2;
5144 SSL_CTX_sess_set_cache_size(server_ctx_.get(), limit);
5145 {
5146 std::vector<std::thread> threads;
5147 for (int i = 0; i < 4; i++) {
5148 threads.emplace_back([&]() {
5149 connect_with_session(nullptr);
5150 EXPECT_LE(SSL_CTX_sess_number(server_ctx_.get()), limit);
5151 });
5152 }
5153 for (auto &thread : threads) {
5154 thread.join();
5155 }
5156 EXPECT_EQ(SSL_CTX_sess_number(server_ctx_.get()), limit);
5157 }
5158}
5159
5160TEST_P(SSLVersionTest, SessionTicketThreads) {
5161 for (bool renew_ticket : {false, true}) {
5162 SCOPED_TRACE(renew_ticket);
5163 ResetContexts();
5164 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5165 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5166 if (renew_ticket) {
5167 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
5168 }
5169
5170 // Establish two client sessions to test with.
5171 bssl::UniquePtr<SSL_SESSION> session1 =
5172 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5173 ASSERT_TRUE(session1);
5174 bssl::UniquePtr<SSL_SESSION> session2 =
5175 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5176 ASSERT_TRUE(session2);
5177
5178 auto connect_with_session = [&](SSL_SESSION *session) {
5179 ClientConfig config;
5180 config.session = session;
5181 UniquePtr<SSL> client, server;
5182 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
5183 server_ctx_.get(), config));
5184 };
5185
5186 // Resume sessions in parallel with establishing new ones.
5187 {
5188 std::vector<std::thread> threads;
5189 threads.emplace_back([&] { connect_with_session(nullptr); });
5190 threads.emplace_back([&] { connect_with_session(nullptr); });
5191 threads.emplace_back([&] { connect_with_session(session1.get()); });
5192 threads.emplace_back([&] { connect_with_session(session1.get()); });
5193 threads.emplace_back([&] { connect_with_session(session2.get()); });
5194 threads.emplace_back([&] { connect_with_session(session2.get()); });
5195 for (auto &thread : threads) {
5196 thread.join();
5197 }
5198 }
5199 }
5200}
5201
5202// SSL_CTX_get0_certificate needs to lock internally. Test this works.
5203TEST(SSLTest, GetCertificateThreads) {
5204 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
5205 ASSERT_TRUE(ctx);
5206 bssl::UniquePtr<X509> cert = GetTestCertificate();
5207 ASSERT_TRUE(cert);
5208 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
5209
5210 // Existing code expects |SSL_CTX_get0_certificate| to be callable from two
5211 // threads concurrently. It originally was an immutable operation. Now we
5212 // implement it with a thread-safe cache, so it is worth testing.
5213 X509 *cert2_thread;
5214 std::thread thread(
5215 [&] { cert2_thread = SSL_CTX_get0_certificate(ctx.get()); });
5216 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
5217 thread.join();
5218
5219 EXPECT_EQ(cert2, cert2_thread);
5220 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
5221}
David Benjamin4cce9552018-12-13 12:20:54 -06005222
5223// Functions which access properties on the negotiated session are thread-safe
5224// where needed. Prior to TLS 1.3, clients resuming sessions and servers
5225// performing stateful resumption will share an underlying SSL_SESSION object,
5226// potentially across threads.
5227TEST_P(SSLVersionTest, SessionPropertiesThreads) {
5228 if (version() == TLS1_3_VERSION) {
5229 // Our TLS 1.3 implementation does not support stateful resumption.
5230 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
5231 return;
5232 }
5233
5234 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
5235 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5236 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5237
5238 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
5239 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
5240
5241 // Configure mutual authentication, so we have more session state.
5242 SSL_CTX_set_custom_verify(
5243 client_ctx_.get(), SSL_VERIFY_PEER,
5244 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
5245 SSL_CTX_set_custom_verify(
5246 server_ctx_.get(), SSL_VERIFY_PEER,
5247 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
5248
5249 // Establish a client session to test with.
5250 bssl::UniquePtr<SSL_SESSION> session =
5251 CreateClientSession(client_ctx_.get(), server_ctx_.get());
5252 ASSERT_TRUE(session);
5253
5254 // Resume with it twice.
5255 UniquePtr<SSL> ssls[4];
5256 ClientConfig config;
5257 config.session = session.get();
5258 ASSERT_TRUE(ConnectClientAndServer(&ssls[0], &ssls[1], client_ctx_.get(),
5259 server_ctx_.get(), config));
5260 ASSERT_TRUE(ConnectClientAndServer(&ssls[2], &ssls[3], client_ctx_.get(),
5261 server_ctx_.get(), config));
5262
5263 // Read properties in parallel.
5264 auto read_properties = [](const SSL *ssl) {
5265 EXPECT_TRUE(SSL_get_peer_cert_chain(ssl));
5266 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(ssl));
5267 EXPECT_TRUE(peer);
5268 EXPECT_TRUE(SSL_get_current_cipher(ssl));
5269 EXPECT_TRUE(SSL_get_curve_id(ssl));
5270 };
5271
5272 std::vector<std::thread> threads;
5273 for (const auto &ssl_ptr : ssls) {
5274 const SSL *ssl = ssl_ptr.get();
5275 threads.emplace_back([=] { read_properties(ssl); });
5276 }
5277 for (auto &thread : threads) {
5278 thread.join();
5279 }
5280}
David Benjamina486c6c2019-03-28 18:32:38 -05005281#endif // OPENSSL_THREADS
David Benjamin6c04bd12018-07-19 18:13:09 -04005282
Steven Valdezc8e0f902018-07-14 11:23:01 -04005283constexpr size_t kNumQUICLevels = 4;
5284static_assert(ssl_encryption_initial < kNumQUICLevels,
5285 "kNumQUICLevels is wrong");
5286static_assert(ssl_encryption_early_data < kNumQUICLevels,
5287 "kNumQUICLevels is wrong");
5288static_assert(ssl_encryption_handshake < kNumQUICLevels,
5289 "kNumQUICLevels is wrong");
5290static_assert(ssl_encryption_application < kNumQUICLevels,
5291 "kNumQUICLevels is wrong");
5292
David Benjamin1e859052020-02-09 16:04:58 -05005293const char *LevelToString(ssl_encryption_level_t level) {
5294 switch (level) {
5295 case ssl_encryption_initial:
5296 return "initial";
5297 case ssl_encryption_early_data:
5298 return "early data";
5299 case ssl_encryption_handshake:
5300 return "handshake";
5301 case ssl_encryption_application:
5302 return "application";
5303 }
5304 return "<unknown>";
5305}
5306
Steven Valdezc8e0f902018-07-14 11:23:01 -04005307class MockQUICTransport {
5308 public:
David Benjamind6343572019-08-15 17:29:02 -04005309 enum class Role { kClient, kServer };
5310
5311 explicit MockQUICTransport(Role role) : role_(role) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005312 // The caller is expected to configure initial secrets.
5313 levels_[ssl_encryption_initial].write_secret = {1};
5314 levels_[ssl_encryption_initial].read_secret = {1};
5315 }
5316
5317 void set_peer(MockQUICTransport *peer) { peer_ = peer; }
5318
5319 bool has_alert() const { return has_alert_; }
5320 ssl_encryption_level_t alert_level() const { return alert_level_; }
5321 uint8_t alert() const { return alert_; }
5322
5323 bool PeerSecretsMatch(ssl_encryption_level_t level) const {
5324 return levels_[level].write_secret == peer_->levels_[level].read_secret &&
Steven Valdez384d0ea2018-11-06 10:45:36 -05005325 levels_[level].read_secret == peer_->levels_[level].write_secret &&
5326 levels_[level].cipher == peer_->levels_[level].cipher;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005327 }
5328
David Benjamin1e859052020-02-09 16:04:58 -05005329 bool HasReadSecret(ssl_encryption_level_t level) const {
5330 return !levels_[level].read_secret.empty();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005331 }
5332
David Benjamin1e859052020-02-09 16:04:58 -05005333 bool HasWriteSecret(ssl_encryption_level_t level) const {
5334 return !levels_[level].write_secret.empty();
5335 }
5336
David Benjamin5298ef92020-03-13 12:17:30 -04005337 void AllowOutOfOrderWrites() { allow_out_of_order_writes_ = true; }
5338
David Benjamin1e859052020-02-09 16:04:58 -05005339 bool SetReadSecret(ssl_encryption_level_t level, const SSL_CIPHER *cipher,
5340 Span<const uint8_t> secret) {
5341 if (HasReadSecret(level)) {
5342 ADD_FAILURE() << LevelToString(level) << " read secret configured twice";
5343 return false;
5344 }
5345
5346 if (role_ == Role::kClient && level == ssl_encryption_early_data) {
5347 ADD_FAILURE() << "Unexpected early data read secret";
5348 return false;
5349 }
5350
5351 ssl_encryption_level_t ack_level =
5352 level == ssl_encryption_early_data ? ssl_encryption_application : level;
5353 if (!HasWriteSecret(ack_level)) {
5354 ADD_FAILURE() << LevelToString(level)
5355 << " read secret configured before ACK write secret";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005356 return false;
5357 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05005358
5359 if (cipher == nullptr) {
David Benjamin1e859052020-02-09 16:04:58 -05005360 ADD_FAILURE() << "Unexpected null cipher";
Steven Valdez384d0ea2018-11-06 10:45:36 -05005361 return false;
5362 }
5363
David Benjamin1e859052020-02-09 16:04:58 -05005364 if (level != ssl_encryption_early_data &&
5365 SSL_CIPHER_get_id(cipher) != levels_[level].cipher) {
5366 ADD_FAILURE() << "Cipher suite inconsistent";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005367 return false;
5368 }
David Benjamind6343572019-08-15 17:29:02 -04005369
David Benjamin1e859052020-02-09 16:04:58 -05005370 levels_[level].read_secret.assign(secret.begin(), secret.end());
5371 levels_[level].cipher = SSL_CIPHER_get_id(cipher);
5372 return true;
5373 }
5374
5375 bool SetWriteSecret(ssl_encryption_level_t level, const SSL_CIPHER *cipher,
5376 Span<const uint8_t> secret) {
5377 if (HasWriteSecret(level)) {
5378 ADD_FAILURE() << LevelToString(level) << " write secret configured twice";
David Benjamind6343572019-08-15 17:29:02 -04005379 return false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005380 }
David Benjamind6343572019-08-15 17:29:02 -04005381
David Benjamin1e859052020-02-09 16:04:58 -05005382 if (role_ == Role::kServer && level == ssl_encryption_early_data) {
5383 ADD_FAILURE() << "Unexpected early data write secret";
5384 return false;
5385 }
5386
5387 if (cipher == nullptr) {
5388 ADD_FAILURE() << "Unexpected null cipher";
5389 return false;
5390 }
5391
5392 levels_[level].write_secret.assign(secret.begin(), secret.end());
Steven Valdez384d0ea2018-11-06 10:45:36 -05005393 levels_[level].cipher = SSL_CIPHER_get_id(cipher);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005394 return true;
5395 }
5396
5397 bool WriteHandshakeData(ssl_encryption_level_t level,
5398 Span<const uint8_t> data) {
5399 if (levels_[level].write_secret.empty()) {
David Benjamin1e859052020-02-09 16:04:58 -05005400 ADD_FAILURE() << LevelToString(level)
5401 << " write secret not yet configured";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005402 return false;
5403 }
David Benjamin5298ef92020-03-13 12:17:30 -04005404
5405 // Although the levels are conceptually separate, BoringSSL finishes writing
5406 // data from a previous level before installing keys for the next level.
5407 if (!allow_out_of_order_writes_) {
5408 switch (level) {
5409 case ssl_encryption_early_data:
5410 ADD_FAILURE() << "unexpected handshake data at early data level";
5411 return false;
5412 case ssl_encryption_initial:
5413 if (!levels_[ssl_encryption_handshake].write_secret.empty()) {
5414 ADD_FAILURE()
5415 << LevelToString(level)
5416 << " handshake data written after handshake keys installed";
5417 return false;
5418 }
5419 OPENSSL_FALLTHROUGH;
5420 case ssl_encryption_handshake:
5421 if (!levels_[ssl_encryption_application].write_secret.empty()) {
5422 ADD_FAILURE()
5423 << LevelToString(level)
5424 << " handshake data written after application keys installed";
5425 return false;
5426 }
5427 OPENSSL_FALLTHROUGH;
5428 case ssl_encryption_application:
5429 break;
5430 }
5431 }
5432
Steven Valdezc8e0f902018-07-14 11:23:01 -04005433 levels_[level].write_data.insert(levels_[level].write_data.end(),
5434 data.begin(), data.end());
5435 return true;
5436 }
5437
5438 bool SendAlert(ssl_encryption_level_t level, uint8_t alert_value) {
5439 if (has_alert_) {
5440 ADD_FAILURE() << "duplicate alert sent";
5441 return false;
5442 }
5443
5444 if (levels_[level].write_secret.empty()) {
David Benjamin1e859052020-02-09 16:04:58 -05005445 ADD_FAILURE() << LevelToString(level)
5446 << " write secret not yet configured";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005447 return false;
5448 }
5449
5450 has_alert_ = true;
5451 alert_level_ = level;
5452 alert_ = alert_value;
5453 return true;
5454 }
5455
5456 bool ReadHandshakeData(std::vector<uint8_t> *out,
5457 ssl_encryption_level_t level,
5458 size_t num = std::numeric_limits<size_t>::max()) {
5459 if (levels_[level].read_secret.empty()) {
David Benjamind6343572019-08-15 17:29:02 -04005460 ADD_FAILURE() << "data read before keys configured in level " << level;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005461 return false;
5462 }
5463 // The peer may not have configured any keys yet.
5464 if (peer_->levels_[level].write_secret.empty()) {
David Benjamind0b97942019-08-21 12:54:20 -04005465 out->clear();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005466 return true;
5467 }
5468 // Check the peer computed the same key.
5469 if (peer_->levels_[level].write_secret != levels_[level].read_secret) {
David Benjamind6343572019-08-15 17:29:02 -04005470 ADD_FAILURE() << "peer write key does not match read key in level "
5471 << level;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005472 return false;
5473 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05005474 if (peer_->levels_[level].cipher != levels_[level].cipher) {
David Benjamind6343572019-08-15 17:29:02 -04005475 ADD_FAILURE() << "peer cipher does not match in level " << level;
Steven Valdez384d0ea2018-11-06 10:45:36 -05005476 return false;
5477 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04005478 std::vector<uint8_t> *peer_data = &peer_->levels_[level].write_data;
5479 num = std::min(num, peer_data->size());
5480 out->assign(peer_data->begin(), peer_data->begin() + num);
5481 peer_data->erase(peer_data->begin(), peer_data->begin() + num);
5482 return true;
5483 }
5484
5485 private:
David Benjamind6343572019-08-15 17:29:02 -04005486 Role role_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005487 MockQUICTransport *peer_ = nullptr;
5488
David Benjamin5298ef92020-03-13 12:17:30 -04005489 bool allow_out_of_order_writes_ = false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005490 bool has_alert_ = false;
5491 ssl_encryption_level_t alert_level_ = ssl_encryption_initial;
5492 uint8_t alert_ = 0;
5493
5494 struct Level {
5495 std::vector<uint8_t> write_data;
5496 std::vector<uint8_t> write_secret;
5497 std::vector<uint8_t> read_secret;
Steven Valdez384d0ea2018-11-06 10:45:36 -05005498 uint32_t cipher = 0;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005499 };
5500 Level levels_[kNumQUICLevels];
5501};
5502
5503class MockQUICTransportPair {
5504 public:
David Benjamind6343572019-08-15 17:29:02 -04005505 MockQUICTransportPair()
5506 : client_(MockQUICTransport::Role::kClient),
5507 server_(MockQUICTransport::Role::kServer) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005508 client_.set_peer(&server_);
David Benjamind6343572019-08-15 17:29:02 -04005509 server_.set_peer(&client_);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005510 }
5511
5512 ~MockQUICTransportPair() {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005513 client_.set_peer(nullptr);
David Benjamind6343572019-08-15 17:29:02 -04005514 server_.set_peer(nullptr);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005515 }
5516
5517 MockQUICTransport *client() { return &client_; }
5518 MockQUICTransport *server() { return &server_; }
5519
5520 bool SecretsMatch(ssl_encryption_level_t level) const {
David Benjamin1e859052020-02-09 16:04:58 -05005521 // We only need to check |HasReadSecret| and |HasWriteSecret| on |client_|.
5522 // |PeerSecretsMatch| checks that |server_| is analogously configured.
5523 return client_.PeerSecretsMatch(level) &&
5524 client_.HasWriteSecret(level) &&
5525 (level == ssl_encryption_early_data || client_.HasReadSecret(level));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005526 }
5527
5528 private:
5529 MockQUICTransport client_;
5530 MockQUICTransport server_;
5531};
5532
5533class QUICMethodTest : public testing::Test {
5534 protected:
5535 void SetUp() override {
5536 client_ctx_.reset(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04005537 server_ctx_ = CreateContextWithTestCertificate(TLS_method());
Steven Valdezc8e0f902018-07-14 11:23:01 -04005538 ASSERT_TRUE(client_ctx_);
5539 ASSERT_TRUE(server_ctx_);
5540
Steven Valdezc8e0f902018-07-14 11:23:01 -04005541 SSL_CTX_set_min_proto_version(server_ctx_.get(), TLS1_3_VERSION);
5542 SSL_CTX_set_max_proto_version(server_ctx_.get(), TLS1_3_VERSION);
5543 SSL_CTX_set_min_proto_version(client_ctx_.get(), TLS1_3_VERSION);
5544 SSL_CTX_set_max_proto_version(client_ctx_.get(), TLS1_3_VERSION);
Nick Harper74161f42020-07-24 15:35:27 -07005545
5546 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
5547 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
5548 sizeof(kALPNProtos)),
5549 0);
5550 SSL_CTX_set_alpn_select_cb(
5551 server_ctx_.get(),
5552 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
5553 unsigned in_len, void *arg) -> int {
5554 return SSL_select_next_proto(
5555 const_cast<uint8_t **>(out), out_len, in, in_len,
5556 kALPNProtos, sizeof(kALPNProtos)) == OPENSSL_NPN_NEGOTIATED
5557 ? SSL_TLSEXT_ERR_OK
5558 : SSL_TLSEXT_ERR_NOACK;
5559 },
5560 nullptr);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005561 }
5562
5563 static MockQUICTransport *TransportFromSSL(const SSL *ssl) {
5564 return ex_data_.Get(ssl);
5565 }
5566
5567 static bool ProvideHandshakeData(
5568 SSL *ssl, size_t num = std::numeric_limits<size_t>::max()) {
5569 MockQUICTransport *transport = TransportFromSSL(ssl);
5570 ssl_encryption_level_t level = SSL_quic_read_level(ssl);
5571 std::vector<uint8_t> data;
5572 return transport->ReadHandshakeData(&data, level, num) &&
5573 SSL_provide_quic_data(ssl, level, data.data(), data.size());
5574 }
5575
David Benjamin5298ef92020-03-13 12:17:30 -04005576 void AllowOutOfOrderWrites() {
5577 allow_out_of_order_writes_ = true;
5578 }
5579
Steven Valdezc8e0f902018-07-14 11:23:01 -04005580 bool CreateClientAndServer() {
5581 client_.reset(SSL_new(client_ctx_.get()));
5582 server_.reset(SSL_new(server_ctx_.get()));
5583 if (!client_ || !server_) {
5584 return false;
5585 }
5586
5587 SSL_set_connect_state(client_.get());
5588 SSL_set_accept_state(server_.get());
5589
David Benjamind6343572019-08-15 17:29:02 -04005590 transport_.reset(new MockQUICTransportPair);
5591 ex_data_.Set(client_.get(), transport_->client());
5592 ex_data_.Set(server_.get(), transport_->server());
David Benjamin5298ef92020-03-13 12:17:30 -04005593 if (allow_out_of_order_writes_) {
5594 transport_->client()->AllowOutOfOrderWrites();
5595 transport_->server()->AllowOutOfOrderWrites();
5596 }
Nick Harper7c522992020-04-30 14:15:49 -07005597 static const uint8_t client_transport_params[] = {0};
5598 if (!SSL_set_quic_transport_params(client_.get(), client_transport_params,
5599 sizeof(client_transport_params)) ||
5600 !SSL_set_quic_transport_params(server_.get(),
5601 server_transport_params_.data(),
5602 server_transport_params_.size()) ||
5603 !SSL_set_quic_early_data_context(
5604 server_.get(), server_quic_early_data_context_.data(),
5605 server_quic_early_data_context_.size())) {
Nick Harper72cff812020-03-26 18:06:16 -07005606 return false;
5607 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04005608 return true;
5609 }
5610
Nick Harper72cff812020-03-26 18:06:16 -07005611 enum class ExpectedError {
5612 kNoError,
5613 kClientError,
5614 kServerError,
5615 };
5616
David Benjamind6343572019-08-15 17:29:02 -04005617 // CompleteHandshakesForQUIC runs |SSL_do_handshake| on |client_| and
5618 // |server_| until each completes once. It returns true on success and false
5619 // on failure.
5620 bool CompleteHandshakesForQUIC() {
Nick Harper72cff812020-03-26 18:06:16 -07005621 return RunQUICHandshakesAndExpectError(ExpectedError::kNoError);
5622 }
5623
5624 // Runs |SSL_do_handshake| on |client_| and |server_| until each completes
5625 // once. If |expect_client_error| is true, it will return true only if the
5626 // client handshake failed. Otherwise, it returns true if both handshakes
5627 // succeed and false otherwise.
5628 bool RunQUICHandshakesAndExpectError(ExpectedError expected_error) {
David Benjamind6343572019-08-15 17:29:02 -04005629 bool client_done = false, server_done = false;
5630 while (!client_done || !server_done) {
5631 if (!client_done) {
5632 if (!ProvideHandshakeData(client_.get())) {
5633 ADD_FAILURE() << "ProvideHandshakeData(client_) failed";
5634 return false;
5635 }
5636 int client_ret = SSL_do_handshake(client_.get());
David Benjamin2fb729d2020-02-20 17:37:33 -05005637 int client_err = SSL_get_error(client_.get(), client_ret);
David Benjamind6343572019-08-15 17:29:02 -04005638 if (client_ret == 1) {
5639 client_done = true;
David Benjamin2fb729d2020-02-20 17:37:33 -05005640 } else if (client_ret != -1 || client_err != SSL_ERROR_WANT_READ) {
Nick Harper72cff812020-03-26 18:06:16 -07005641 if (expected_error == ExpectedError::kClientError) {
5642 return true;
5643 }
David Benjamin2fb729d2020-02-20 17:37:33 -05005644 ADD_FAILURE() << "Unexpected client output: " << client_ret << " "
5645 << client_err;
5646 return false;
David Benjamind6343572019-08-15 17:29:02 -04005647 }
5648 }
5649
5650 if (!server_done) {
5651 if (!ProvideHandshakeData(server_.get())) {
5652 ADD_FAILURE() << "ProvideHandshakeData(server_) failed";
5653 return false;
5654 }
5655 int server_ret = SSL_do_handshake(server_.get());
David Benjamin2fb729d2020-02-20 17:37:33 -05005656 int server_err = SSL_get_error(server_.get(), server_ret);
David Benjamind6343572019-08-15 17:29:02 -04005657 if (server_ret == 1) {
5658 server_done = true;
David Benjamin2fb729d2020-02-20 17:37:33 -05005659 } else if (server_ret != -1 || server_err != SSL_ERROR_WANT_READ) {
Nick Harper72cff812020-03-26 18:06:16 -07005660 if (expected_error == ExpectedError::kServerError) {
5661 return true;
5662 }
David Benjamin2fb729d2020-02-20 17:37:33 -05005663 ADD_FAILURE() << "Unexpected server output: " << server_ret << " "
5664 << server_err;
5665 return false;
David Benjamind6343572019-08-15 17:29:02 -04005666 }
5667 }
5668 }
Nick Harper72cff812020-03-26 18:06:16 -07005669 return expected_error == ExpectedError::kNoError;
David Benjamind6343572019-08-15 17:29:02 -04005670 }
5671
5672 bssl::UniquePtr<SSL_SESSION> CreateClientSessionForQUIC() {
5673 g_last_session = nullptr;
5674 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
5675 if (!CreateClientAndServer() ||
5676 !CompleteHandshakesForQUIC()) {
5677 return nullptr;
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005678 }
5679
David Benjamind6343572019-08-15 17:29:02 -04005680 // The server sent NewSessionTicket messages in the handshake.
5681 if (!ProvideHandshakeData(client_.get()) ||
5682 !SSL_process_quic_post_handshake(client_.get())) {
5683 return nullptr;
5684 }
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005685
David Benjamind6343572019-08-15 17:29:02 -04005686 return std::move(g_last_session);
5687 }
5688
5689 void ExpectHandshakeSuccess() {
5690 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_application));
5691 EXPECT_EQ(ssl_encryption_application, SSL_quic_read_level(client_.get()));
5692 EXPECT_EQ(ssl_encryption_application, SSL_quic_write_level(client_.get()));
5693 EXPECT_EQ(ssl_encryption_application, SSL_quic_read_level(server_.get()));
5694 EXPECT_EQ(ssl_encryption_application, SSL_quic_write_level(server_.get()));
5695 EXPECT_FALSE(transport_->client()->has_alert());
5696 EXPECT_FALSE(transport_->server()->has_alert());
5697
5698 // SSL_do_handshake is now idempotent.
5699 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
5700 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005701 }
5702
David Benjamin1e859052020-02-09 16:04:58 -05005703 // Returns a default SSL_QUIC_METHOD. Individual methods may be overwritten by
5704 // the test.
5705 SSL_QUIC_METHOD DefaultQUICMethod() {
5706 return SSL_QUIC_METHOD{
5707 SetReadSecretCallback, SetWriteSecretCallback, AddHandshakeDataCallback,
5708 FlushFlightCallback, SendAlertCallback,
5709 };
5710 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04005711
David Benjamin1e859052020-02-09 16:04:58 -05005712 static int SetReadSecretCallback(SSL *ssl, ssl_encryption_level_t level,
5713 const SSL_CIPHER *cipher,
5714 const uint8_t *secret, size_t secret_len) {
5715 return TransportFromSSL(ssl)->SetReadSecret(
5716 level, cipher, MakeConstSpan(secret, secret_len));
5717 }
5718
5719 static int SetWriteSecretCallback(SSL *ssl, ssl_encryption_level_t level,
5720 const SSL_CIPHER *cipher,
5721 const uint8_t *secret, size_t secret_len) {
5722 return TransportFromSSL(ssl)->SetWriteSecret(
5723 level, cipher, MakeConstSpan(secret, secret_len));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005724 }
5725
David Benjamincc9d9352018-10-30 19:45:22 -05005726 static int AddHandshakeDataCallback(SSL *ssl,
5727 enum ssl_encryption_level_t level,
5728 const uint8_t *data, size_t len) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005729 EXPECT_EQ(level, SSL_quic_write_level(ssl));
5730 return TransportFromSSL(ssl)->WriteHandshakeData(level,
5731 MakeConstSpan(data, len));
5732 }
5733
5734 static int FlushFlightCallback(SSL *ssl) { return 1; }
5735
5736 static int SendAlertCallback(SSL *ssl, ssl_encryption_level_t level,
5737 uint8_t alert) {
5738 EXPECT_EQ(level, SSL_quic_write_level(ssl));
5739 return TransportFromSSL(ssl)->SendAlert(level, alert);
5740 }
5741
5742 bssl::UniquePtr<SSL_CTX> client_ctx_;
5743 bssl::UniquePtr<SSL_CTX> server_ctx_;
5744
5745 static UnownedSSLExData<MockQUICTransport> ex_data_;
David Benjamind6343572019-08-15 17:29:02 -04005746 std::unique_ptr<MockQUICTransportPair> transport_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005747
5748 bssl::UniquePtr<SSL> client_;
5749 bssl::UniquePtr<SSL> server_;
David Benjamin5298ef92020-03-13 12:17:30 -04005750
Nick Harper7c522992020-04-30 14:15:49 -07005751 std::vector<uint8_t> server_transport_params_ = {1};
5752 std::vector<uint8_t> server_quic_early_data_context_ = {2};
5753
David Benjamin5298ef92020-03-13 12:17:30 -04005754 bool allow_out_of_order_writes_ = false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005755};
5756
5757UnownedSSLExData<MockQUICTransport> QUICMethodTest::ex_data_;
5758
David Benjaminfd863b62019-07-25 13:51:32 -04005759// Test a full handshake and resumption work.
Steven Valdezc8e0f902018-07-14 11:23:01 -04005760TEST_F(QUICMethodTest, Basic) {
David Benjamin1e859052020-02-09 16:04:58 -05005761 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005762
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005763 g_last_session = nullptr;
5764
5765 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5766 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005767 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5768 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
David Benjamind6343572019-08-15 17:29:02 -04005769
Steven Valdezc8e0f902018-07-14 11:23:01 -04005770 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04005771 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdezc8e0f902018-07-14 11:23:01 -04005772
David Benjamind6343572019-08-15 17:29:02 -04005773 ExpectHandshakeSuccess();
5774 EXPECT_FALSE(SSL_session_reused(client_.get()));
5775 EXPECT_FALSE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005776
5777 // The server sent NewSessionTicket messages in the handshake.
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005778 EXPECT_FALSE(g_last_session);
5779 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5780 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
5781 EXPECT_TRUE(g_last_session);
5782
5783 // Create a second connection to verify resumption works.
David Benjamind6343572019-08-15 17:29:02 -04005784 ASSERT_TRUE(CreateClientAndServer());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005785 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
5786 SSL_set_session(client_.get(), session.get());
5787
David Benjamind6343572019-08-15 17:29:02 -04005788 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005789
David Benjamind6343572019-08-15 17:29:02 -04005790 ExpectHandshakeSuccess();
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005791 EXPECT_TRUE(SSL_session_reused(client_.get()));
5792 EXPECT_TRUE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005793}
5794
David Benjaminfd863b62019-07-25 13:51:32 -04005795// Test that HelloRetryRequest in QUIC works.
5796TEST_F(QUICMethodTest, HelloRetryRequest) {
David Benjamin1e859052020-02-09 16:04:58 -05005797 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjaminfd863b62019-07-25 13:51:32 -04005798
5799 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5800 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5801
5802 // BoringSSL predicts the most preferred curve, so using different preferences
5803 // will trigger HelloRetryRequest.
5804 static const int kClientPrefs[] = {NID_X25519, NID_X9_62_prime256v1};
5805 ASSERT_TRUE(SSL_CTX_set1_curves(client_ctx_.get(), kClientPrefs,
5806 OPENSSL_ARRAY_SIZE(kClientPrefs)));
5807 static const int kServerPrefs[] = {NID_X9_62_prime256v1, NID_X25519};
5808 ASSERT_TRUE(SSL_CTX_set1_curves(server_ctx_.get(), kServerPrefs,
5809 OPENSSL_ARRAY_SIZE(kServerPrefs)));
5810
5811 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04005812 ASSERT_TRUE(CompleteHandshakesForQUIC());
5813 ExpectHandshakeSuccess();
5814}
David Benjaminfd863b62019-07-25 13:51:32 -04005815
Nick Harpere32549e2020-05-06 14:27:11 -07005816// Test that the client does not send a legacy_session_id in the ClientHello.
5817TEST_F(QUICMethodTest, NoLegacySessionId) {
5818 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
5819
5820 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5821 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5822 // Check that the session ID length is 0 in an early callback.
5823 SSL_CTX_set_select_certificate_cb(
5824 server_ctx_.get(),
5825 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
5826 EXPECT_EQ(client_hello->session_id_len, 0u);
5827 return ssl_select_cert_success;
5828 });
5829
5830 ASSERT_TRUE(CreateClientAndServer());
5831 ASSERT_TRUE(CompleteHandshakesForQUIC());
5832
5833 ExpectHandshakeSuccess();
5834}
5835
David Benjamin1e859052020-02-09 16:04:58 -05005836// Test that, even in a 1-RTT handshake, the server installs keys at the right
5837// time. Half-RTT keys are available early, but 1-RTT read keys are deferred.
5838TEST_F(QUICMethodTest, HalfRTTKeys) {
5839 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
5840
5841 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5842 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5843 ASSERT_TRUE(CreateClientAndServer());
5844
5845 // The client sends ClientHello.
5846 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5847 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client_.get(), -1));
5848
5849 // The server reads ClientHello and sends ServerHello..Finished.
5850 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5851 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
5852 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
5853
5854 // At this point, the server has half-RTT write keys, but it cannot access
5855 // 1-RTT read keys until client Finished.
5856 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
5857 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
5858
5859 // Finish up the client and server handshakes.
5860 ASSERT_TRUE(CompleteHandshakesForQUIC());
5861
5862 // Both sides can now exchange 1-RTT data.
5863 ExpectHandshakeSuccess();
5864}
5865
David Benjamind6343572019-08-15 17:29:02 -04005866TEST_F(QUICMethodTest, ZeroRTTAccept) {
David Benjamin1e859052020-02-09 16:04:58 -05005867 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjamind6343572019-08-15 17:29:02 -04005868
5869 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5870 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
5871 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
5872 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5873 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5874
5875 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
5876 ASSERT_TRUE(session);
5877
5878 ASSERT_TRUE(CreateClientAndServer());
5879 SSL_set_session(client_.get(), session.get());
5880
5881 // The client handshake should return immediately into the early data state.
5882 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
5883 EXPECT_TRUE(SSL_in_early_data(client_.get()));
5884 // The transport should have keys for sending 0-RTT data.
David Benjamin1e859052020-02-09 16:04:58 -05005885 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04005886
5887 // The server will consume the ClientHello and also enter the early data
5888 // state.
5889 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5890 ASSERT_EQ(SSL_do_handshake(server_.get()), 1);
5891 EXPECT_TRUE(SSL_in_early_data(server_.get()));
5892 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_early_data));
David Benjamin1e859052020-02-09 16:04:58 -05005893 // At this point, the server has half-RTT write keys, but it cannot access
5894 // 1-RTT read keys until client Finished.
5895 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
5896 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
David Benjamind6343572019-08-15 17:29:02 -04005897
5898 // Finish up the client and server handshakes.
5899 ASSERT_TRUE(CompleteHandshakesForQUIC());
5900
5901 // Both sides can now exchange 1-RTT data.
5902 ExpectHandshakeSuccess();
5903 EXPECT_TRUE(SSL_session_reused(client_.get()));
5904 EXPECT_TRUE(SSL_session_reused(server_.get()));
5905 EXPECT_FALSE(SSL_in_early_data(client_.get()));
5906 EXPECT_FALSE(SSL_in_early_data(server_.get()));
5907 EXPECT_TRUE(SSL_early_data_accepted(client_.get()));
5908 EXPECT_TRUE(SSL_early_data_accepted(server_.get()));
Nick Harper5e086952020-09-30 13:59:14 -07005909
5910 // Finish handling post-handshake messages after the first 0-RTT resumption.
5911 EXPECT_TRUE(ProvideHandshakeData(client_.get()));
5912 EXPECT_TRUE(SSL_process_quic_post_handshake(client_.get()));
5913
5914 // Perform a second 0-RTT resumption attempt, and confirm that 0-RTT is
5915 // accepted again.
5916 ASSERT_TRUE(CreateClientAndServer());
5917 SSL_set_session(client_.get(), g_last_session.get());
5918
5919 // The client handshake should return immediately into the early data state.
5920 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
5921 EXPECT_TRUE(SSL_in_early_data(client_.get()));
5922 // The transport should have keys for sending 0-RTT data.
5923 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
5924
5925 // The server will consume the ClientHello and also enter the early data
5926 // state.
5927 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5928 ASSERT_EQ(SSL_do_handshake(server_.get()), 1);
5929 EXPECT_TRUE(SSL_in_early_data(server_.get()));
5930 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_early_data));
5931 // At this point, the server has half-RTT write keys, but it cannot access
5932 // 1-RTT read keys until client Finished.
5933 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
5934 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
5935
5936 // Finish up the client and server handshakes.
5937 ASSERT_TRUE(CompleteHandshakesForQUIC());
5938
5939 // Both sides can now exchange 1-RTT data.
5940 ExpectHandshakeSuccess();
5941 EXPECT_TRUE(SSL_session_reused(client_.get()));
5942 EXPECT_TRUE(SSL_session_reused(server_.get()));
5943 EXPECT_FALSE(SSL_in_early_data(client_.get()));
5944 EXPECT_FALSE(SSL_in_early_data(server_.get()));
5945 EXPECT_TRUE(SSL_early_data_accepted(client_.get()));
5946 EXPECT_TRUE(SSL_early_data_accepted(server_.get()));
5947 EXPECT_EQ(SSL_get_early_data_reason(client_.get()), ssl_early_data_accepted);
5948 EXPECT_EQ(SSL_get_early_data_reason(server_.get()), ssl_early_data_accepted);
David Benjamind6343572019-08-15 17:29:02 -04005949}
5950
Nick Harper7c522992020-04-30 14:15:49 -07005951TEST_F(QUICMethodTest, ZeroRTTRejectMismatchedParameters) {
5952 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
5953
5954 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5955 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
5956 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
5957 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5958 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5959
5960
5961 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
5962 ASSERT_TRUE(session);
5963
Nick Harper85194322020-05-20 16:59:29 -07005964 ASSERT_TRUE(CreateClientAndServer());
5965 static const uint8_t new_context[] = {4};
5966 ASSERT_TRUE(SSL_set_quic_early_data_context(server_.get(), new_context,
5967 sizeof(new_context)));
5968 SSL_set_session(client_.get(), session.get());
Nick Harper7c522992020-04-30 14:15:49 -07005969
Nick Harper85194322020-05-20 16:59:29 -07005970 // The client handshake should return immediately into the early data
5971 // state.
5972 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
5973 EXPECT_TRUE(SSL_in_early_data(client_.get()));
5974 // The transport should have keys for sending 0-RTT data.
5975 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
Nick Harper7c522992020-04-30 14:15:49 -07005976
Nick Harper85194322020-05-20 16:59:29 -07005977 // The server will consume the ClientHello, but it will not accept 0-RTT.
5978 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5979 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
5980 EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
5981 EXPECT_FALSE(SSL_in_early_data(server_.get()));
5982 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_early_data));
Nick Harper7c522992020-04-30 14:15:49 -07005983
Nick Harper85194322020-05-20 16:59:29 -07005984 // The client consumes the server response and signals 0-RTT rejection.
5985 for (;;) {
5986 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5987 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
5988 int err = SSL_get_error(client_.get(), -1);
5989 if (err == SSL_ERROR_EARLY_DATA_REJECTED) {
5990 break;
Nick Harper7c522992020-04-30 14:15:49 -07005991 }
Nick Harper85194322020-05-20 16:59:29 -07005992 ASSERT_EQ(SSL_ERROR_WANT_READ, err);
Nick Harper7c522992020-04-30 14:15:49 -07005993 }
Nick Harper85194322020-05-20 16:59:29 -07005994
5995 // As in TLS over TCP, 0-RTT rejection is sticky.
5996 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
5997 ASSERT_EQ(SSL_ERROR_EARLY_DATA_REJECTED, SSL_get_error(client_.get(), -1));
5998
5999 // Finish up the client and server handshakes.
6000 SSL_reset_early_data_reject(client_.get());
6001 ASSERT_TRUE(CompleteHandshakesForQUIC());
6002
6003 // Both sides can now exchange 1-RTT data.
6004 ExpectHandshakeSuccess();
6005 EXPECT_TRUE(SSL_session_reused(client_.get()));
6006 EXPECT_TRUE(SSL_session_reused(server_.get()));
6007 EXPECT_FALSE(SSL_in_early_data(client_.get()));
6008 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6009 EXPECT_FALSE(SSL_early_data_accepted(client_.get()));
6010 EXPECT_FALSE(SSL_early_data_accepted(server_.get()));
6011}
6012
6013TEST_F(QUICMethodTest, NoZeroRTTTicketWithoutEarlyDataContext) {
6014 server_quic_early_data_context_ = {};
6015 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6016
6017 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6018 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6019 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6020 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6021 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6022
6023 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6024 ASSERT_TRUE(session);
6025 EXPECT_FALSE(SSL_SESSION_early_data_capable(session.get()));
Nick Harper7c522992020-04-30 14:15:49 -07006026}
6027
David Benjamind6343572019-08-15 17:29:02 -04006028TEST_F(QUICMethodTest, ZeroRTTReject) {
David Benjamin1e859052020-02-09 16:04:58 -05006029 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjamind6343572019-08-15 17:29:02 -04006030
6031 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6032 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6033 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6034 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6035 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6036
6037 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6038 ASSERT_TRUE(session);
6039
6040 for (bool reject_hrr : {false, true}) {
6041 SCOPED_TRACE(reject_hrr);
6042
6043 ASSERT_TRUE(CreateClientAndServer());
6044 if (reject_hrr) {
6045 // Configure the server to prefer P-256, which will reject 0-RTT via
6046 // HelloRetryRequest.
6047 int p256 = NID_X9_62_prime256v1;
6048 ASSERT_TRUE(SSL_set1_curves(server_.get(), &p256, 1));
6049 } else {
6050 // Disable 0-RTT on the server, so it will reject it.
6051 SSL_set_early_data_enabled(server_.get(), 0);
David Benjaminfd863b62019-07-25 13:51:32 -04006052 }
David Benjamind6343572019-08-15 17:29:02 -04006053 SSL_set_session(client_.get(), session.get());
David Benjaminfd863b62019-07-25 13:51:32 -04006054
David Benjamind6343572019-08-15 17:29:02 -04006055 // The client handshake should return immediately into the early data state.
6056 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6057 EXPECT_TRUE(SSL_in_early_data(client_.get()));
6058 // The transport should have keys for sending 0-RTT data.
David Benjamin1e859052020-02-09 16:04:58 -05006059 EXPECT_TRUE(
6060 transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04006061
6062 // The server will consume the ClientHello, but it will not accept 0-RTT.
David Benjaminfd863b62019-07-25 13:51:32 -04006063 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
David Benjamind6343572019-08-15 17:29:02 -04006064 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6065 EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
6066 EXPECT_FALSE(SSL_in_early_data(server_.get()));
David Benjamin1e859052020-02-09 16:04:58 -05006067 EXPECT_FALSE(
6068 transport_->server()->HasReadSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04006069
6070 // The client consumes the server response and signals 0-RTT rejection.
6071 for (;;) {
6072 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6073 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
6074 int err = SSL_get_error(client_.get(), -1);
6075 if (err == SSL_ERROR_EARLY_DATA_REJECTED) {
6076 break;
6077 }
6078 ASSERT_EQ(SSL_ERROR_WANT_READ, err);
David Benjaminfd863b62019-07-25 13:51:32 -04006079 }
6080
David Benjamind6343572019-08-15 17:29:02 -04006081 // As in TLS over TCP, 0-RTT rejection is sticky.
6082 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
6083 ASSERT_EQ(SSL_ERROR_EARLY_DATA_REJECTED, SSL_get_error(client_.get(), -1));
6084
6085 // Finish up the client and server handshakes.
6086 SSL_reset_early_data_reject(client_.get());
6087 ASSERT_TRUE(CompleteHandshakesForQUIC());
6088
6089 // Both sides can now exchange 1-RTT data.
6090 ExpectHandshakeSuccess();
6091 EXPECT_TRUE(SSL_session_reused(client_.get()));
6092 EXPECT_TRUE(SSL_session_reused(server_.get()));
6093 EXPECT_FALSE(SSL_in_early_data(client_.get()));
6094 EXPECT_FALSE(SSL_in_early_data(server_.get()));
6095 EXPECT_FALSE(SSL_early_data_accepted(client_.get()));
6096 EXPECT_FALSE(SSL_early_data_accepted(server_.get()));
David Benjaminfd863b62019-07-25 13:51:32 -04006097 }
David Benjaminfd863b62019-07-25 13:51:32 -04006098}
6099
David Benjaminee0716f2019-11-19 14:16:28 +08006100TEST_F(QUICMethodTest, NoZeroRTTKeysBeforeReverify) {
David Benjamin1e859052020-02-09 16:04:58 -05006101 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjaminee0716f2019-11-19 14:16:28 +08006102
6103 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6104 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6105 SSL_CTX_set_reverify_on_resume(client_ctx_.get(), 1);
6106 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6107 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6108 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6109
6110 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6111 ASSERT_TRUE(session);
6112
6113 ASSERT_TRUE(CreateClientAndServer());
6114 SSL_set_session(client_.get(), session.get());
6115
6116 // Configure the certificate (re)verification to never complete. The client
6117 // handshake should pause.
6118 SSL_set_custom_verify(
6119 client_.get(), SSL_VERIFY_PEER,
6120 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
6121 return ssl_verify_retry;
6122 });
6123 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6124 ASSERT_EQ(SSL_get_error(client_.get(), -1),
6125 SSL_ERROR_WANT_CERTIFICATE_VERIFY);
6126
6127 // The early data keys have not yet been released.
David Benjamin1e859052020-02-09 16:04:58 -05006128 EXPECT_FALSE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjaminee0716f2019-11-19 14:16:28 +08006129
6130 // After the verification completes, the handshake progresses to the 0-RTT
6131 // point and releases keys.
6132 SSL_set_custom_verify(
6133 client_.get(), SSL_VERIFY_PEER,
6134 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
6135 return ssl_verify_ok;
6136 });
6137 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6138 EXPECT_TRUE(SSL_in_early_data(client_.get()));
David Benjamin1e859052020-02-09 16:04:58 -05006139 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjaminee0716f2019-11-19 14:16:28 +08006140}
6141
Steven Valdezc8e0f902018-07-14 11:23:01 -04006142// Test only releasing data to QUIC one byte at a time on request, to maximize
6143// state machine pauses. Additionally, test that existing asynchronous callbacks
6144// still work.
6145TEST_F(QUICMethodTest, Async) {
David Benjamin1e859052020-02-09 16:04:58 -05006146 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006147
6148 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6149 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6150 ASSERT_TRUE(CreateClientAndServer());
6151
6152 // Install an asynchronous certificate callback.
6153 bool cert_cb_ok = false;
6154 SSL_set_cert_cb(server_.get(),
6155 [](SSL *, void *arg) -> int {
6156 return *static_cast<bool *>(arg) ? 1 : -1;
6157 },
6158 &cert_cb_ok);
6159
6160 for (;;) {
6161 int client_ret = SSL_do_handshake(client_.get());
6162 if (client_ret != 1) {
6163 ASSERT_EQ(client_ret, -1);
6164 ASSERT_EQ(SSL_get_error(client_.get(), client_ret), SSL_ERROR_WANT_READ);
6165 ASSERT_TRUE(ProvideHandshakeData(client_.get(), 1));
6166 }
6167
6168 int server_ret = SSL_do_handshake(server_.get());
6169 if (server_ret != 1) {
6170 ASSERT_EQ(server_ret, -1);
6171 int ssl_err = SSL_get_error(server_.get(), server_ret);
6172 switch (ssl_err) {
6173 case SSL_ERROR_WANT_READ:
6174 ASSERT_TRUE(ProvideHandshakeData(server_.get(), 1));
6175 break;
6176 case SSL_ERROR_WANT_X509_LOOKUP:
6177 ASSERT_FALSE(cert_cb_ok);
6178 cert_cb_ok = true;
6179 break;
6180 default:
6181 FAIL() << "Unexpected SSL_get_error result: " << ssl_err;
6182 }
6183 }
6184
6185 if (client_ret == 1 && server_ret == 1) {
6186 break;
6187 }
6188 }
6189
David Benjamind6343572019-08-15 17:29:02 -04006190 ExpectHandshakeSuccess();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006191}
6192
6193// Test buffering write data until explicit flushes.
6194TEST_F(QUICMethodTest, Buffered) {
David Benjamin5298ef92020-03-13 12:17:30 -04006195 AllowOutOfOrderWrites();
6196
Steven Valdezc8e0f902018-07-14 11:23:01 -04006197 struct BufferedFlight {
6198 std::vector<uint8_t> data[kNumQUICLevels];
6199 };
6200 static UnownedSSLExData<BufferedFlight> buffered_flights;
6201
David Benjamincc9d9352018-10-30 19:45:22 -05006202 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
6203 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04006204 BufferedFlight *flight = buffered_flights.Get(ssl);
6205 flight->data[level].insert(flight->data[level].end(), data, data + len);
6206 return 1;
6207 };
6208
6209 auto flush_flight = [](SSL *ssl) -> int {
6210 BufferedFlight *flight = buffered_flights.Get(ssl);
6211 for (size_t level = 0; level < kNumQUICLevels; level++) {
6212 if (!flight->data[level].empty()) {
6213 if (!TransportFromSSL(ssl)->WriteHandshakeData(
6214 static_cast<ssl_encryption_level_t>(level),
6215 flight->data[level])) {
6216 return 0;
6217 }
6218 flight->data[level].clear();
6219 }
6220 }
6221 return 1;
6222 };
6223
David Benjamin1e859052020-02-09 16:04:58 -05006224 SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6225 quic_method.add_handshake_data = add_handshake_data;
6226 quic_method.flush_flight = flush_flight;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006227
6228 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6229 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6230 ASSERT_TRUE(CreateClientAndServer());
6231
6232 BufferedFlight client_flight, server_flight;
6233 buffered_flights.Set(client_.get(), &client_flight);
6234 buffered_flights.Set(server_.get(), &server_flight);
6235
David Benjamind6343572019-08-15 17:29:02 -04006236 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdezc8e0f902018-07-14 11:23:01 -04006237
David Benjamind6343572019-08-15 17:29:02 -04006238 ExpectHandshakeSuccess();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006239}
6240
6241// Test that excess data at one level is rejected. That is, if a single
6242// |SSL_provide_quic_data| call included both ServerHello and
6243// EncryptedExtensions in a single chunk, BoringSSL notices and rejects this on
6244// key change.
6245TEST_F(QUICMethodTest, ExcessProvidedData) {
David Benjamin5298ef92020-03-13 12:17:30 -04006246 AllowOutOfOrderWrites();
6247
David Benjamincc9d9352018-10-30 19:45:22 -05006248 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
6249 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04006250 // Switch everything to the initial level.
6251 return TransportFromSSL(ssl)->WriteHandshakeData(ssl_encryption_initial,
6252 MakeConstSpan(data, len));
6253 };
6254
David Benjamin1e859052020-02-09 16:04:58 -05006255 SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6256 quic_method.add_handshake_data = add_handshake_data;
Steven Valdezc8e0f902018-07-14 11:23:01 -04006257
6258 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6259 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6260 ASSERT_TRUE(CreateClientAndServer());
6261
6262 // Send the ClientHello and ServerHello through Finished.
6263 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6264 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
6265 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6266 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6267 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
6268
6269 // The client is still waiting for the ServerHello at initial
6270 // encryption.
6271 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
6272
David Benjamincc9d9352018-10-30 19:45:22 -05006273 // |add_handshake_data| incorrectly wrote everything at the initial level, so
6274 // this queues up ServerHello through Finished in one chunk.
Steven Valdezc8e0f902018-07-14 11:23:01 -04006275 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6276
6277 // The client reads ServerHello successfully, but then rejects the buffered
6278 // EncryptedExtensions on key change.
6279 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6280 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_SSL);
6281 uint32_t err = ERR_get_error();
6282 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
David Benjaminf9cc26f2020-02-09 16:49:31 -05006283 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_EXCESS_HANDSHAKE_DATA);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006284
David Benjamin1e859052020-02-09 16:04:58 -05006285 // The client sends an alert in response to this. The alert is sent at
6286 // handshake level because we install write secrets before read secrets and
6287 // the error is discovered when installing the read secret. (How to send
6288 // alerts on protocol syntax errors near key changes is ambiguous in general.)
David Benjamind6343572019-08-15 17:29:02 -04006289 ASSERT_TRUE(transport_->client()->has_alert());
David Benjamin1e859052020-02-09 16:04:58 -05006290 EXPECT_EQ(transport_->client()->alert_level(), ssl_encryption_handshake);
David Benjamind6343572019-08-15 17:29:02 -04006291 EXPECT_EQ(transport_->client()->alert(), SSL_AD_UNEXPECTED_MESSAGE);
Steven Valdezc8e0f902018-07-14 11:23:01 -04006292
David Benjamin5298ef92020-03-13 12:17:30 -04006293 // Sanity-check handshake secrets. The error is discovered while setting the
6294 // read secret, so only the write secret has been installed.
David Benjamin1e859052020-02-09 16:04:58 -05006295 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_handshake));
David Benjamin5298ef92020-03-13 12:17:30 -04006296 EXPECT_FALSE(transport_->client()->HasReadSecret(ssl_encryption_handshake));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006297}
6298
6299// Test that |SSL_provide_quic_data| will reject data at the wrong level.
6300TEST_F(QUICMethodTest, ProvideWrongLevel) {
David Benjamin1e859052020-02-09 16:04:58 -05006301 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006302
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 ASSERT_TRUE(CreateClientAndServer());
6306
6307 // Send the ClientHello and ServerHello through Finished.
6308 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6309 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
6310 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6311 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6312 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
6313
6314 // The client is still waiting for the ServerHello at initial
6315 // encryption.
6316 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
6317
6318 // Data cannot be provided at the next level.
6319 std::vector<uint8_t> data;
6320 ASSERT_TRUE(
David Benjamind6343572019-08-15 17:29:02 -04006321 transport_->client()->ReadHandshakeData(&data, ssl_encryption_initial));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006322 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_handshake,
6323 data.data(), data.size()));
6324 ERR_clear_error();
6325
6326 // Progress to EncryptedExtensions.
6327 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
6328 data.data(), data.size()));
6329 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6330 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
6331 ASSERT_EQ(ssl_encryption_handshake, SSL_quic_read_level(client_.get()));
6332
6333 // Data cannot be provided at the previous level.
6334 ASSERT_TRUE(
David Benjamind6343572019-08-15 17:29:02 -04006335 transport_->client()->ReadHandshakeData(&data, ssl_encryption_handshake));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006336 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
6337 data.data(), data.size()));
6338}
6339
6340TEST_F(QUICMethodTest, TooMuchData) {
David Benjamin1e859052020-02-09 16:04:58 -05006341 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006342
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 ASSERT_TRUE(CreateClientAndServer());
6346
6347 size_t limit =
6348 SSL_quic_max_handshake_flight_len(client_.get(), ssl_encryption_initial);
6349 uint8_t b = 0;
6350 for (size_t i = 0; i < limit; i++) {
6351 ASSERT_TRUE(
6352 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
6353 }
6354
6355 EXPECT_FALSE(
6356 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
6357}
6358
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006359// Provide invalid post-handshake data.
6360TEST_F(QUICMethodTest, BadPostHandshake) {
David Benjamin1e859052020-02-09 16:04:58 -05006361 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006362
6363 g_last_session = nullptr;
6364
6365 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6366 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6367 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6368 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6369 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04006370 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006371
6372 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
6373 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
David Benjamind6343572019-08-15 17:29:02 -04006374 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_application));
6375 EXPECT_FALSE(transport_->client()->has_alert());
6376 EXPECT_FALSE(transport_->server()->has_alert());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006377
6378 // Junk sent as part of post-handshake data should cause an error.
6379 uint8_t kJunk[] = {0x17, 0x0, 0x0, 0x4, 0xB, 0xE, 0xE, 0xF};
6380 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_application,
6381 kJunk, sizeof(kJunk)));
6382 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 0);
6383}
6384
Nick Harper80ddfc72020-03-11 18:26:31 -07006385static void ExpectReceivedTransportParamsEqual(const SSL *ssl,
6386 Span<const uint8_t> expected) {
6387 const uint8_t *received;
6388 size_t received_len;
6389 SSL_get_peer_quic_transport_params(ssl, &received, &received_len);
6390 ASSERT_EQ(received_len, expected.size());
6391 EXPECT_EQ(Bytes(received, received_len), Bytes(expected));
6392}
6393
6394TEST_F(QUICMethodTest, SetTransportParameters) {
6395 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6396 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6397 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6398
6399 ASSERT_TRUE(CreateClientAndServer());
6400 uint8_t kClientParams[] = {1, 2, 3, 4};
6401 uint8_t kServerParams[] = {5, 6, 7};
6402 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6403 sizeof(kClientParams)));
6404 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6405 sizeof(kServerParams)));
6406
6407 ASSERT_TRUE(CompleteHandshakesForQUIC());
6408 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6409 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6410}
6411
6412TEST_F(QUICMethodTest, SetTransportParamsInCallback) {
6413 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6414 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6415 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6416
6417 ASSERT_TRUE(CreateClientAndServer());
6418 uint8_t kClientParams[] = {1, 2, 3, 4};
6419 static uint8_t kServerParams[] = {5, 6, 7};
6420 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6421 sizeof(kClientParams)));
6422 SSL_CTX_set_tlsext_servername_callback(
6423 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
6424 EXPECT_TRUE(SSL_set_quic_transport_params(ssl, kServerParams,
6425 sizeof(kServerParams)));
6426 return SSL_TLSEXT_ERR_OK;
6427 });
6428
6429 ASSERT_TRUE(CompleteHandshakesForQUIC());
6430 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6431 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6432}
6433
Nick Harper6bfd25c2020-03-30 17:15:19 -07006434TEST_F(QUICMethodTest, ForbidCrossProtocolResumptionClient) {
6435 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6436
6437 g_last_session = nullptr;
6438
6439 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6440 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6441 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6442 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6443
6444 ASSERT_TRUE(CreateClientAndServer());
6445 ASSERT_TRUE(CompleteHandshakesForQUIC());
6446
6447 ExpectHandshakeSuccess();
6448 EXPECT_FALSE(SSL_session_reused(client_.get()));
6449 EXPECT_FALSE(SSL_session_reused(server_.get()));
6450
6451 // The server sent NewSessionTicket messages in the handshake.
6452 EXPECT_FALSE(g_last_session);
6453 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6454 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
6455 EXPECT_TRUE(g_last_session);
6456
6457 // Pretend that g_last_session came from a TLS-over-TCP connection.
6458 g_last_session.get()->is_quic = false;
6459
6460 // Create a second connection and verify that resumption does not occur with
6461 // a session from a non-QUIC connection. This tests that the client does not
6462 // offer over QUIC a session believed to be received over TCP. The server
6463 // believes this is a QUIC session, so if the client offered the session, the
6464 // server would have resumed it.
6465 ASSERT_TRUE(CreateClientAndServer());
6466 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
6467 SSL_set_session(client_.get(), session.get());
6468
6469 ASSERT_TRUE(CompleteHandshakesForQUIC());
6470 ExpectHandshakeSuccess();
6471 EXPECT_FALSE(SSL_session_reused(client_.get()));
6472 EXPECT_FALSE(SSL_session_reused(server_.get()));
6473}
6474
6475TEST_F(QUICMethodTest, ForbidCrossProtocolResumptionServer) {
6476 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6477
6478 g_last_session = nullptr;
6479
6480 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6481 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6482 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6483 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6484
6485 ASSERT_TRUE(CreateClientAndServer());
6486 ASSERT_TRUE(CompleteHandshakesForQUIC());
6487
6488 ExpectHandshakeSuccess();
6489 EXPECT_FALSE(SSL_session_reused(client_.get()));
6490 EXPECT_FALSE(SSL_session_reused(server_.get()));
6491
6492 // The server sent NewSessionTicket messages in the handshake.
6493 EXPECT_FALSE(g_last_session);
6494 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6495 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
6496 EXPECT_TRUE(g_last_session);
6497
6498 // Attempt a resumption with g_last_session using TLS_method.
6499 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
6500 ASSERT_TRUE(client_ctx);
6501
6502 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), nullptr));
6503
6504 bssl::UniquePtr<SSL> client(SSL_new(client_ctx.get())),
6505 server(SSL_new(server_ctx_.get()));
6506 ASSERT_TRUE(client);
6507 ASSERT_TRUE(server);
6508 SSL_set_connect_state(client.get());
6509 SSL_set_accept_state(server.get());
6510
6511 // The TLS-over-TCP client will refuse to resume with a quic session, so
6512 // mark is_quic = false to bypass the client check to test the server check.
6513 g_last_session.get()->is_quic = false;
6514 SSL_set_session(client.get(), g_last_session.get());
6515
6516 BIO *bio1, *bio2;
6517 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
6518
6519 // SSL_set_bio takes ownership.
6520 SSL_set_bio(client.get(), bio1, bio1);
6521 SSL_set_bio(server.get(), bio2, bio2);
6522 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
6523
6524 EXPECT_FALSE(SSL_session_reused(client.get()));
6525 EXPECT_FALSE(SSL_session_reused(server.get()));
6526}
6527
Nick Harper72cff812020-03-26 18:06:16 -07006528TEST_F(QUICMethodTest, ClientRejectsMissingTransportParams) {
6529 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6530 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6531 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6532
6533 ASSERT_TRUE(CreateClientAndServer());
6534 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), nullptr, 0));
6535 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
6536}
6537
6538TEST_F(QUICMethodTest, ServerRejectsMissingTransportParams) {
6539 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6540 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6541 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6542
6543 ASSERT_TRUE(CreateClientAndServer());
6544 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), nullptr, 0));
6545 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kClientError));
6546}
6547
David Schinazi3d8b8c32021-01-14 11:25:49 -08006548TEST_F(QUICMethodTest, QuicLegacyCodepointEnabled) {
6549 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6550 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6551 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6552
6553 ASSERT_TRUE(CreateClientAndServer());
6554 uint8_t kClientParams[] = {1, 2, 3, 4};
6555 uint8_t kServerParams[] = {5, 6, 7};
6556 SSL_set_quic_use_legacy_codepoint(client_.get(), 1);
6557 SSL_set_quic_use_legacy_codepoint(server_.get(), 1);
6558 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6559 sizeof(kClientParams)));
6560 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6561 sizeof(kServerParams)));
6562
6563 ASSERT_TRUE(CompleteHandshakesForQUIC());
6564 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6565 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6566}
6567
6568TEST_F(QUICMethodTest, QuicLegacyCodepointDisabled) {
6569 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6570 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6571 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6572
6573 ASSERT_TRUE(CreateClientAndServer());
6574 uint8_t kClientParams[] = {1, 2, 3, 4};
6575 uint8_t kServerParams[] = {5, 6, 7};
6576 SSL_set_quic_use_legacy_codepoint(client_.get(), 0);
6577 SSL_set_quic_use_legacy_codepoint(server_.get(), 0);
6578 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6579 sizeof(kClientParams)));
6580 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6581 sizeof(kServerParams)));
6582
6583 ASSERT_TRUE(CompleteHandshakesForQUIC());
6584 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6585 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6586}
6587
6588TEST_F(QUICMethodTest, QuicLegacyCodepointClientOnly) {
6589 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6590 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6591 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6592
6593 ASSERT_TRUE(CreateClientAndServer());
6594 uint8_t kClientParams[] = {1, 2, 3, 4};
6595 uint8_t kServerParams[] = {5, 6, 7};
6596 SSL_set_quic_use_legacy_codepoint(client_.get(), 1);
6597 SSL_set_quic_use_legacy_codepoint(server_.get(), 0);
6598 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6599 sizeof(kClientParams)));
6600 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6601 sizeof(kServerParams)));
6602
6603 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
6604}
6605
6606TEST_F(QUICMethodTest, QuicLegacyCodepointServerOnly) {
6607 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6608 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6609 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6610
6611 ASSERT_TRUE(CreateClientAndServer());
6612 uint8_t kClientParams[] = {1, 2, 3, 4};
6613 uint8_t kServerParams[] = {5, 6, 7};
6614 SSL_set_quic_use_legacy_codepoint(client_.get(), 0);
6615 SSL_set_quic_use_legacy_codepoint(server_.get(), 1);
6616 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6617 sizeof(kClientParams)));
6618 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6619 sizeof(kServerParams)));
6620
6621 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
6622}
6623
David Benjaminc47bfce2021-01-20 17:10:32 -05006624// Test that the default QUIC code point is consistent with
6625// |TLSEXT_TYPE_quic_transport_parameters|. This test ensures we remember to
6626// update the two values together.
6627TEST_F(QUICMethodTest, QuicCodePointDefault) {
6628 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6629 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6630 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6631 SSL_CTX_set_select_certificate_cb(
6632 server_ctx_.get(),
6633 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
6634 const uint8_t *data;
6635 size_t len;
6636 if (!SSL_early_callback_ctx_extension_get(
6637 client_hello, TLSEXT_TYPE_quic_transport_parameters, &data,
6638 &len)) {
6639 ADD_FAILURE() << "Could not find quic_transport_parameters extension";
6640 return ssl_select_cert_error;
6641 }
6642 return ssl_select_cert_success;
6643 });
6644
6645 ASSERT_TRUE(CreateClientAndServer());
6646 ASSERT_TRUE(CompleteHandshakesForQUIC());
6647}
6648
Adam Langley7540cc22019-04-18 09:56:13 -07006649extern "C" {
6650int BORINGSSL_enum_c_type_test(void);
6651}
6652
6653TEST(SSLTest, EnumTypes) {
6654 EXPECT_EQ(sizeof(int), sizeof(ssl_private_key_result_t));
6655 EXPECT_EQ(1, BORINGSSL_enum_c_type_test());
6656}
6657
David Benjaminb29e1e12019-05-06 14:44:46 -05006658TEST_P(SSLVersionTest, DoubleSSLError) {
6659 // Connect the inner SSL connections.
6660 ASSERT_TRUE(Connect());
6661
6662 // Make a pair of |BIO|s which wrap |client_| and |server_|.
6663 UniquePtr<BIO_METHOD> bio_method(BIO_meth_new(0, nullptr));
6664 ASSERT_TRUE(bio_method);
6665 ASSERT_TRUE(BIO_meth_set_read(
6666 bio_method.get(), [](BIO *bio, char *out, int len) -> int {
6667 SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
6668 int ret = SSL_read(ssl, out, len);
6669 int ssl_ret = SSL_get_error(ssl, ret);
6670 if (ssl_ret == SSL_ERROR_WANT_READ) {
6671 BIO_set_retry_read(bio);
6672 }
6673 return ret;
6674 }));
6675 ASSERT_TRUE(BIO_meth_set_write(
6676 bio_method.get(), [](BIO *bio, const char *in, int len) -> int {
6677 SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
6678 int ret = SSL_write(ssl, in, len);
6679 int ssl_ret = SSL_get_error(ssl, ret);
6680 if (ssl_ret == SSL_ERROR_WANT_WRITE) {
6681 BIO_set_retry_write(bio);
6682 }
6683 return ret;
6684 }));
6685 ASSERT_TRUE(BIO_meth_set_ctrl(
6686 bio_method.get(), [](BIO *bio, int cmd, long larg, void *parg) -> long {
6687 // |SSL| objects require |BIO_flush| support.
6688 if (cmd == BIO_CTRL_FLUSH) {
6689 return 1;
6690 }
6691 return 0;
6692 }));
6693
6694 UniquePtr<BIO> client_bio(BIO_new(bio_method.get()));
6695 ASSERT_TRUE(client_bio);
6696 BIO_set_data(client_bio.get(), client_.get());
6697 BIO_set_init(client_bio.get(), 1);
6698
6699 UniquePtr<BIO> server_bio(BIO_new(bio_method.get()));
6700 ASSERT_TRUE(server_bio);
6701 BIO_set_data(server_bio.get(), server_.get());
6702 BIO_set_init(server_bio.get(), 1);
6703
6704 // Wrap the inner connections in another layer of SSL.
6705 UniquePtr<SSL> client_outer(SSL_new(client_ctx_.get()));
6706 ASSERT_TRUE(client_outer);
6707 SSL_set_connect_state(client_outer.get());
6708 SSL_set_bio(client_outer.get(), client_bio.get(), client_bio.get());
6709 client_bio.release(); // |SSL_set_bio| takes ownership.
6710
6711 UniquePtr<SSL> server_outer(SSL_new(server_ctx_.get()));
6712 ASSERT_TRUE(server_outer);
6713 SSL_set_accept_state(server_outer.get());
6714 SSL_set_bio(server_outer.get(), server_bio.get(), server_bio.get());
6715 server_bio.release(); // |SSL_set_bio| takes ownership.
6716
6717 // Configure |client_outer| to reject the server certificate.
6718 SSL_set_custom_verify(
6719 client_outer.get(), SSL_VERIFY_PEER,
6720 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
6721 return ssl_verify_invalid;
6722 });
6723
6724 for (;;) {
6725 int client_ret = SSL_do_handshake(client_outer.get());
6726 int client_err = SSL_get_error(client_outer.get(), client_ret);
6727 if (client_err != SSL_ERROR_WANT_READ &&
6728 client_err != SSL_ERROR_WANT_WRITE) {
6729 // The client handshake should terminate on a certificate verification
6730 // error.
6731 EXPECT_EQ(SSL_ERROR_SSL, client_err);
6732 uint32_t err = ERR_peek_error();
6733 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
6734 EXPECT_EQ(SSL_R_CERTIFICATE_VERIFY_FAILED, ERR_GET_REASON(err));
6735 break;
6736 }
6737
6738 // Run the server handshake and continue.
6739 int server_ret = SSL_do_handshake(server_outer.get());
6740 int server_err = SSL_get_error(server_outer.get(), server_ret);
6741 ASSERT_TRUE(server_err == SSL_ERROR_NONE ||
6742 server_err == SSL_ERROR_WANT_READ ||
6743 server_err == SSL_ERROR_WANT_WRITE);
6744 }
6745}
6746
David Benjamin1b819472020-06-09 14:01:02 -04006747TEST_P(SSLVersionTest, SameKeyResume) {
6748 uint8_t key[48];
6749 RAND_bytes(key, sizeof(key));
6750
6751 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
6752 ASSERT_TRUE(server_ctx2);
6753 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
6754 ASSERT_TRUE(
6755 SSL_CTX_set_tlsext_ticket_keys(server_ctx_.get(), key, sizeof(key)));
6756 ASSERT_TRUE(
6757 SSL_CTX_set_tlsext_ticket_keys(server_ctx2.get(), key, sizeof(key)));
6758
6759 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6760 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
6761 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
6762
6763 // Establish a session for |server_ctx_|.
6764 bssl::UniquePtr<SSL_SESSION> session =
6765 CreateClientSession(client_ctx_.get(), server_ctx_.get());
6766 ASSERT_TRUE(session);
6767 ClientConfig config;
6768 config.session = session.get();
6769
6770 // Resuming with |server_ctx_| again works.
6771 bssl::UniquePtr<SSL> client, server;
6772 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6773 server_ctx_.get(), config));
6774 EXPECT_TRUE(SSL_session_reused(client.get()));
6775 EXPECT_TRUE(SSL_session_reused(server.get()));
6776
6777 // Resuming with |server_ctx2| also works.
6778 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6779 server_ctx2.get(), config));
6780 EXPECT_TRUE(SSL_session_reused(client.get()));
6781 EXPECT_TRUE(SSL_session_reused(server.get()));
6782}
6783
6784TEST_P(SSLVersionTest, DifferentKeyNoResume) {
6785 uint8_t key1[48], key2[48];
6786 RAND_bytes(key1, sizeof(key1));
6787 RAND_bytes(key2, sizeof(key2));
6788
6789 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
6790 ASSERT_TRUE(server_ctx2);
6791 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
6792 ASSERT_TRUE(
6793 SSL_CTX_set_tlsext_ticket_keys(server_ctx_.get(), key1, sizeof(key1)));
6794 ASSERT_TRUE(
6795 SSL_CTX_set_tlsext_ticket_keys(server_ctx2.get(), key2, sizeof(key2)));
6796
6797 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6798 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
6799 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
6800
6801 // Establish a session for |server_ctx_|.
6802 bssl::UniquePtr<SSL_SESSION> session =
6803 CreateClientSession(client_ctx_.get(), server_ctx_.get());
6804 ASSERT_TRUE(session);
6805 ClientConfig config;
6806 config.session = session.get();
6807
6808 // Resuming with |server_ctx_| again works.
6809 bssl::UniquePtr<SSL> client, server;
6810 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6811 server_ctx_.get(), config));
6812 EXPECT_TRUE(SSL_session_reused(client.get()));
6813 EXPECT_TRUE(SSL_session_reused(server.get()));
6814
6815 // Resuming with |server_ctx2| does not work.
6816 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6817 server_ctx2.get(), config));
6818 EXPECT_FALSE(SSL_session_reused(client.get()));
6819 EXPECT_FALSE(SSL_session_reused(server.get()));
6820}
6821
6822TEST_P(SSLVersionTest, UnrelatedServerNoResume) {
6823 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
6824 ASSERT_TRUE(server_ctx2);
6825 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
6826
6827 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6828 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
6829 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
6830
6831 // Establish a session for |server_ctx_|.
6832 bssl::UniquePtr<SSL_SESSION> session =
6833 CreateClientSession(client_ctx_.get(), server_ctx_.get());
6834 ASSERT_TRUE(session);
6835 ClientConfig config;
6836 config.session = session.get();
6837
6838 // Resuming with |server_ctx_| again works.
6839 bssl::UniquePtr<SSL> client, server;
6840 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6841 server_ctx_.get(), config));
6842 EXPECT_TRUE(SSL_session_reused(client.get()));
6843 EXPECT_TRUE(SSL_session_reused(server.get()));
6844
6845 // Resuming with |server_ctx2| does not work.
6846 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6847 server_ctx2.get(), config));
6848 EXPECT_FALSE(SSL_session_reused(client.get()));
6849 EXPECT_FALSE(SSL_session_reused(server.get()));
6850}
6851
Adam Langley47cefed2021-05-26 13:36:40 -07006852Span<const uint8_t> SessionIDOf(const SSL* ssl) {
6853 const SSL_SESSION *session = SSL_get_session(ssl);
6854 unsigned len;
6855 const uint8_t *data = SSL_SESSION_get_id(session, &len);
6856 return MakeConstSpan(data, len);
6857}
6858
6859TEST_P(SSLVersionTest, TicketSessionIDsMatch) {
6860 // This checks that the session IDs at client and server match after a ticket
6861 // resumption. It's unclear whether this should be true, but Envoy depends
6862 // on it in their tests so this will give an early signal if we break it.
6863 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6864 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
6865
6866 bssl::UniquePtr<SSL_SESSION> session =
6867 CreateClientSession(client_ctx_.get(), server_ctx_.get());
6868
6869 bssl::UniquePtr<SSL> client, server;
6870 ClientConfig config;
6871 config.session = session.get();
6872 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6873 server_ctx_.get(), config));
6874 EXPECT_TRUE(SSL_session_reused(client.get()));
6875 EXPECT_TRUE(SSL_session_reused(server.get()));
6876
6877 EXPECT_EQ(Bytes(SessionIDOf(client.get())), Bytes(SessionIDOf(server.get())));
6878}
6879
David Benjamin0e7dbd52019-05-15 16:01:18 -04006880TEST(SSLTest, WriteWhileExplicitRenegotiate) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04006881 bssl::UniquePtr<SSL_CTX> ctx(CreateContextWithTestCertificate(TLS_method()));
David Benjamin0e7dbd52019-05-15 16:01:18 -04006882 ASSERT_TRUE(ctx);
6883
David Benjamin0e7dbd52019-05-15 16:01:18 -04006884 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_2_VERSION));
6885 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_2_VERSION));
6886 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
6887 ctx.get(), "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"));
6888
6889 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04006890 ASSERT_TRUE(CreateClientAndServer(&client, &server, ctx.get(), ctx.get()));
David Benjamin0e7dbd52019-05-15 16:01:18 -04006891 SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_explicit);
David Benjamin9b2cdb72021-04-01 23:21:53 -04006892 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
David Benjamin0e7dbd52019-05-15 16:01:18 -04006893
6894 static const uint8_t kInput[] = {'h', 'e', 'l', 'l', 'o'};
6895
6896 // Write "hello" until the buffer is full, so |client| has a pending write.
6897 size_t num_writes = 0;
6898 for (;;) {
6899 int ret = SSL_write(client.get(), kInput, sizeof(kInput));
6900 if (ret != int(sizeof(kInput))) {
6901 ASSERT_EQ(-1, ret);
6902 ASSERT_EQ(SSL_ERROR_WANT_WRITE, SSL_get_error(client.get(), ret));
6903 break;
6904 }
6905 num_writes++;
6906 }
6907
6908 // Encrypt a HelloRequest.
6909 uint8_t in[] = {SSL3_MT_HELLO_REQUEST, 0, 0, 0};
6910#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
6911 // Fuzzer-mode records are unencrypted.
6912 uint8_t record[5 + sizeof(in)];
6913 record[0] = SSL3_RT_HANDSHAKE;
6914 record[1] = 3;
6915 record[2] = 3; // TLS 1.2
6916 record[3] = 0;
6917 record[4] = sizeof(record) - 5;
6918 memcpy(record + 5, in, sizeof(in));
6919#else
6920 // Extract key material from |server|.
6921 static const size_t kKeyLen = 32;
6922 static const size_t kNonceLen = 12;
6923 ASSERT_EQ(2u * (kKeyLen + kNonceLen), SSL_get_key_block_len(server.get()));
6924 uint8_t key_block[2u * (kKeyLen + kNonceLen)];
6925 ASSERT_TRUE(
6926 SSL_generate_key_block(server.get(), key_block, sizeof(key_block)));
6927 Span<uint8_t> key = MakeSpan(key_block + kKeyLen, kKeyLen);
6928 Span<uint8_t> nonce =
6929 MakeSpan(key_block + kKeyLen + kKeyLen + kNonceLen, kNonceLen);
6930
6931 uint8_t ad[13];
6932 uint64_t seq = SSL_get_write_sequence(server.get());
6933 for (size_t i = 0; i < 8; i++) {
6934 // The nonce is XORed with the sequence number.
6935 nonce[11 - i] ^= uint8_t(seq);
6936 ad[7 - i] = uint8_t(seq);
6937 seq >>= 8;
6938 }
6939
6940 ad[8] = SSL3_RT_HANDSHAKE;
6941 ad[9] = 3;
6942 ad[10] = 3; // TLS 1.2
6943 ad[11] = 0;
6944 ad[12] = sizeof(in);
6945
6946 uint8_t record[5 + sizeof(in) + 16];
6947 record[0] = SSL3_RT_HANDSHAKE;
6948 record[1] = 3;
6949 record[2] = 3; // TLS 1.2
6950 record[3] = 0;
6951 record[4] = sizeof(record) - 5;
6952
6953 ScopedEVP_AEAD_CTX aead;
6954 ASSERT_TRUE(EVP_AEAD_CTX_init(aead.get(), EVP_aead_chacha20_poly1305(),
6955 key.data(), key.size(),
6956 EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr));
6957 size_t len;
6958 ASSERT_TRUE(EVP_AEAD_CTX_seal(aead.get(), record + 5, &len,
6959 sizeof(record) - 5, nonce.data(), nonce.size(),
6960 in, sizeof(in), ad, sizeof(ad)));
6961 ASSERT_EQ(sizeof(record) - 5, len);
6962#endif // BORINGSSL_UNSAFE_FUZZER_MODE
6963
6964 ASSERT_EQ(int(sizeof(record)),
6965 BIO_write(SSL_get_wbio(server.get()), record, sizeof(record)));
6966
6967 // |SSL_read| should pick up the HelloRequest.
6968 uint8_t byte;
6969 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
6970 ASSERT_EQ(SSL_ERROR_WANT_RENEGOTIATE, SSL_get_error(client.get(), -1));
6971
6972 // Drain the data from the |client|.
6973 uint8_t buf[sizeof(kInput)];
6974 for (size_t i = 0; i < num_writes; i++) {
6975 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
6976 EXPECT_EQ(Bytes(buf), Bytes(kInput));
6977 }
6978
6979 // |client| should be able to finish the pending write and continue to write,
6980 // despite the paused HelloRequest.
6981 ASSERT_EQ(int(sizeof(kInput)),
6982 SSL_write(client.get(), kInput, sizeof(kInput)));
6983 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
6984 EXPECT_EQ(Bytes(buf), Bytes(kInput));
6985
6986 ASSERT_EQ(int(sizeof(kInput)),
6987 SSL_write(client.get(), kInput, sizeof(kInput)));
6988 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
6989 EXPECT_EQ(Bytes(buf), Bytes(kInput));
6990
6991 // |SSL_read| is stuck until we acknowledge the HelloRequest.
6992 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
6993 ASSERT_EQ(SSL_ERROR_WANT_RENEGOTIATE, SSL_get_error(client.get(), -1));
6994
6995 ASSERT_TRUE(SSL_renegotiate(client.get()));
6996 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
6997 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
6998
6999 // We never renegotiate as a server.
7000 ASSERT_EQ(-1, SSL_read(server.get(), buf, sizeof(buf)));
7001 ASSERT_EQ(SSL_ERROR_SSL, SSL_get_error(server.get(), -1));
7002 uint32_t err = ERR_get_error();
7003 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
7004 EXPECT_EQ(SSL_R_NO_RENEGOTIATION, ERR_GET_REASON(err));
7005}
7006
David Benjaminf9e0cda2020-03-23 18:29:09 -04007007
7008TEST(SSLTest, CopyWithoutEarlyData) {
7009 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04007010 bssl::UniquePtr<SSL_CTX> server_ctx(
7011 CreateContextWithTestCertificate(TLS_method()));
David Benjaminf9e0cda2020-03-23 18:29:09 -04007012 ASSERT_TRUE(client_ctx);
7013 ASSERT_TRUE(server_ctx);
7014
David Benjaminf9e0cda2020-03-23 18:29:09 -04007015 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
7016 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
7017 SSL_CTX_set_early_data_enabled(client_ctx.get(), 1);
7018 SSL_CTX_set_early_data_enabled(server_ctx.get(), 1);
7019
7020 bssl::UniquePtr<SSL_SESSION> session =
7021 CreateClientSession(client_ctx.get(), server_ctx.get());
7022 ASSERT_TRUE(session);
7023
7024 // The client should attempt early data with |session|.
David Benjaminf9e0cda2020-03-23 18:29:09 -04007025 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04007026 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7027 server_ctx.get()));
7028 SSL_set_session(client.get(), session.get());
7029 SSL_set_early_data_enabled(client.get(), 1);
David Benjaminf9e0cda2020-03-23 18:29:09 -04007030 ASSERT_EQ(1, SSL_do_handshake(client.get()));
7031 EXPECT_TRUE(SSL_in_early_data(client.get()));
7032
7033 // |SSL_SESSION_copy_without_early_data| should disable early data but
7034 // still resume the session.
7035 bssl::UniquePtr<SSL_SESSION> session2(
7036 SSL_SESSION_copy_without_early_data(session.get()));
7037 ASSERT_TRUE(session2);
7038 EXPECT_NE(session.get(), session2.get());
David Benjamin9b2cdb72021-04-01 23:21:53 -04007039 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7040 server_ctx.get()));
7041 SSL_set_session(client.get(), session2.get());
7042 SSL_set_early_data_enabled(client.get(), 1);
7043 EXPECT_TRUE(CompleteHandshakes(client.get(), server.get()));
David Benjaminf9e0cda2020-03-23 18:29:09 -04007044 EXPECT_TRUE(SSL_session_reused(client.get()));
7045 EXPECT_EQ(ssl_early_data_unsupported_for_session,
7046 SSL_get_early_data_reason(client.get()));
7047
7048 // |SSL_SESSION_copy_without_early_data| should be a reference count increase
7049 // when passed an early-data-incapable session.
7050 bssl::UniquePtr<SSL_SESSION> session3(
7051 SSL_SESSION_copy_without_early_data(session2.get()));
7052 EXPECT_EQ(session2.get(), session3.get());
7053}
7054
Adam Langley53a17f52020-05-26 14:44:07 -07007055TEST(SSLTest, ProcessTLS13NewSessionTicket) {
7056 // Configure client and server to negotiate TLS 1.3 only.
Adam Langley53a17f52020-05-26 14:44:07 -07007057 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04007058 bssl::UniquePtr<SSL_CTX> server_ctx(
7059 CreateContextWithTestCertificate(TLS_method()));
Adam Langley53a17f52020-05-26 14:44:07 -07007060 ASSERT_TRUE(client_ctx);
7061 ASSERT_TRUE(server_ctx);
7062 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
7063 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
7064 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
7065 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
Adam Langley53a17f52020-05-26 14:44:07 -07007066
7067 bssl::UniquePtr<SSL> client, server;
7068 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
7069 server_ctx.get()));
7070 EXPECT_EQ(TLS1_3_VERSION, SSL_version(client.get()));
7071
7072 // Process a TLS 1.3 NewSessionTicket.
7073 static const uint8_t kTicket[] = {
7074 0x04, 0x00, 0x00, 0xb2, 0x00, 0x02, 0xa3, 0x00, 0x04, 0x03, 0x02, 0x01,
7075 0x01, 0x00, 0x00, 0xa0, 0x01, 0x06, 0x09, 0x11, 0x16, 0x19, 0x21, 0x26,
7076 0x29, 0x31, 0x36, 0x39, 0x41, 0x46, 0x49, 0x51, 0x03, 0x06, 0x09, 0x13,
7077 0x16, 0x19, 0x23, 0x26, 0x29, 0x33, 0x36, 0x39, 0x43, 0x46, 0x49, 0x53,
7078 0xf7, 0x00, 0x29, 0xec, 0xf2, 0xc4, 0xa4, 0x41, 0xfc, 0x30, 0x17, 0x2e,
7079 0x9f, 0x7c, 0xa8, 0xaf, 0x75, 0x70, 0xf0, 0x1f, 0xc7, 0x98, 0xf7, 0xcf,
7080 0x5a, 0x5a, 0x6b, 0x5b, 0xfe, 0xf1, 0xe7, 0x3a, 0xe8, 0xf7, 0x6c, 0xd2,
7081 0xa8, 0xa6, 0x92, 0x5b, 0x96, 0x8d, 0xde, 0xdb, 0xd3, 0x20, 0x6a, 0xcb,
7082 0x69, 0x06, 0xf4, 0x91, 0x85, 0x2e, 0xe6, 0x5e, 0x0c, 0x59, 0xf2, 0x9e,
7083 0x9b, 0x79, 0x91, 0x24, 0x7e, 0x4a, 0x32, 0x3d, 0xbe, 0x4b, 0x80, 0x70,
7084 0xaf, 0xd0, 0x1d, 0xe2, 0xca, 0x05, 0x35, 0x09, 0x09, 0x05, 0x0f, 0xbb,
7085 0xc4, 0xae, 0xd7, 0xc4, 0xed, 0xd7, 0xae, 0x35, 0xc8, 0x73, 0x63, 0x78,
7086 0x64, 0xc9, 0x7a, 0x1f, 0xed, 0x7a, 0x9a, 0x47, 0x44, 0xfd, 0x50, 0xf7,
7087 0xb7, 0xe0, 0x64, 0xa9, 0x02, 0xc1, 0x5c, 0x23, 0x18, 0x3f, 0xc4, 0xcf,
7088 0x72, 0x02, 0x59, 0x2d, 0xe1, 0xaa, 0x61, 0x72, 0x00, 0x04, 0x5a, 0x5a,
7089 0x00, 0x00,
7090 };
7091 bssl::UniquePtr<SSL_SESSION> session(SSL_process_tls13_new_session_ticket(
7092 client.get(), kTicket, sizeof(kTicket)));
7093 ASSERT_TRUE(session);
7094 ASSERT_TRUE(SSL_SESSION_has_ticket(session.get()));
7095
7096 uint8_t *session_buf = nullptr;
7097 size_t session_length = 0;
7098 ASSERT_TRUE(
7099 SSL_SESSION_to_bytes(session.get(), &session_buf, &session_length));
7100 bssl::UniquePtr<uint8_t> session_buf_free(session_buf);
7101 ASSERT_TRUE(session_buf);
7102 ASSERT_GT(session_length, 0u);
7103
7104 // Servers cannot call |SSL_process_tls13_new_session_ticket|.
7105 ASSERT_FALSE(SSL_process_tls13_new_session_ticket(server.get(), kTicket,
7106 sizeof(kTicket)));
7107
7108 // Clients cannot call |SSL_process_tls13_new_session_ticket| before the
7109 // handshake completes.
7110 bssl::UniquePtr<SSL> client2(SSL_new(client_ctx.get()));
7111 ASSERT_TRUE(client2);
7112 SSL_set_connect_state(client2.get());
7113 ASSERT_FALSE(SSL_process_tls13_new_session_ticket(client2.get(), kTicket,
7114 sizeof(kTicket)));
7115}
7116
David Benjamin3989c992020-10-09 14:12:06 -04007117TEST(SSLTest, BIO) {
7118 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04007119 bssl::UniquePtr<SSL_CTX> server_ctx(
7120 CreateContextWithTestCertificate(TLS_method()));
David Benjamin3989c992020-10-09 14:12:06 -04007121 ASSERT_TRUE(client_ctx);
7122 ASSERT_TRUE(server_ctx);
7123
David Benjamin3989c992020-10-09 14:12:06 -04007124 for (bool take_ownership : {true, false}) {
7125 // For simplicity, get the handshake out of the way first.
7126 bssl::UniquePtr<SSL> client, server;
7127 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
7128 server_ctx.get()));
7129
7130 // Wrap |client| in an SSL BIO.
7131 bssl::UniquePtr<BIO> client_bio(BIO_new(BIO_f_ssl()));
7132 ASSERT_TRUE(client_bio);
7133 ASSERT_EQ(1, BIO_set_ssl(client_bio.get(), client.get(), take_ownership));
7134 if (take_ownership) {
7135 client.release();
7136 }
7137
7138 // Flushing the BIO should not crash.
7139 EXPECT_EQ(1, BIO_flush(client_bio.get()));
7140
7141 // Exchange some data.
7142 EXPECT_EQ(5, BIO_write(client_bio.get(), "hello", 5));
7143 uint8_t buf[5];
7144 ASSERT_EQ(5, SSL_read(server.get(), buf, sizeof(buf)));
7145 EXPECT_EQ(Bytes("hello"), Bytes(buf));
7146
7147 EXPECT_EQ(5, SSL_write(server.get(), "world", 5));
7148 ASSERT_EQ(5, BIO_read(client_bio.get(), buf, sizeof(buf)));
7149 EXPECT_EQ(Bytes("world"), Bytes(buf));
7150
7151 // |BIO_should_read| should work.
7152 EXPECT_EQ(-1, BIO_read(client_bio.get(), buf, sizeof(buf)));
7153 EXPECT_TRUE(BIO_should_read(client_bio.get()));
7154
7155 // Writing data should eventually exceed the buffer size and fail, reporting
7156 // |BIO_should_write|.
7157 int ret;
7158 for (int i = 0; i < 1024; i++) {
7159 std::vector<uint8_t> buffer(1024);
7160 ret = BIO_write(client_bio.get(), buffer.data(), buffer.size());
7161 if (ret <= 0) {
7162 break;
7163 }
7164 }
7165 EXPECT_EQ(-1, ret);
7166 EXPECT_TRUE(BIO_should_write(client_bio.get()));
7167 }
7168}
7169
David Benjamin12a3e7e2021-04-13 11:47:36 -04007170TEST(SSLTest, ALPNConfig) {
7171 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
7172 ASSERT_TRUE(ctx);
7173 bssl::UniquePtr<X509> cert = GetTestCertificate();
7174 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
7175 ASSERT_TRUE(cert);
7176 ASSERT_TRUE(key);
7177 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
7178 ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
7179
7180 // Set up some machinery to check the configured ALPN against what is actually
7181 // sent over the wire. Note that the ALPN callback is only called when the
7182 // client offers ALPN.
7183 std::vector<uint8_t> observed_alpn;
7184 SSL_CTX_set_alpn_select_cb(
7185 ctx.get(),
7186 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
7187 unsigned in_len, void *arg) -> int {
7188 std::vector<uint8_t> *observed_alpn_ptr =
7189 static_cast<std::vector<uint8_t> *>(arg);
7190 observed_alpn_ptr->assign(in, in + in_len);
7191 return SSL_TLSEXT_ERR_NOACK;
7192 },
7193 &observed_alpn);
7194 auto check_alpn_proto = [&](Span<const uint8_t> expected) {
7195 observed_alpn.clear();
7196 bssl::UniquePtr<SSL> client, server;
7197 EXPECT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
7198 EXPECT_EQ(Bytes(expected), Bytes(observed_alpn));
7199 };
7200
7201 // Note that |SSL_CTX_set_alpn_protos|'s return value is reversed.
7202 static const uint8_t kValidList[] = {0x03, 'f', 'o', 'o',
7203 0x03, 'b', 'a', 'r'};
7204 EXPECT_EQ(0,
7205 SSL_CTX_set_alpn_protos(ctx.get(), kValidList, sizeof(kValidList)));
7206 check_alpn_proto(kValidList);
7207
7208 // Invalid lists are rejected.
7209 static const uint8_t kInvalidList[] = {0x04, 'f', 'o', 'o'};
7210 EXPECT_EQ(1, SSL_CTX_set_alpn_protos(ctx.get(), kInvalidList,
7211 sizeof(kInvalidList)));
7212
7213 // Empty lists are valid and are interpreted as disabling ALPN.
7214 EXPECT_EQ(0, SSL_CTX_set_alpn_protos(ctx.get(), nullptr, 0));
7215 check_alpn_proto({});
7216}
7217
David Benjamin2f3958a2021-04-16 11:55:23 -04007218// Test that the key usage checker can correctly handle issuerUID and
7219// subjectUID. See https://crbug.com/1199744.
7220TEST(SSLTest, KeyUsageWithUIDs) {
7221 static const char kGoodKeyUsage[] = R"(
7222-----BEGIN CERTIFICATE-----
7223MIIB7DCCAZOgAwIBAgIJANlMBNpJfb/rMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYT
7224AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn
7225aXRzIFB0eSBMdGQwHhcNMTQwNDIzMjMyMTU3WhcNMTQwNTIzMjMyMTU3WjBFMQsw
7226CQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJu
7227ZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp
72284r9ln5e+Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsW
7229Ghz1HX7xlC1Lz3IiwYEEABI0VoIEABI0VqNgMF4wHQYDVR0OBBYEFKuE0qyrlfCC
7230ThZ4B1VXX+QmjYLRMB8GA1UdIwQYMBaAFKuE0qyrlfCCThZ4B1VXX+QmjYLRMA4G
7231A1UdDwEB/wQEAwIHgDAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0cAMEQCIEWJ
723234EcqW5MHwLIA1hZ2Tj/jV2QjN02KLxis9mFsqDKAiAMlMTkzsM51vVs9Ohqa+Rc
72334Z7qDhjIhiF4dM0uEDYRVA==
7234-----END CERTIFICATE-----
7235)";
7236 static const char kBadKeyUsage[] = R"(
7237-----BEGIN CERTIFICATE-----
7238MIIB7jCCAZOgAwIBAgIJANlMBNpJfb/rMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYT
7239AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn
7240aXRzIFB0eSBMdGQwHhcNMTQwNDIzMjMyMTU3WhcNMTQwNTIzMjMyMTU3WjBFMQsw
7241CQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJu
7242ZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp
72434r9ln5e+Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsW
7244Ghz1HX7xlC1Lz3IiwYEEABI0VoIEABI0VqNgMF4wHQYDVR0OBBYEFKuE0qyrlfCC
7245ThZ4B1VXX+QmjYLRMB8GA1UdIwQYMBaAFKuE0qyrlfCCThZ4B1VXX+QmjYLRMA4G
7246A1UdDwEB/wQEAwIDCDAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0kAMEYCIQC6
7247taYBUDu2gcZC6EMk79FBHArYI0ucF+kzvETegZCbBAIhANtObFec5gtso/47moPD
7248RHrQbWsFUakETXL9QMlegh5t
7249-----END CERTIFICATE-----
7250)";
7251
7252 bssl::UniquePtr<X509> good = CertFromPEM(kGoodKeyUsage);
7253 ASSERT_TRUE(good);
7254 bssl::UniquePtr<X509> bad = CertFromPEM(kBadKeyUsage);
7255 ASSERT_TRUE(bad);
7256
7257 // We check key usage when configuring EC certificates to distinguish ECDSA
7258 // and ECDH.
7259 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
7260 ASSERT_TRUE(ctx);
7261 EXPECT_TRUE(SSL_CTX_use_certificate(ctx.get(), good.get()));
7262 EXPECT_FALSE(SSL_CTX_use_certificate(ctx.get(), bad.get()));
7263}
7264
David Benjamin9b2cdb72021-04-01 23:21:53 -04007265// Test that |SSL_can_release_private_key| reports true as early as expected.
7266// The internal asserts in the library check we do not report true too early.
7267TEST(SSLTest, CanReleasePrivateKey) {
7268 bssl::UniquePtr<SSL_CTX> client_ctx =
7269 CreateContextWithTestCertificate(TLS_method());
7270 ASSERT_TRUE(client_ctx);
7271 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
7272
7273 // Note this assumes the transport buffer is large enough to fit the client
7274 // and server first flights. We check this with |SSL_ERROR_WANT_READ|. If the
7275 // transport buffer was too small it would return |SSL_ERROR_WANT_WRITE|.
7276 auto check_first_server_round_trip = [&](SSL *client, SSL *server) {
7277 // Write the ClientHello.
7278 ASSERT_EQ(-1, SSL_do_handshake(client));
7279 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client, -1));
7280
7281 // Consume the ClientHello and write the server flight.
7282 ASSERT_EQ(-1, SSL_do_handshake(server));
7283 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server, -1));
7284
7285 EXPECT_TRUE(SSL_can_release_private_key(server));
7286 };
7287
7288 {
7289 SCOPED_TRACE("TLS 1.2 ECDHE");
7290 bssl::UniquePtr<SSL_CTX> server_ctx(
7291 CreateContextWithTestCertificate(TLS_method()));
7292 ASSERT_TRUE(server_ctx);
7293 ASSERT_TRUE(
7294 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
7295 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
7296 server_ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
7297 // Configure the server to request client certificates, so we can also test
7298 // the client half.
7299 SSL_CTX_set_custom_verify(
7300 server_ctx.get(), SSL_VERIFY_PEER,
7301 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
7302 bssl::UniquePtr<SSL> client, server;
7303 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7304 server_ctx.get()));
7305 check_first_server_round_trip(client.get(), server.get());
7306
7307 // Consume the server flight and write the client response. The client still
7308 // has a Finished message to consume but can also release its key early.
7309 ASSERT_EQ(-1, SSL_do_handshake(client.get()));
7310 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
7311 EXPECT_TRUE(SSL_can_release_private_key(client.get()));
7312
7313 // However, a client that has not disabled renegotiation can never release
7314 // the key.
7315 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7316 server_ctx.get()));
7317 SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_freely);
7318 check_first_server_round_trip(client.get(), server.get());
7319 ASSERT_EQ(-1, SSL_do_handshake(client.get()));
7320 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
7321 EXPECT_FALSE(SSL_can_release_private_key(client.get()));
7322 }
7323
7324 {
7325 SCOPED_TRACE("TLS 1.2 resumption");
7326 bssl::UniquePtr<SSL_CTX> server_ctx(
7327 CreateContextWithTestCertificate(TLS_method()));
7328 ASSERT_TRUE(server_ctx);
7329 ASSERT_TRUE(
7330 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
7331 bssl::UniquePtr<SSL_SESSION> session =
7332 CreateClientSession(client_ctx.get(), server_ctx.get());
7333 ASSERT_TRUE(session);
7334 bssl::UniquePtr<SSL> client, server;
7335 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7336 server_ctx.get()));
7337 SSL_set_session(client.get(), session.get());
7338 check_first_server_round_trip(client.get(), server.get());
7339 }
7340
7341 {
7342 SCOPED_TRACE("TLS 1.3 1-RTT");
7343 bssl::UniquePtr<SSL_CTX> server_ctx(
7344 CreateContextWithTestCertificate(TLS_method()));
7345 ASSERT_TRUE(server_ctx);
7346 ASSERT_TRUE(
7347 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
7348 bssl::UniquePtr<SSL> client, server;
7349 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7350 server_ctx.get()));
7351 check_first_server_round_trip(client.get(), server.get());
7352 }
7353
7354 {
7355 SCOPED_TRACE("TLS 1.3 resumption");
7356 bssl::UniquePtr<SSL_CTX> server_ctx(
7357 CreateContextWithTestCertificate(TLS_method()));
7358 ASSERT_TRUE(server_ctx);
7359 ASSERT_TRUE(
7360 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
7361 bssl::UniquePtr<SSL_SESSION> session =
7362 CreateClientSession(client_ctx.get(), server_ctx.get());
7363 ASSERT_TRUE(session);
7364 bssl::UniquePtr<SSL> client, server;
7365 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7366 server_ctx.get()));
7367 SSL_set_session(client.get(), session.get());
7368 check_first_server_round_trip(client.get(), server.get());
7369 }
7370}
7371
Martin Kreichgauer72912d22017-08-04 12:06:43 -07007372} // namespace
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -07007373BSSL_NAMESPACE_END