blob: a8e6a0c2a5d2cbfd343134032ff49d2ac1082418 [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 Benjaminc79ae7a2017-08-29 16:09:44 -04001409// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
1410// before configuring as a server.
1411TEST(SSLTest, ClientCAList) {
1412 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1413 ASSERT_TRUE(ctx);
1414 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1415 ASSERT_TRUE(ssl);
1416
1417 bssl::UniquePtr<X509_NAME> name(X509_NAME_new());
1418 ASSERT_TRUE(name);
1419
1420 bssl::UniquePtr<X509_NAME> name_dup(X509_NAME_dup(name.get()));
1421 ASSERT_TRUE(name_dup);
1422
1423 bssl::UniquePtr<STACK_OF(X509_NAME)> stack(sk_X509_NAME_new_null());
1424 ASSERT_TRUE(stack);
David Benjamin2908dd12018-06-29 17:46:42 -04001425 ASSERT_TRUE(PushToStack(stack.get(), std::move(name_dup)));
David Benjaminc79ae7a2017-08-29 16:09:44 -04001426
1427 // |SSL_set_client_CA_list| takes ownership.
1428 SSL_set_client_CA_list(ssl.get(), stack.release());
1429
1430 STACK_OF(X509_NAME) *result = SSL_get_client_CA_list(ssl.get());
1431 ASSERT_TRUE(result);
1432 ASSERT_EQ(1u, sk_X509_NAME_num(result));
1433 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(result, 0), name.get()));
1434}
1435
1436TEST(SSLTest, AddClientCA) {
1437 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1438 ASSERT_TRUE(ctx);
1439 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1440 ASSERT_TRUE(ssl);
1441
1442 bssl::UniquePtr<X509> cert1 = GetTestCertificate();
1443 bssl::UniquePtr<X509> cert2 = GetChainTestCertificate();
1444 ASSERT_TRUE(cert1 && cert2);
1445 X509_NAME *name1 = X509_get_subject_name(cert1.get());
1446 X509_NAME *name2 = X509_get_subject_name(cert2.get());
1447
1448 EXPECT_EQ(0u, sk_X509_NAME_num(SSL_get_client_CA_list(ssl.get())));
1449
1450 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1451 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert2.get()));
1452
1453 STACK_OF(X509_NAME) *list = SSL_get_client_CA_list(ssl.get());
1454 ASSERT_EQ(2u, sk_X509_NAME_num(list));
1455 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1456 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1457
1458 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1459
1460 list = SSL_get_client_CA_list(ssl.get());
1461 ASSERT_EQ(3u, sk_X509_NAME_num(list));
1462 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1463 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1464 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 2), name1));
1465}
1466
Daniel McArdle00e434d2021-02-18 11:47:18 -05001467// kECHConfig contains a serialized ECHConfig value.
1468static const uint8_t kECHConfig[] = {
1469 // version
Steven Valdez94a63a52021-04-29 10:52:42 -04001470 0xfe, 0x0a,
Daniel McArdle00e434d2021-02-18 11:47:18 -05001471 // length
Steven Valdez94a63a52021-04-29 10:52:42 -04001472 0x00, 0x43,
1473 // contents.config_id
1474 0x42,
1475 // contents.kem_id
1476 0x00, 0x20,
Daniel McArdle00e434d2021-02-18 11:47:18 -05001477 // contents.public_key
1478 0x00, 0x20, 0xa6, 0x9a, 0x41, 0x48, 0x5d, 0x32, 0x96, 0xa4, 0xe0, 0xc3,
1479 0x6a, 0xee, 0xf6, 0x63, 0x0f, 0x59, 0x32, 0x6f, 0xdc, 0xff, 0x81, 0x29,
1480 0x59, 0xa5, 0x85, 0xd3, 0x9b, 0x3b, 0xde, 0x98, 0x55, 0x5c,
Daniel McArdle00e434d2021-02-18 11:47:18 -05001481 // contents.cipher_suites
1482 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x03,
1483 // contents.maximum_name_length
1484 0x00, 0x10,
Steven Valdez94a63a52021-04-29 10:52:42 -04001485 // contents.public_name
1486 0x00, 0x0e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2e, 0x65, 0x78, 0x61,
1487 0x6d, 0x70, 0x6c, 0x65,
Daniel McArdle00e434d2021-02-18 11:47:18 -05001488 // contents.extensions
1489 0x00, 0x00};
1490
David Benjaminc3b373b2021-06-06 13:04:26 -04001491// kECHPublicKey is the public key encoded in |kECHConfig|.
1492static const uint8_t kECHPublicKey[X25519_PUBLIC_VALUE_LEN] = {
Daniel McArdle00e434d2021-02-18 11:47:18 -05001493 0xa6, 0x9a, 0x41, 0x48, 0x5d, 0x32, 0x96, 0xa4, 0xe0, 0xc3, 0x6a,
1494 0xee, 0xf6, 0x63, 0x0f, 0x59, 0x32, 0x6f, 0xdc, 0xff, 0x81, 0x29,
1495 0x59, 0xa5, 0x85, 0xd3, 0x9b, 0x3b, 0xde, 0x98, 0x55, 0x5c};
1496
David Benjaminc3b373b2021-06-06 13:04:26 -04001497// kECHPrivateKey is the X25519 private key corresponding to |kECHPublicKey|.
1498static const uint8_t kECHPrivateKey[X25519_PRIVATE_KEY_LEN] = {
Daniel McArdle00e434d2021-02-18 11:47:18 -05001499 0xbc, 0xb5, 0x51, 0x29, 0x31, 0x10, 0x30, 0xc9, 0xed, 0x26, 0xde,
1500 0xd4, 0xb3, 0xdf, 0x3a, 0xce, 0x06, 0x8a, 0xee, 0x17, 0xab, 0xce,
1501 0xd7, 0xdb, 0xf3, 0x11, 0xe5, 0xa8, 0xf3, 0xb1, 0x8e, 0x24};
1502
1503// MakeECHConfig serializes an ECHConfig and writes it to |*out| with the
1504// specified parameters. |cipher_suites| is a list of code points which should
1505// contain pairs of KDF and AEAD IDs.
Steven Valdez94a63a52021-04-29 10:52:42 -04001506bool MakeECHConfig(std::vector<uint8_t> *out, uint8_t config_id,
1507 uint16_t kem_id, Span<const uint8_t> public_key,
Daniel McArdle00e434d2021-02-18 11:47:18 -05001508 Span<const uint16_t> cipher_suites,
1509 Span<const uint8_t> extensions) {
1510 bssl::ScopedCBB cbb;
1511 CBB contents, child;
1512 static const char kPublicName[] = "example.com";
1513 if (!CBB_init(cbb.get(), 64) ||
1514 !CBB_add_u16(cbb.get(), TLSEXT_TYPE_encrypted_client_hello) ||
1515 !CBB_add_u16_length_prefixed(cbb.get(), &contents) ||
Steven Valdez94a63a52021-04-29 10:52:42 -04001516 !CBB_add_u8(&contents, config_id) ||
1517 !CBB_add_u16(&contents, kem_id) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001518 !CBB_add_u16_length_prefixed(&contents, &child) ||
1519 !CBB_add_bytes(&child, public_key.data(), public_key.size()) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001520 !CBB_add_u16_length_prefixed(&contents, &child)) {
1521 return false;
1522 }
1523 for (uint16_t cipher_suite : cipher_suites) {
1524 if (!CBB_add_u16(&child, cipher_suite)) {
1525 return false;
1526 }
1527 }
1528 if (!CBB_add_u16(&contents, strlen(kPublicName)) || // maximum_name_length
1529 !CBB_add_u16_length_prefixed(&contents, &child) ||
Steven Valdez94a63a52021-04-29 10:52:42 -04001530 !CBB_add_bytes(&child, reinterpret_cast<const uint8_t *>(kPublicName),
1531 strlen(kPublicName)) ||
1532 !CBB_add_u16_length_prefixed(&contents, &child) ||
Daniel McArdle00e434d2021-02-18 11:47:18 -05001533 !CBB_add_bytes(&child, extensions.data(), extensions.size()) ||
1534 !CBB_flush(cbb.get())) {
1535 return false;
1536 }
1537
1538 out->assign(CBB_data(cbb.get()), CBB_data(cbb.get()) + CBB_len(cbb.get()));
1539 return true;
1540}
1541
David Benjaminc3b373b2021-06-06 13:04:26 -04001542TEST(SSLTest, ECHKeys) {
Daniel McArdle00e434d2021-02-18 11:47:18 -05001543 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1544 ASSERT_TRUE(ctx);
1545
David Benjaminc3b373b2021-06-06 13:04:26 -04001546 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1547 ASSERT_TRUE(keys);
Daniel McArdle00e434d2021-02-18 11:47:18 -05001548
David Benjaminc890ae52021-06-06 13:32:29 -04001549 // Adding an ECHConfig with the wrong public key is an error.
1550 bssl::ScopedEVP_HPKE_KEY wrong_key;
1551 ASSERT_TRUE(
1552 EVP_HPKE_KEY_generate(wrong_key.get(), EVP_hpke_x25519_hkdf_sha256()));
David Benjaminc3b373b2021-06-06 13:04:26 -04001553 ASSERT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, kECHConfig,
David Benjaminc890ae52021-06-06 13:32:29 -04001554 sizeof(kECHConfig), wrong_key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001555 uint32_t err = ERR_get_error();
1556 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
1557 EXPECT_EQ(SSL_R_ECH_SERVER_CONFIG_AND_PRIVATE_KEY_MISMATCH,
1558 ERR_GET_REASON(err));
1559 ERR_clear_error();
1560
David Benjaminc890ae52021-06-06 13:32:29 -04001561 // Adding an ECHConfig with the right public key, but wrong KEM ID, is an
1562 // error.
1563 bssl::ScopedEVP_HPKE_KEY key;
1564 ASSERT_TRUE(EVP_HPKE_KEY_init(key.get(), EVP_hpke_x25519_hkdf_sha256(),
1565 kECHPrivateKey, sizeof(kECHPrivateKey)));
1566 std::vector<uint8_t> ech_config;
1567 ASSERT_TRUE(MakeECHConfig(
1568 &ech_config, 0x42, 0x0010 /* DHKEM(P-256, HKDF-SHA256) */, kECHPublicKey,
1569 std::vector<uint16_t>{EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_128_GCM},
1570 /*extensions=*/{}));
1571 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1572 ech_config.data(), ech_config.size(),
1573 key.get()));
1574
1575 // Adding an ECHConfig with the matching public key succeeds.
David Benjaminc3b373b2021-06-06 13:04:26 -04001576 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, kECHConfig,
David Benjaminc890ae52021-06-06 13:32:29 -04001577 sizeof(kECHConfig), key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001578
David Benjaminc3b373b2021-06-06 13:04:26 -04001579 ASSERT_TRUE(SSL_CTX_set1_ech_keys(ctx.get(), keys.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001580
1581 // Build a new config list and replace the old one on |ctx|.
David Benjaminc3b373b2021-06-06 13:04:26 -04001582 bssl::UniquePtr<SSL_ECH_KEYS> next_keys(SSL_ECH_KEYS_new());
1583 ASSERT_TRUE(SSL_ECH_KEYS_add(next_keys.get(), /*is_retry_config=*/1,
David Benjaminc890ae52021-06-06 13:32:29 -04001584 kECHConfig, sizeof(kECHConfig),key.get()));
David Benjaminc3b373b2021-06-06 13:04:26 -04001585 ASSERT_TRUE(SSL_CTX_set1_ech_keys(ctx.get(), next_keys.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001586}
1587
1588TEST(SSLTest, ECHServerConfigListTruncatedPublicKey) {
1589 std::vector<uint8_t> ech_config;
1590 ASSERT_TRUE(MakeECHConfig(
Steven Valdez94a63a52021-04-29 10:52:42 -04001591 &ech_config, 0x42, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
David Benjaminc3b373b2021-06-06 13:04:26 -04001592 MakeConstSpan(kECHPublicKey, sizeof(kECHPublicKey) - 1),
David Benjaminf39c81d2021-05-03 18:39:46 -04001593 std::vector<uint16_t>{EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_128_GCM},
Daniel McArdle00e434d2021-02-18 11:47:18 -05001594 /*extensions=*/{}));
1595
1596 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1597 ASSERT_TRUE(ctx);
1598
David Benjaminc890ae52021-06-06 13:32:29 -04001599 bssl::ScopedEVP_HPKE_KEY key;
1600 ASSERT_TRUE(EVP_HPKE_KEY_init(key.get(), EVP_hpke_x25519_hkdf_sha256(),
1601 kECHPrivateKey, sizeof(kECHPrivateKey)));
David Benjaminc3b373b2021-06-06 13:04:26 -04001602 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1603 ASSERT_TRUE(keys);
1604 ASSERT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1605 ech_config.data(), ech_config.size(),
David Benjaminc890ae52021-06-06 13:32:29 -04001606 key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001607
1608 uint32_t err = ERR_peek_error();
1609 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
David Benjamin1d58cd12021-05-04 15:24:24 -04001610 EXPECT_EQ(SSL_R_ECH_SERVER_CONFIG_AND_PRIVATE_KEY_MISMATCH,
1611 ERR_GET_REASON(err));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001612 ERR_clear_error();
1613}
1614
David Benjaminc3b373b2021-06-06 13:04:26 -04001615// Test that |SSL_CTX_set1_ech_keys| fails when the config list
Daniel McArdle00e434d2021-02-18 11:47:18 -05001616// has no retry configs.
1617TEST(SSLTest, ECHServerConfigsWithoutRetryConfigs) {
1618 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1619 ASSERT_TRUE(ctx);
1620
David Benjaminc3b373b2021-06-06 13:04:26 -04001621 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1622 ASSERT_TRUE(keys);
Daniel McArdle00e434d2021-02-18 11:47:18 -05001623
David Benjaminc890ae52021-06-06 13:32:29 -04001624 bssl::ScopedEVP_HPKE_KEY key;
1625 ASSERT_TRUE(EVP_HPKE_KEY_init(key.get(), EVP_hpke_x25519_hkdf_sha256(),
1626 kECHPrivateKey, sizeof(kECHPrivateKey)));
David Benjaminc3b373b2021-06-06 13:04:26 -04001627 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/0, kECHConfig,
David Benjaminc890ae52021-06-06 13:32:29 -04001628 sizeof(kECHConfig), key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001629
David Benjaminc3b373b2021-06-06 13:04:26 -04001630 ASSERT_FALSE(SSL_CTX_set1_ech_keys(ctx.get(), keys.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001631 uint32_t err = ERR_peek_error();
1632 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
1633 EXPECT_EQ(SSL_R_ECH_SERVER_WOULD_HAVE_NO_RETRY_CONFIGS, ERR_GET_REASON(err));
1634 ERR_clear_error();
1635
1636 // Add the same ECHConfig to the list, but this time mark it as a retry
1637 // config.
David Benjaminc3b373b2021-06-06 13:04:26 -04001638 ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, kECHConfig,
David Benjaminc890ae52021-06-06 13:32:29 -04001639 sizeof(kECHConfig), key.get()));
David Benjaminc3b373b2021-06-06 13:04:26 -04001640 ASSERT_TRUE(SSL_CTX_set1_ech_keys(ctx.get(), keys.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001641}
1642
1643// Test that the server APIs reject ECHConfigs with unsupported features.
1644TEST(SSLTest, UnsupportedECHConfig) {
David Benjaminc3b373b2021-06-06 13:04:26 -04001645 bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1646 ASSERT_TRUE(keys);
David Benjaminc890ae52021-06-06 13:32:29 -04001647 bssl::ScopedEVP_HPKE_KEY key;
1648 ASSERT_TRUE(EVP_HPKE_KEY_init(key.get(), EVP_hpke_x25519_hkdf_sha256(),
1649 kECHPrivateKey, sizeof(kECHPrivateKey)));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001650
1651 // Unsupported versions are rejected.
1652 static const uint8_t kUnsupportedVersion[] = {0xff, 0xff, 0x00, 0x00};
David Benjaminc3b373b2021-06-06 13:04:26 -04001653 EXPECT_FALSE(SSL_ECH_KEYS_add(
1654 keys.get(), /*is_retry_config=*/1, kUnsupportedVersion,
David Benjaminc890ae52021-06-06 13:32:29 -04001655 sizeof(kUnsupportedVersion), key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001656
1657 // Unsupported cipher suites are rejected. (We only support HKDF-SHA256.)
1658 std::vector<uint8_t> ech_config;
1659 ASSERT_TRUE(MakeECHConfig(
David Benjaminc3b373b2021-06-06 13:04:26 -04001660 &ech_config, 0x42, EVP_HPKE_DHKEM_X25519_HKDF_SHA256, kECHPublicKey,
David Benjaminf39c81d2021-05-03 18:39:46 -04001661 std::vector<uint16_t>{0x002 /* HKDF-SHA384 */, EVP_HPKE_AES_128_GCM},
Daniel McArdle00e434d2021-02-18 11:47:18 -05001662 /*extensions=*/{}));
David Benjaminc3b373b2021-06-06 13:04:26 -04001663 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1664 ech_config.data(), ech_config.size(),
David Benjaminc890ae52021-06-06 13:32:29 -04001665 key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001666
1667 // Unsupported extensions are rejected.
1668 static const uint8_t kExtensions[] = {0x00, 0x01, 0x00, 0x00};
1669 ASSERT_TRUE(MakeECHConfig(
David Benjaminc3b373b2021-06-06 13:04:26 -04001670 &ech_config, 0x42, EVP_HPKE_DHKEM_X25519_HKDF_SHA256, kECHPublicKey,
David Benjaminf39c81d2021-05-03 18:39:46 -04001671 std::vector<uint16_t>{EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_128_GCM},
Daniel McArdle00e434d2021-02-18 11:47:18 -05001672 kExtensions));
David Benjaminc3b373b2021-06-06 13:04:26 -04001673 EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
1674 ech_config.data(), ech_config.size(),
David Benjaminc890ae52021-06-06 13:32:29 -04001675 key.get()));
Daniel McArdle00e434d2021-02-18 11:47:18 -05001676}
1677
David Benjaminc79ae7a2017-08-29 16:09:44 -04001678static void AppendSession(SSL_SESSION *session, void *arg) {
1679 std::vector<SSL_SESSION*> *out =
1680 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
1681 out->push_back(session);
1682}
1683
1684// CacheEquals returns true if |ctx|'s session cache consists of |expected|, in
1685// order.
1686static bool CacheEquals(SSL_CTX *ctx,
1687 const std::vector<SSL_SESSION*> &expected) {
1688 // Check the linked list.
1689 SSL_SESSION *ptr = ctx->session_cache_head;
1690 for (SSL_SESSION *session : expected) {
1691 if (ptr != session) {
1692 return false;
1693 }
1694 // TODO(davidben): This is an absurd way to denote the end of the list.
1695 if (ptr->next ==
1696 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
1697 ptr = nullptr;
1698 } else {
1699 ptr = ptr->next;
1700 }
1701 }
1702 if (ptr != nullptr) {
1703 return false;
1704 }
1705
1706 // Check the hash table.
1707 std::vector<SSL_SESSION*> actual, expected_copy;
David Benjamin9eaa3bd2017-09-27 17:03:54 -04001708 lh_SSL_SESSION_doall_arg(ctx->sessions, AppendSession, &actual);
David Benjaminc79ae7a2017-08-29 16:09:44 -04001709 expected_copy = expected;
1710
1711 std::sort(actual.begin(), actual.end());
1712 std::sort(expected_copy.begin(), expected_copy.end());
1713
1714 return actual == expected_copy;
1715}
1716
1717static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
1718 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
1719 if (!ssl_ctx) {
1720 return nullptr;
1721 }
1722 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new(ssl_ctx.get()));
1723 if (!ret) {
1724 return nullptr;
1725 }
1726
David Benjaminaaef8332018-06-29 16:45:49 -04001727 uint8_t id[SSL3_SSL_SESSION_ID_LENGTH] = {0};
1728 OPENSSL_memcpy(id, &number, sizeof(number));
1729 if (!SSL_SESSION_set1_id(ret.get(), id, sizeof(id))) {
1730 return nullptr;
1731 }
David Benjaminc79ae7a2017-08-29 16:09:44 -04001732 return ret;
1733}
1734
1735// Test that the internal session cache behaves as expected.
1736TEST(SSLTest, InternalSessionCache) {
1737 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1738 ASSERT_TRUE(ctx);
1739
1740 // Prepare 10 test sessions.
1741 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
1742 for (int i = 0; i < 10; i++) {
1743 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
1744 ASSERT_TRUE(session);
1745 sessions.push_back(std::move(session));
1746 }
1747
1748 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1749
1750 // Insert all the test sessions.
1751 for (const auto &session : sessions) {
1752 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), session.get()));
1753 }
1754
1755 // Only the last five should be in the list.
1756 ASSERT_TRUE(CacheEquals(
1757 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
1758 sessions[6].get(), sessions[5].get()}));
1759
1760 // Inserting an element already in the cache should fail and leave the cache
1761 // unchanged.
1762 ASSERT_FALSE(SSL_CTX_add_session(ctx.get(), sessions[7].get()));
1763 ASSERT_TRUE(CacheEquals(
1764 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
1765 sessions[6].get(), sessions[5].get()}));
1766
1767 // Although collisions should be impossible (256-bit session IDs), the cache
1768 // must handle them gracefully.
1769 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
1770 ASSERT_TRUE(collision);
1771 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), collision.get()));
1772 ASSERT_TRUE(CacheEquals(
1773 ctx.get(), {collision.get(), sessions[9].get(), sessions[8].get(),
1774 sessions[6].get(), sessions[5].get()}));
1775
1776 // Removing sessions behaves correctly.
1777 ASSERT_TRUE(SSL_CTX_remove_session(ctx.get(), sessions[6].get()));
1778 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
1779 sessions[8].get(), sessions[5].get()}));
1780
1781 // Removing sessions requires an exact match.
1782 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[0].get()));
1783 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[7].get()));
1784
1785 // The cache remains unchanged.
1786 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
1787 sessions[8].get(), sessions[5].get()}));
1788}
1789
1790static uint16_t EpochFromSequence(uint64_t seq) {
1791 return static_cast<uint16_t>(seq >> 48);
1792}
1793
David Benjamin71dfad42017-07-16 17:27:39 -04001794static const uint8_t kTestName[] = {
1795 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
1796 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
1797 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
1798 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
1799 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
1800 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64,
1801};
1802
David Benjaminb79cc842016-12-07 15:57:14 -05001803static bool CompleteHandshakes(SSL *client, SSL *server) {
1804 // Drive both their handshakes to completion.
1805 for (;;) {
1806 int client_ret = SSL_do_handshake(client);
1807 int client_err = SSL_get_error(client, client_ret);
1808 if (client_err != SSL_ERROR_NONE &&
1809 client_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001810 client_err != SSL_ERROR_WANT_WRITE &&
1811 client_err != SSL_ERROR_PENDING_TICKET) {
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08001812 fprintf(stderr, "Client error: %s\n", SSL_error_description(client_err));
David Benjaminb79cc842016-12-07 15:57:14 -05001813 return false;
1814 }
1815
1816 int server_ret = SSL_do_handshake(server);
1817 int server_err = SSL_get_error(server, server_ret);
1818 if (server_err != SSL_ERROR_NONE &&
1819 server_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001820 server_err != SSL_ERROR_WANT_WRITE &&
1821 server_err != SSL_ERROR_PENDING_TICKET) {
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08001822 fprintf(stderr, "Server error: %s\n", SSL_error_description(server_err));
David Benjaminb79cc842016-12-07 15:57:14 -05001823 return false;
1824 }
1825
1826 if (client_ret == 1 && server_ret == 1) {
1827 break;
1828 }
1829 }
1830
1831 return true;
1832}
1833
Steven Valdez777a2392019-02-21 11:30:47 -05001834static bool FlushNewSessionTickets(SSL *client, SSL *server) {
1835 // NewSessionTickets are deferred on the server to |SSL_write|, and clients do
1836 // not pick them up until |SSL_read|.
1837 for (;;) {
1838 int server_ret = SSL_write(server, nullptr, 0);
1839 int server_err = SSL_get_error(server, server_ret);
1840 // The server may either succeed (|server_ret| is zero) or block on write
1841 // (|server_ret| is -1 and |server_err| is |SSL_ERROR_WANT_WRITE|).
1842 if (server_ret > 0 ||
1843 (server_ret < 0 && server_err != SSL_ERROR_WANT_WRITE)) {
1844 fprintf(stderr, "Unexpected server result: %d %d\n", server_ret,
1845 server_err);
1846 return false;
1847 }
1848
1849 int client_ret = SSL_read(client, nullptr, 0);
1850 int client_err = SSL_get_error(client, client_ret);
1851 // The client must always block on read.
1852 if (client_ret != -1 || client_err != SSL_ERROR_WANT_READ) {
1853 fprintf(stderr, "Unexpected client result: %d %d\n", client_ret,
1854 client_err);
1855 return false;
1856 }
1857
1858 // The server flushed everything it had to write.
1859 if (server_ret == 0) {
1860 return true;
1861 }
1862 }
1863}
1864
David Benjamin9b2cdb72021-04-01 23:21:53 -04001865// CreateClientAndServer creates a client and server |SSL| objects whose |BIO|s
1866// are paired with each other. It does not run the handshake. The caller is
1867// expected to configure the objects and drive the handshake as needed.
1868static bool CreateClientAndServer(bssl::UniquePtr<SSL> *out_client,
1869 bssl::UniquePtr<SSL> *out_server,
1870 SSL_CTX *client_ctx, SSL_CTX *server_ctx) {
1871 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
1872 if (!client || !server) {
1873 return false;
1874 }
1875 SSL_set_connect_state(client.get());
1876 SSL_set_accept_state(server.get());
1877
1878 BIO *bio1, *bio2;
1879 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1880 return false;
1881 }
1882 // SSL_set_bio takes ownership.
1883 SSL_set_bio(client.get(), bio1, bio1);
1884 SSL_set_bio(server.get(), bio2, bio2);
1885
1886 *out_client = std::move(client);
1887 *out_server = std::move(server);
1888 return true;
1889}
1890
David Benjamina8614602017-09-06 15:40:19 -04001891struct ClientConfig {
1892 SSL_SESSION *session = nullptr;
1893 std::string servername;
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08001894 bool early_data = false;
David Benjamina8614602017-09-06 15:40:19 -04001895};
1896
David Benjaminb79cc842016-12-07 15:57:14 -05001897static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client,
1898 bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001899 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
Adam Langleyddb57cf2018-01-26 09:17:53 -08001900 const ClientConfig &config = ClientConfig(),
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001901 bool shed_handshake_config = true) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04001902 bssl::UniquePtr<SSL> client, server;
1903 if (!CreateClientAndServer(&client, &server, client_ctx, server_ctx)) {
David Benjaminde942382016-02-11 12:02:01 -05001904 return false;
1905 }
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08001906 if (config.early_data) {
1907 SSL_set_early_data_enabled(client.get(), 1);
1908 }
David Benjamina8614602017-09-06 15:40:19 -04001909 if (config.session) {
1910 SSL_set_session(client.get(), config.session);
1911 }
1912 if (!config.servername.empty() &&
1913 !SSL_set_tlsext_host_name(client.get(), config.servername.c_str())) {
1914 return false;
1915 }
David Benjamina20e5352016-08-02 19:09:41 -04001916
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001917 SSL_set_shed_handshake_config(client.get(), shed_handshake_config);
1918 SSL_set_shed_handshake_config(server.get(), shed_handshake_config);
1919
David Benjamin9b2cdb72021-04-01 23:21:53 -04001920 if (!CompleteHandshakes(client.get(), server.get())) {
David Benjaminb79cc842016-12-07 15:57:14 -05001921 return false;
David Benjaminde942382016-02-11 12:02:01 -05001922 }
1923
David Benjamin686bb192016-05-10 15:15:41 -04001924 *out_client = std::move(client);
1925 *out_server = std::move(server);
1926 return true;
1927}
1928
David Benjaminc11ea9422017-08-29 16:33:21 -04001929// SSLVersionTest executes its test cases under all available protocol versions.
1930// Test cases call |Connect| to create a connection using context objects with
1931// the protocol version fixed to the current version under test.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001932class SSLVersionTest : public ::testing::TestWithParam<VersionParam> {
1933 protected:
1934 SSLVersionTest() : cert_(GetTestCertificate()), key_(GetTestKey()) {}
1935
1936 void SetUp() { ResetContexts(); }
1937
1938 bssl::UniquePtr<SSL_CTX> CreateContext() const {
1939 const SSL_METHOD *method = is_dtls() ? DTLS_method() : TLS_method();
1940 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
1941 if (!ctx || !SSL_CTX_set_min_proto_version(ctx.get(), version()) ||
1942 !SSL_CTX_set_max_proto_version(ctx.get(), version())) {
1943 return nullptr;
1944 }
1945 return ctx;
David Benjamin0fef3052016-11-18 15:11:10 +09001946 }
David Benjamin686bb192016-05-10 15:15:41 -04001947
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001948 void ResetContexts() {
1949 ASSERT_TRUE(cert_);
1950 ASSERT_TRUE(key_);
1951 client_ctx_ = CreateContext();
1952 ASSERT_TRUE(client_ctx_);
1953 server_ctx_ = CreateContext();
1954 ASSERT_TRUE(server_ctx_);
1955 // Set up a server cert. Client certs can be set up explicitly.
1956 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09001957 }
David Benjamin686bb192016-05-10 15:15:41 -04001958
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001959 bool UseCertAndKey(SSL_CTX *ctx) const {
1960 return SSL_CTX_use_certificate(ctx, cert_.get()) &&
1961 SSL_CTX_use_PrivateKey(ctx, key_.get());
David Benjamin0fef3052016-11-18 15:11:10 +09001962 }
David Benjamin686bb192016-05-10 15:15:41 -04001963
David Benjamina8614602017-09-06 15:40:19 -04001964 bool Connect(const ClientConfig &config = ClientConfig()) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001965 return ConnectClientAndServer(&client_, &server_, client_ctx_.get(),
David Benjamin9b2cdb72021-04-01 23:21:53 -04001966 server_ctx_.get(), config,
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001967 shed_handshake_config_);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001968 }
1969
1970 uint16_t version() const { return GetParam().version; }
1971
1972 bool is_dtls() const {
1973 return GetParam().ssl_method == VersionParam::is_dtls;
1974 }
1975
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001976 bool shed_handshake_config_ = true;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001977 bssl::UniquePtr<SSL> client_, server_;
1978 bssl::UniquePtr<SSL_CTX> server_ctx_, client_ctx_;
1979 bssl::UniquePtr<X509> cert_;
1980 bssl::UniquePtr<EVP_PKEY> key_;
1981};
1982
David Benjaminbe7006a2019-04-09 18:05:02 -05001983INSTANTIATE_TEST_SUITE_P(WithVersion, SSLVersionTest,
1984 testing::ValuesIn(kAllVersions),
1985 [](const testing::TestParamInfo<VersionParam> &i) {
1986 return i.param.name;
1987 });
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001988
1989TEST_P(SSLVersionTest, SequenceNumber) {
1990 ASSERT_TRUE(Connect());
1991
David Benjamin0fef3052016-11-18 15:11:10 +09001992 // Drain any post-handshake messages to ensure there are no unread records
1993 // on either end.
Steven Valdez777a2392019-02-21 11:30:47 -05001994 ASSERT_TRUE(FlushNewSessionTickets(client_.get(), server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05001995
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001996 uint64_t client_read_seq = SSL_get_read_sequence(client_.get());
1997 uint64_t client_write_seq = SSL_get_write_sequence(client_.get());
1998 uint64_t server_read_seq = SSL_get_read_sequence(server_.get());
1999 uint64_t server_write_seq = SSL_get_write_sequence(server_.get());
Steven Valdez2c62fe92016-10-14 12:08:12 -04002000
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002001 if (is_dtls()) {
David Benjamin0fef3052016-11-18 15:11:10 +09002002 // Both client and server must be at epoch 1.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002003 EXPECT_EQ(EpochFromSequence(client_read_seq), 1);
2004 EXPECT_EQ(EpochFromSequence(client_write_seq), 1);
2005 EXPECT_EQ(EpochFromSequence(server_read_seq), 1);
2006 EXPECT_EQ(EpochFromSequence(server_write_seq), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09002007
2008 // The next record to be written should exceed the largest received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002009 EXPECT_GT(client_write_seq, server_read_seq);
2010 EXPECT_GT(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09002011 } else {
2012 // The next record to be written should equal the next to be received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002013 EXPECT_EQ(client_write_seq, server_read_seq);
2014 EXPECT_EQ(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09002015 }
2016
2017 // Send a record from client to server.
Steven Valdez777a2392019-02-21 11:30:47 -05002018 uint8_t byte = 0;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002019 EXPECT_EQ(SSL_write(client_.get(), &byte, 1), 1);
2020 EXPECT_EQ(SSL_read(server_.get(), &byte, 1), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09002021
2022 // The client write and server read sequence numbers should have
2023 // incremented.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002024 EXPECT_EQ(client_write_seq + 1, SSL_get_write_sequence(client_.get()));
2025 EXPECT_EQ(server_read_seq + 1, SSL_get_read_sequence(server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05002026}
2027
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002028TEST_P(SSLVersionTest, OneSidedShutdown) {
David Benjamin68f37b72016-11-18 15:14:42 +09002029 // SSL_shutdown is a no-op in DTLS.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002030 if (is_dtls()) {
2031 return;
David Benjamin686bb192016-05-10 15:15:41 -04002032 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002033 ASSERT_TRUE(Connect());
David Benjamin686bb192016-05-10 15:15:41 -04002034
2035 // Shut down half the connection. SSL_shutdown will return 0 to signal only
2036 // one side has shut down.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002037 ASSERT_EQ(SSL_shutdown(client_.get()), 0);
David Benjamin686bb192016-05-10 15:15:41 -04002038
2039 // Reading from the server should consume the EOF.
2040 uint8_t byte;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002041 ASSERT_EQ(SSL_read(server_.get(), &byte, 1), 0);
2042 ASSERT_EQ(SSL_get_error(server_.get(), 0), SSL_ERROR_ZERO_RETURN);
David Benjamin686bb192016-05-10 15:15:41 -04002043
2044 // However, the server may continue to write data and then shut down the
2045 // connection.
2046 byte = 42;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002047 ASSERT_EQ(SSL_write(server_.get(), &byte, 1), 1);
2048 ASSERT_EQ(SSL_read(client_.get(), &byte, 1), 1);
2049 ASSERT_EQ(byte, 42);
David Benjamin686bb192016-05-10 15:15:41 -04002050
2051 // The server may then shutdown the connection.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002052 EXPECT_EQ(SSL_shutdown(server_.get()), 1);
2053 EXPECT_EQ(SSL_shutdown(client_.get()), 1);
David Benjamin686bb192016-05-10 15:15:41 -04002054}
David Benjamin68f37b72016-11-18 15:14:42 +09002055
David Benjaminf0d8e222017-02-04 10:58:26 -05002056TEST(SSLTest, SessionDuplication) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002057 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04002058 bssl::UniquePtr<SSL_CTX> server_ctx =
2059 CreateContextWithTestCertificate(TLS_method());
David Benjaminf0d8e222017-02-04 10:58:26 -05002060 ASSERT_TRUE(client_ctx);
2061 ASSERT_TRUE(server_ctx);
Steven Valdez87eab492016-06-27 16:34:59 -04002062
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002063 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05002064 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04002065 server_ctx.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04002066
2067 SSL_SESSION *session0 = SSL_get_session(client.get());
David Benjamin31b0c9b2017-07-20 14:49:15 -04002068 bssl::UniquePtr<SSL_SESSION> session1 =
2069 bssl::SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL);
David Benjaminf0d8e222017-02-04 10:58:26 -05002070 ASSERT_TRUE(session1);
David Benjamin4501bd52016-08-01 13:39:41 -04002071
David Benjamina3a71e92018-06-29 13:24:45 -04002072 session1->not_resumable = false;
Steven Valdez84b5c002016-08-25 16:30:58 -04002073
Steven Valdez87eab492016-06-27 16:34:59 -04002074 uint8_t *s0_bytes, *s1_bytes;
2075 size_t s0_len, s1_len;
2076
David Benjaminf0d8e222017-02-04 10:58:26 -05002077 ASSERT_TRUE(SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002078 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04002079
David Benjaminf0d8e222017-02-04 10:58:26 -05002080 ASSERT_TRUE(SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002081 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04002082
David Benjamin7d7554b2017-02-04 11:48:59 -05002083 EXPECT_EQ(Bytes(s0_bytes, s0_len), Bytes(s1_bytes, s1_len));
Steven Valdez87eab492016-06-27 16:34:59 -04002084}
David Benjamin686bb192016-05-10 15:15:41 -04002085
David Benjaminf0d8e222017-02-04 10:58:26 -05002086static void ExpectFDs(const SSL *ssl, int rfd, int wfd) {
David Benjaminca743582017-06-15 17:51:35 -04002087 EXPECT_EQ(rfd, SSL_get_fd(ssl));
David Benjaminf0d8e222017-02-04 10:58:26 -05002088 EXPECT_EQ(rfd, SSL_get_rfd(ssl));
2089 EXPECT_EQ(wfd, SSL_get_wfd(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04002090
2091 // The wrapper BIOs are always equal when fds are equal, even if set
2092 // individually.
David Benjaminf0d8e222017-02-04 10:58:26 -05002093 if (rfd == wfd) {
2094 EXPECT_EQ(SSL_get_rbio(ssl), SSL_get_wbio(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04002095 }
David Benjamin5c0fb882016-06-14 14:03:51 -04002096}
2097
David Benjaminf0d8e222017-02-04 10:58:26 -05002098TEST(SSLTest, SetFD) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002099 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002100 ASSERT_TRUE(ctx);
David Benjamin5c0fb882016-06-14 14:03:51 -04002101
2102 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002103 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002104 ASSERT_TRUE(ssl);
2105 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2106 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
2107 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04002108
2109 // Test setting the same FD.
2110 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002111 ASSERT_TRUE(ssl);
2112 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2113 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002114
2115 // Test setting the same FD one side at a time.
2116 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002117 ASSERT_TRUE(ssl);
2118 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2119 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
2120 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002121
2122 // Test setting the same FD in the other order.
2123 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002124 ASSERT_TRUE(ssl);
2125 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
2126 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2127 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002128
David Benjamin5c0fb882016-06-14 14:03:51 -04002129 // Test changing the read FD partway through.
2130 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002131 ASSERT_TRUE(ssl);
2132 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2133 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 2));
2134 ExpectFDs(ssl.get(), 2, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002135
2136 // Test changing the write FD partway through.
2137 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002138 ASSERT_TRUE(ssl);
2139 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2140 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
2141 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04002142
2143 // Test a no-op change to the read FD partway through.
2144 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002145 ASSERT_TRUE(ssl);
2146 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2147 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
2148 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002149
2150 // Test a no-op change to the write FD partway through.
2151 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002152 ASSERT_TRUE(ssl);
2153 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
2154 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
2155 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04002156
2157 // ASan builds will implicitly test that the internal |BIO| reference-counting
2158 // is correct.
David Benjamin5c0fb882016-06-14 14:03:51 -04002159}
2160
David Benjaminf0d8e222017-02-04 10:58:26 -05002161TEST(SSLTest, SetBIO) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002162 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002163 ASSERT_TRUE(ctx);
David Benjamin4501bd52016-08-01 13:39:41 -04002164
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002165 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
2166 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04002167 bio3(BIO_new(BIO_s_mem()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002168 ASSERT_TRUE(ssl);
2169 ASSERT_TRUE(bio1);
2170 ASSERT_TRUE(bio2);
2171 ASSERT_TRUE(bio3);
David Benjamin4501bd52016-08-01 13:39:41 -04002172
2173 // SSL_set_bio takes one reference when the parameters are the same.
2174 BIO_up_ref(bio1.get());
2175 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
2176
2177 // Repeating the call does nothing.
2178 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
2179
2180 // It takes one reference each when the parameters are different.
2181 BIO_up_ref(bio2.get());
2182 BIO_up_ref(bio3.get());
2183 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
2184
2185 // Repeating the call does nothing.
2186 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
2187
2188 // It takes one reference when changing only wbio.
2189 BIO_up_ref(bio1.get());
2190 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
2191
2192 // It takes one reference when changing only rbio and the two are different.
2193 BIO_up_ref(bio3.get());
2194 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
2195
2196 // If setting wbio to rbio, it takes no additional references.
2197 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
2198
2199 // From there, wbio may be switched to something else.
2200 BIO_up_ref(bio1.get());
2201 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
2202
2203 // If setting rbio to wbio, it takes no additional references.
2204 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
2205
2206 // From there, rbio may be switched to something else, but, for historical
2207 // reasons, it takes a reference to both parameters.
2208 BIO_up_ref(bio1.get());
2209 BIO_up_ref(bio2.get());
2210 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
2211
2212 // ASAN builds will implicitly test that the internal |BIO| reference-counting
2213 // is correct.
David Benjamin4501bd52016-08-01 13:39:41 -04002214}
2215
David Benjamin25490f22016-07-14 00:22:54 -04002216static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
2217
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002218TEST_P(SSLVersionTest, GetPeerCertificate) {
2219 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04002220
David Benjamin0fef3052016-11-18 15:11:10 +09002221 // Configure both client and server to accept any certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002222 SSL_CTX_set_verify(client_ctx_.get(),
2223 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2224 nullptr);
2225 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
2226 SSL_CTX_set_verify(server_ctx_.get(),
2227 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2228 nullptr);
2229 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjaminadd5e522016-07-14 00:33:24 -04002230
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002231 ASSERT_TRUE(Connect());
David Benjaminadd5e522016-07-14 00:33:24 -04002232
David Benjamin0fef3052016-11-18 15:11:10 +09002233 // Client and server should both see the leaf certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002234 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
2235 ASSERT_TRUE(peer);
2236 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04002237
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002238 peer.reset(SSL_get_peer_certificate(client_.get()));
2239 ASSERT_TRUE(peer);
2240 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04002241
David Benjamine664a532017-07-20 20:19:36 -04002242 // However, for historical reasons, the X509 chain includes the leaf on the
David Benjamin0fef3052016-11-18 15:11:10 +09002243 // client, but does not on the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002244 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(client_.get())), 1u);
2245 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(client_.get())),
2246 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04002247
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002248 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(server_.get())), 0u);
2249 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(server_.get())),
2250 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04002251}
2252
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002253TEST_P(SSLVersionTest, NoPeerCertificate) {
2254 SSL_CTX_set_verify(server_ctx_.get(), SSL_VERIFY_PEER, nullptr);
2255 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
2256 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
David Benjamine664a532017-07-20 20:19:36 -04002257
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002258 ASSERT_TRUE(Connect());
David Benjamine664a532017-07-20 20:19:36 -04002259
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002260 // Server should not see a peer certificate.
2261 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
2262 ASSERT_FALSE(peer);
2263 ASSERT_FALSE(SSL_get0_peer_certificates(server_.get()));
David Benjamine664a532017-07-20 20:19:36 -04002264}
2265
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002266TEST_P(SSLVersionTest, RetainOnlySHA256OfCerts) {
David Benjamin25490f22016-07-14 00:22:54 -04002267 uint8_t *cert_der = NULL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002268 int cert_der_len = i2d_X509(cert_.get(), &cert_der);
2269 ASSERT_GE(cert_der_len, 0);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002270 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04002271
2272 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
2273 SHA256(cert_der, cert_der_len, cert_sha256);
2274
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002275 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2276
David Benjamin0fef3052016-11-18 15:11:10 +09002277 // Configure both client and server to accept any certificate, but the
2278 // server must retain only the SHA-256 of the peer.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002279 SSL_CTX_set_verify(client_ctx_.get(),
2280 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2281 nullptr);
2282 SSL_CTX_set_verify(server_ctx_.get(),
2283 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2284 nullptr);
2285 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
2286 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
2287 SSL_CTX_set_retain_only_sha256_of_client_certs(server_ctx_.get(), 1);
David Benjamin25490f22016-07-14 00:22:54 -04002288
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002289 ASSERT_TRUE(Connect());
David Benjamin25490f22016-07-14 00:22:54 -04002290
David Benjamin0fef3052016-11-18 15:11:10 +09002291 // The peer certificate has been dropped.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002292 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
2293 EXPECT_FALSE(peer);
David Benjamin25490f22016-07-14 00:22:54 -04002294
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002295 SSL_SESSION *session = SSL_get_session(server_.get());
David Benjamin02de7bd2018-05-08 18:13:54 -04002296 EXPECT_TRUE(SSL_SESSION_has_peer_sha256(session));
David Benjamin25490f22016-07-14 00:22:54 -04002297
David Benjamin02de7bd2018-05-08 18:13:54 -04002298 const uint8_t *peer_sha256;
2299 size_t peer_sha256_len;
2300 SSL_SESSION_get0_peer_sha256(session, &peer_sha256, &peer_sha256_len);
2301 EXPECT_EQ(Bytes(cert_sha256), Bytes(peer_sha256, peer_sha256_len));
David Benjamin25490f22016-07-14 00:22:54 -04002302}
2303
David Benjamin737d2df2017-09-25 15:05:19 -04002304// Tests that our ClientHellos do not change unexpectedly. These are purely
2305// change detection tests. If they fail as part of an intentional ClientHello
2306// change, update the test vector.
2307TEST(SSLTest, ClientHello) {
2308 struct {
2309 uint16_t max_version;
2310 std::vector<uint8_t> expected;
2311 } kTests[] = {
David Benjamin737d2df2017-09-25 15:05:19 -04002312 {TLS1_VERSION,
2313 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x01, 0x00,
2314 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2315 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2316 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
2317 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
Adam Langleyd6680952018-08-23 08:01:23 -07002318 0x01, 0x00, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01,
2319 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
2320 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
David Benjamin737d2df2017-09-25 15:05:19 -04002321 {TLS1_1_VERSION,
2322 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x02, 0x00,
2323 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2324 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2325 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
2326 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
Adam Langleyd6680952018-08-23 08:01:23 -07002327 0x01, 0x00, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01,
2328 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
2329 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
David Benjamin737d2df2017-09-25 15:05:19 -04002330 {TLS1_2_VERSION,
David Benjamin6e678ee2018-04-16 19:54:42 -04002331 {0x16, 0x03, 0x01, 0x00, 0x82, 0x01, 0x00, 0x00, 0x7e, 0x03, 0x03, 0x00,
David Benjamin737d2df2017-09-25 15:05:19 -04002332 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2333 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
David Benjamin6e678ee2018-04-16 19:54:42 -04002334 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xcc, 0xa9,
David Benjamin737d2df2017-09-25 15:05:19 -04002335 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xc0, 0x09,
David Benjamin6e678ee2018-04-16 19:54:42 -04002336 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
Adam Langleyd6680952018-08-23 08:01:23 -07002337 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37, 0x00, 0x17, 0x00, 0x00,
2338 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00,
2339 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
2340 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04, 0x03, 0x08,
2341 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06,
2342 0x01, 0x02, 0x01}},
David Benjamin737d2df2017-09-25 15:05:19 -04002343 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
2344 // implementation has settled enough that it won't change.
David Benjaminafc64de2016-07-19 17:12:41 +02002345 };
David Benjamin737d2df2017-09-25 15:05:19 -04002346
2347 for (const auto &t : kTests) {
2348 SCOPED_TRACE(t.max_version);
2349
2350 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2351 ASSERT_TRUE(ctx);
2352 // Our default cipher list varies by CPU capabilities, so manually place the
2353 // ChaCha20 ciphers in front.
2354 const char *cipher_list = "CHACHA20:ALL";
David Benjamin737d2df2017-09-25 15:05:19 -04002355 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), t.max_version));
2356 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list));
2357
2358 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
2359 ASSERT_TRUE(ssl);
2360 std::vector<uint8_t> client_hello;
2361 ASSERT_TRUE(GetClientHello(ssl.get(), &client_hello));
2362
2363 // Zero the client_random.
2364 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
2365 1 + 3 + // handshake message header
2366 2; // client_version
2367 ASSERT_GE(client_hello.size(), kRandomOffset + SSL3_RANDOM_SIZE);
2368 OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
2369
2370 if (client_hello != t.expected) {
2371 ADD_FAILURE() << "ClientHellos did not match.";
2372 // Print the value manually so it is easier to update the test vector.
2373 for (size_t i = 0; i < client_hello.size(); i += 12) {
2374 printf(" %c", i == 0 ? '{' : ' ');
2375 for (size_t j = i; j < client_hello.size() && j < i + 12; j++) {
2376 if (j > i) {
2377 printf(" ");
2378 }
2379 printf("0x%02x", client_hello[j]);
2380 if (j < client_hello.size() - 1) {
2381 printf(",");
2382 }
2383 }
2384 if (i + 12 >= client_hello.size()) {
Adam Langleyd6680952018-08-23 08:01:23 -07002385 printf("}},");
David Benjamin737d2df2017-09-25 15:05:19 -04002386 }
2387 printf("\n");
2388 }
2389 }
David Benjaminafc64de2016-07-19 17:12:41 +02002390 }
David Benjaminafc64de2016-07-19 17:12:41 +02002391}
2392
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002393static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04002394
2395static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
2396 // Save the most recent session.
2397 g_last_session.reset(session);
2398 return 1;
2399}
2400
David Benjamina8614602017-09-06 15:40:19 -04002401static bssl::UniquePtr<SSL_SESSION> CreateClientSession(
2402 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2403 const ClientConfig &config = ClientConfig()) {
David Benjamina20e5352016-08-02 19:09:41 -04002404 g_last_session = nullptr;
2405 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2406
2407 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002408 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04002409 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
Steven Valdez777a2392019-02-21 11:30:47 -05002410 config) ||
2411 !FlushNewSessionTickets(client.get(), server.get())) {
David Benjamina20e5352016-08-02 19:09:41 -04002412 fprintf(stderr, "Failed to connect client and server.\n");
2413 return nullptr;
2414 }
2415
David Benjamina20e5352016-08-02 19:09:41 -04002416 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2417
2418 if (!g_last_session) {
2419 fprintf(stderr, "Client did not receive a session.\n");
2420 return nullptr;
2421 }
2422 return std::move(g_last_session);
2423}
2424
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002425static void ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2426 SSL_SESSION *session, bool want_reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002427 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002428 ClientConfig config;
2429 config.session = session;
2430 EXPECT_TRUE(
2431 ConnectClientAndServer(&client, &server, client_ctx, server_ctx, config));
David Benjamina20e5352016-08-02 19:09:41 -04002432
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002433 EXPECT_EQ(SSL_session_reused(client.get()), SSL_session_reused(server.get()));
David Benjamina20e5352016-08-02 19:09:41 -04002434
2435 bool was_reused = !!SSL_session_reused(client.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002436 EXPECT_EQ(was_reused, want_reused);
David Benjamina20e5352016-08-02 19:09:41 -04002437}
2438
David Benjamin3c51d9b2016-11-01 17:50:42 -04002439static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
2440 SSL_CTX *server_ctx,
2441 SSL_SESSION *session) {
2442 g_last_session = nullptr;
2443 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2444
2445 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002446 ClientConfig config;
2447 config.session = session;
2448 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
Steven Valdez777a2392019-02-21 11:30:47 -05002449 config) ||
2450 !FlushNewSessionTickets(client.get(), server.get())) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002451 fprintf(stderr, "Failed to connect client and server.\n");
2452 return nullptr;
2453 }
2454
2455 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2456 fprintf(stderr, "Client and server were inconsistent.\n");
2457 return nullptr;
2458 }
2459
2460 if (!SSL_session_reused(client.get())) {
2461 fprintf(stderr, "Session was not reused.\n");
2462 return nullptr;
2463 }
2464
David Benjamin3c51d9b2016-11-01 17:50:42 -04002465 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2466
2467 if (!g_last_session) {
2468 fprintf(stderr, "Client did not receive a renewed session.\n");
2469 return nullptr;
2470 }
2471 return std::move(g_last_session);
2472}
2473
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002474static void ExpectTicketKeyChanged(SSL_CTX *ctx, uint8_t *inout_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002475 bool changed) {
2476 uint8_t new_key[kTicketKeyLen];
David Benjaminc11ea9422017-08-29 16:33:21 -04002477 // May return 0, 1 or 48.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002478 ASSERT_EQ(SSL_CTX_get_tlsext_ticket_keys(ctx, new_key, kTicketKeyLen), 1);
2479 if (changed) {
2480 ASSERT_NE(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
2481 } else {
2482 ASSERT_EQ(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002483 }
2484 OPENSSL_memcpy(inout_key, new_key, kTicketKeyLen);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002485}
2486
David Benjamina933c382016-10-28 00:10:03 -04002487static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
2488 static const uint8_t kContext[] = {3};
2489
2490 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
2491 return SSL_TLSEXT_ERR_ALERT_FATAL;
2492 }
2493
2494 return SSL_TLSEXT_ERR_OK;
2495}
2496
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002497TEST_P(SSLVersionTest, SessionIDContext) {
David Benjamina20e5352016-08-02 19:09:41 -04002498 static const uint8_t kContext1[] = {1};
2499 static const uint8_t kContext2[] = {2};
2500
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002501 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2502 sizeof(kContext1)));
David Benjamina20e5352016-08-02 19:09:41 -04002503
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002504 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2505 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002506
David Benjamin0fef3052016-11-18 15:11:10 +09002507 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002508 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2509 ASSERT_TRUE(session);
David Benjamina20e5352016-08-02 19:09:41 -04002510
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002511 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2512 session.get(),
2513 true /* expect session reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002514
David Benjamin0fef3052016-11-18 15:11:10 +09002515 // Change the session ID context.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002516 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext2,
2517 sizeof(kContext2)));
David Benjamina20e5352016-08-02 19:09:41 -04002518
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002519 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2520 session.get(),
2521 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002522
David Benjamin0fef3052016-11-18 15:11:10 +09002523 // Change the session ID context back and install an SNI callback to switch
2524 // it.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002525 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2526 sizeof(kContext1)));
David Benjamina933c382016-10-28 00:10:03 -04002527
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002528 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09002529 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04002530
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002531 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2532 session.get(),
2533 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002534
David Benjamin0fef3052016-11-18 15:11:10 +09002535 // Switch the session ID context with the early callback instead.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002536 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), nullptr);
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002537 SSL_CTX_set_select_certificate_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002538 server_ctx_.get(),
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002539 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
2540 static const uint8_t kContext[] = {3};
2541
2542 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
2543 sizeof(kContext))) {
2544 return ssl_select_cert_error;
2545 }
2546
2547 return ssl_select_cert_success;
2548 });
David Benjamina933c382016-10-28 00:10:03 -04002549
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002550 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2551 session.get(),
2552 false /* expect session not reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002553}
2554
David Benjamin721e8b72016-08-03 13:13:17 -04002555static timeval g_current_time;
2556
2557static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2558 *out_clock = g_current_time;
2559}
2560
David Benjamin17b30832017-01-28 14:00:32 -05002561static void FrozenTimeCallback(const SSL *ssl, timeval *out_clock) {
2562 out_clock->tv_sec = 1000;
2563 out_clock->tv_usec = 0;
2564}
2565
David Benjamin3c51d9b2016-11-01 17:50:42 -04002566static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
2567 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
2568 int encrypt) {
2569 static const uint8_t kZeros[16] = {0};
2570
2571 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -05002572 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamin3c51d9b2016-11-01 17:50:42 -04002573 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -05002574 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002575 return 0;
2576 }
2577
2578 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
2579 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
2580 return -1;
2581 }
2582
2583 // Returning two from the callback in decrypt mode renews the
2584 // session in TLS 1.2 and below.
2585 return encrypt ? 1 : 2;
2586}
2587
David Benjamin123db572016-11-03 16:59:25 -04002588static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjaminaaef8332018-06-29 16:45:49 -04002589 const uint8_t *ticket;
2590 size_t ticket_len;
2591 SSL_SESSION_get0_ticket(session, &ticket, &ticket_len);
2592 if (ticket_len < 16 + 16 + SHA256_DIGEST_LENGTH) {
David Benjamin123db572016-11-03 16:59:25 -04002593 return false;
2594 }
2595
David Benjaminaaef8332018-06-29 16:45:49 -04002596 const uint8_t *ciphertext = ticket + 16 + 16;
2597 size_t len = ticket_len - 16 - 16 - SHA256_DIGEST_LENGTH;
David Benjamin123db572016-11-03 16:59:25 -04002598 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
2599
David Benjamin9b63f292016-11-15 00:44:05 -05002600#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
2601 // Fuzzer-mode tickets are unencrypted.
David Benjamin17cf2cb2016-12-13 01:07:13 -05002602 OPENSSL_memcpy(plaintext.get(), ciphertext, len);
David Benjamin9b63f292016-11-15 00:44:05 -05002603#else
2604 static const uint8_t kZeros[16] = {0};
David Benjaminaaef8332018-06-29 16:45:49 -04002605 const uint8_t *iv = ticket + 16;
David Benjamin123db572016-11-03 16:59:25 -04002606 bssl::ScopedEVP_CIPHER_CTX ctx;
2607 int len1, len2;
2608 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
2609 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
2610 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
2611 return false;
2612 }
2613
2614 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05002615#endif
David Benjamin123db572016-11-03 16:59:25 -04002616
Adam Langley46db7af2017-02-01 15:49:37 -08002617 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
2618 if (!ssl_ctx) {
2619 return false;
2620 }
David Benjamin123db572016-11-03 16:59:25 -04002621 bssl::UniquePtr<SSL_SESSION> server_session(
Adam Langley46db7af2017-02-01 15:49:37 -08002622 SSL_SESSION_from_bytes(plaintext.get(), len, ssl_ctx.get()));
David Benjamin123db572016-11-03 16:59:25 -04002623 if (!server_session) {
2624 return false;
2625 }
2626
David Benjaminaaef8332018-06-29 16:45:49 -04002627 *out = SSL_SESSION_get_time(server_session.get());
David Benjamin123db572016-11-03 16:59:25 -04002628 return true;
2629}
2630
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002631TEST_P(SSLVersionTest, SessionTimeout) {
2632 for (bool server_test : {false, true}) {
2633 SCOPED_TRACE(server_test);
David Benjamin721e8b72016-08-03 13:13:17 -04002634
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002635 ResetContexts();
2636 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2637 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
2638
David Benjamin17b30832017-01-28 14:00:32 -05002639 static const time_t kStartTime = 1000;
David Benjamin0fef3052016-11-18 15:11:10 +09002640 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002641
David Benjamin17b30832017-01-28 14:00:32 -05002642 // We are willing to use a longer lifetime for TLS 1.3 sessions as
2643 // resumptions still perform ECDHE.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002644 const time_t timeout = version() == TLS1_3_VERSION
David Benjamin17b30832017-01-28 14:00:32 -05002645 ? SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT
2646 : SSL_DEFAULT_SESSION_TIMEOUT;
2647
David Benjamin17b30832017-01-28 14:00:32 -05002648 // Both client and server must enforce session timeouts. We configure the
2649 // other side with a frozen clock so it never expires tickets.
David Benjamin0fef3052016-11-18 15:11:10 +09002650 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002651 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2652 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002653 } else {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002654 SSL_CTX_set_current_time_cb(client_ctx_.get(), CurrentTimeCallback);
2655 SSL_CTX_set_current_time_cb(server_ctx_.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002656 }
2657
2658 // Configure a ticket callback which renews tickets.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002659 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002660
2661 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002662 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2663 ASSERT_TRUE(session);
David Benjamin0fef3052016-11-18 15:11:10 +09002664
2665 // Advance the clock just behind the timeout.
David Benjamin17b30832017-01-28 14:00:32 -05002666 g_current_time.tv_sec += timeout - 1;
David Benjamin0fef3052016-11-18 15:11:10 +09002667
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002668 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2669 session.get(),
2670 true /* expect session reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002671
2672 // Advance the clock one more second.
2673 g_current_time.tv_sec++;
2674
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002675 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2676 session.get(),
2677 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002678
2679 // Rewind the clock to before the session was minted.
2680 g_current_time.tv_sec = kStartTime - 1;
2681
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002682 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2683 session.get(),
2684 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002685
David Benjamin0fef3052016-11-18 15:11:10 +09002686 // Renew the session 10 seconds before expiration.
David Benjamin17b30832017-01-28 14:00:32 -05002687 time_t new_start_time = kStartTime + timeout - 10;
2688 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002689 bssl::UniquePtr<SSL_SESSION> new_session = ExpectSessionRenewed(
2690 client_ctx_.get(), server_ctx_.get(), session.get());
2691 ASSERT_TRUE(new_session);
David Benjamin0fef3052016-11-18 15:11:10 +09002692
2693 // This new session is not the same object as before.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002694 EXPECT_NE(session.get(), new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002695
2696 // Check the sessions have timestamps measured from issuance.
2697 long session_time = 0;
2698 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002699 ASSERT_TRUE(GetServerTicketTime(&session_time, new_session.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09002700 } else {
David Benjaminaaef8332018-06-29 16:45:49 -04002701 session_time = SSL_SESSION_get_time(new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002702 }
David Benjamin721e8b72016-08-03 13:13:17 -04002703
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002704 ASSERT_EQ(session_time, g_current_time.tv_sec);
David Benjamin721e8b72016-08-03 13:13:17 -04002705
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002706 if (version() == TLS1_3_VERSION) {
David Benjamin17b30832017-01-28 14:00:32 -05002707 // Renewal incorporates fresh key material in TLS 1.3, so we extend the
2708 // lifetime TLS 1.3.
2709 g_current_time.tv_sec = new_start_time + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002710 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2711 new_session.get(),
2712 true /* expect session reused */));
David Benjamin721e8b72016-08-03 13:13:17 -04002713
David Benjamin17b30832017-01-28 14:00:32 -05002714 // The new session expires after the new timeout.
2715 g_current_time.tv_sec = new_start_time + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002716 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2717 new_session.get(),
2718 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002719
2720 // Renew the session until it begins just past the auth timeout.
2721 time_t auth_end_time = kStartTime + SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
2722 while (new_start_time < auth_end_time - 1000) {
2723 // Get as close as possible to target start time.
2724 new_start_time =
2725 std::min(auth_end_time - 1000, new_start_time + timeout - 1);
2726 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002727 new_session = ExpectSessionRenewed(client_ctx_.get(), server_ctx_.get(),
David Benjamin17b30832017-01-28 14:00:32 -05002728 new_session.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002729 ASSERT_TRUE(new_session);
David Benjamin17b30832017-01-28 14:00:32 -05002730 }
2731
2732 // Now the session's lifetime is bound by the auth timeout.
2733 g_current_time.tv_sec = auth_end_time - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002734 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2735 new_session.get(),
2736 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002737
2738 g_current_time.tv_sec = auth_end_time + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002739 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2740 new_session.get(),
2741 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002742 } else {
2743 // The new session is usable just before the old expiration.
2744 g_current_time.tv_sec = kStartTime + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002745 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2746 new_session.get(),
2747 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002748
2749 // Renewal does not extend the lifetime, so it is not usable beyond the
2750 // old expiration.
2751 g_current_time.tv_sec = kStartTime + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002752 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2753 new_session.get(),
2754 false /* expect session not reused */));
David Benjamin1b22f852016-10-27 16:36:32 -04002755 }
David Benjamin721e8b72016-08-03 13:13:17 -04002756 }
David Benjamin721e8b72016-08-03 13:13:17 -04002757}
2758
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002759TEST_P(SSLVersionTest, DefaultTicketKeyInitialization) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002760 static const uint8_t kZeroKey[kTicketKeyLen] = {};
2761 uint8_t ticket_key[kTicketKeyLen];
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002762 ASSERT_EQ(1, SSL_CTX_get_tlsext_ticket_keys(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002763 kTicketKeyLen));
2764 ASSERT_NE(0, OPENSSL_memcmp(ticket_key, kZeroKey, kTicketKeyLen));
2765}
2766
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002767TEST_P(SSLVersionTest, DefaultTicketKeyRotation) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002768 static const time_t kStartTime = 1001;
2769 g_current_time.tv_sec = kStartTime;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002770
David Benjaminc11ea9422017-08-29 16:33:21 -04002771 // We use session reuse as a proxy for ticket decryption success, hence
2772 // disable session timeouts.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002773 SSL_CTX_set_timeout(server_ctx_.get(), std::numeric_limits<uint32_t>::max());
2774 SSL_CTX_set_session_psk_dhe_timeout(server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002775 std::numeric_limits<uint32_t>::max());
2776
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002777 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2778 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002779
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002780 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2781 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_OFF);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002782
David Benjamin1f0d54b2018-08-09 16:19:13 -05002783 // Initialize ticket_key with the current key and check that it was
2784 // initialized to something, not all zeros.
2785 uint8_t ticket_key[kTicketKeyLen] = {0};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002786 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2787 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002788
David Benjaminc11ea9422017-08-29 16:33:21 -04002789 // Verify ticket resumption actually works.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002790 bssl::UniquePtr<SSL> client, server;
2791 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002792 CreateClientSession(client_ctx_.get(), server_ctx_.get());
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002793 ASSERT_TRUE(session);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002794 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002795 session.get(), true /* reused */));
2796
David Benjaminc11ea9422017-08-29 16:33:21 -04002797 // Advance time to just before key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002798 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002799 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002800 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002801 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002802 false /* NOT changed */));
2803
David Benjaminc11ea9422017-08-29 16:33:21 -04002804 // Force key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002805 g_current_time.tv_sec += 1;
2806 bssl::UniquePtr<SSL_SESSION> new_session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002807 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2808 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2809 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002810
David Benjaminc11ea9422017-08-29 16:33:21 -04002811 // Resumption with both old and new ticket should work.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002812 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002813 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002814 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002815 new_session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002816 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002817 false /* NOT changed */));
2818
David Benjaminc11ea9422017-08-29 16:33:21 -04002819 // Force key rotation again. Resumption with the old ticket now fails.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002820 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002821 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002822 session.get(), false /* NOT reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002823 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2824 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002825
David Benjaminc11ea9422017-08-29 16:33:21 -04002826 // But resumption with the newer session still works.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002827 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002828 new_session.get(), true /* reused */));
2829}
2830
David Benjamin0fc37ef2016-08-17 15:29:46 -04002831static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002832 SSL_CTX *ctx = reinterpret_cast<SSL_CTX *>(arg);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002833 SSL_set_SSL_CTX(ssl, ctx);
2834 return SSL_TLSEXT_ERR_OK;
2835}
2836
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002837TEST_P(SSLVersionTest, SNICallback) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002838 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002839 ASSERT_TRUE(cert2);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002840 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002841 ASSERT_TRUE(key2);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002842
David Benjamin0fef3052016-11-18 15:11:10 +09002843 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
2844 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002845
David Benjamin83a32122017-02-14 18:34:54 -05002846 static const uint8_t kSCTList[] = {0, 6, 0, 4, 5, 6, 7, 8};
2847 static const uint8_t kOCSPResponse[] = {1, 2, 3, 4};
2848
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002849 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
2850 ASSERT_TRUE(server_ctx2);
2851 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()));
2852 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()));
2853 ASSERT_TRUE(SSL_CTX_set_signed_cert_timestamp_list(
2854 server_ctx2.get(), kSCTList, sizeof(kSCTList)));
2855 ASSERT_TRUE(SSL_CTX_set_ocsp_response(server_ctx2.get(), kOCSPResponse,
2856 sizeof(kOCSPResponse)));
2857 // Historically signing preferences would be lost in some cases with the
2858 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2859 // this doesn't happen when |version| is TLS 1.2, configure the private
2860 // key to only sign SHA-256.
2861 ASSERT_TRUE(SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
2862 &kECDSAWithSHA256, 1));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002863
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002864 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), SwitchContext);
2865 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002866
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002867 SSL_CTX_enable_signed_cert_timestamps(client_ctx_.get());
2868 SSL_CTX_enable_ocsp_stapling(client_ctx_.get());
David Benjamin83a32122017-02-14 18:34:54 -05002869
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002870 ASSERT_TRUE(Connect());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002871
David Benjamin0fef3052016-11-18 15:11:10 +09002872 // The client should have received |cert2|.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002873 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client_.get()));
2874 ASSERT_TRUE(peer);
2875 EXPECT_EQ(X509_cmp(peer.get(), cert2.get()), 0);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002876
David Benjamin83a32122017-02-14 18:34:54 -05002877 // The client should have received |server_ctx2|'s SCT list.
2878 const uint8_t *data;
2879 size_t len;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002880 SSL_get0_signed_cert_timestamp_list(client_.get(), &data, &len);
2881 EXPECT_EQ(Bytes(kSCTList), Bytes(data, len));
David Benjamin83a32122017-02-14 18:34:54 -05002882
2883 // The client should have received |server_ctx2|'s OCSP response.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002884 SSL_get0_ocsp_response(client_.get(), &data, &len);
2885 EXPECT_EQ(Bytes(kOCSPResponse), Bytes(data, len));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002886}
2887
David Benjaminf0d8e222017-02-04 10:58:26 -05002888// Test that the early callback can swap the maximum version.
2889TEST(SSLTest, EarlyCallbackVersionSwitch) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04002890 bssl::UniquePtr<SSL_CTX> server_ctx =
2891 CreateContextWithTestCertificate(TLS_method());
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002892 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002893 ASSERT_TRUE(server_ctx);
2894 ASSERT_TRUE(client_ctx);
David Benjaminf0d8e222017-02-04 10:58:26 -05002895 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
2896 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
David Benjamin99620572016-08-30 00:35:36 -04002897
David Benjaminf0d8e222017-02-04 10:58:26 -05002898 SSL_CTX_set_select_certificate_cb(
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002899 server_ctx.get(),
2900 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
David Benjaminf0d8e222017-02-04 10:58:26 -05002901 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002902 return ssl_select_cert_error;
David Benjaminf0d8e222017-02-04 10:58:26 -05002903 }
2904
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002905 return ssl_select_cert_success;
David Benjaminf0d8e222017-02-04 10:58:26 -05002906 });
David Benjamin99620572016-08-30 00:35:36 -04002907
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002908 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05002909 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04002910 server_ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002911 EXPECT_EQ(TLS1_2_VERSION, SSL_version(client.get()));
David Benjamin99620572016-08-30 00:35:36 -04002912}
2913
David Benjaminf0d8e222017-02-04 10:58:26 -05002914TEST(SSLTest, SetVersion) {
David Benjamin2dc02042016-09-19 19:57:37 -04002915 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002916 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002917
David Benjaminf0d8e222017-02-04 10:58:26 -05002918 // Set valid TLS versions.
2919 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2920 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
2921 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2922 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002923
David Benjaminf0d8e222017-02-04 10:58:26 -05002924 // Invalid TLS versions are rejected.
2925 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2926 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x0200));
2927 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2928 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2929 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x0200));
2930 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002931
David Benjaminf0d8e222017-02-04 10:58:26 -05002932 // Zero is the default version.
2933 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08002934 EXPECT_EQ(TLS1_3_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002935 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07002936 EXPECT_EQ(TLS1_VERSION, SSL_CTX_get_min_proto_version(ctx.get()));
David Benjamin3cfeb952017-03-01 16:48:38 -05002937
David Benjamin9bb15f52018-06-26 00:07:40 -04002938 // TLS 1.3 is available, but not by default.
David Benjamin3cfeb952017-03-01 16:48:38 -05002939 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07002940 EXPECT_EQ(TLS1_3_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjamine34bcc92016-09-21 16:53:09 -04002941
David Benjamin9bb15f52018-06-26 00:07:40 -04002942 // SSL 3.0 is not available.
2943 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION));
2944
David Benjamin2dc02042016-09-19 19:57:37 -04002945 ctx.reset(SSL_CTX_new(DTLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002946 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002947
David Benjaminf0d8e222017-02-04 10:58:26 -05002948 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2949 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION));
2950 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2951 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002952
David Benjaminf0d8e222017-02-04 10:58:26 -05002953 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2954 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2955 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2956 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2957 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2958 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2959 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2960 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002961
David Benjaminf0d8e222017-02-04 10:58:26 -05002962 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07002963 EXPECT_EQ(DTLS1_2_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002964 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07002965 EXPECT_EQ(DTLS1_VERSION, SSL_CTX_get_min_proto_version(ctx.get()));
David Benjamin2dc02042016-09-19 19:57:37 -04002966}
2967
David Benjamin458334a2016-12-15 13:53:25 -05002968static const char *GetVersionName(uint16_t version) {
2969 switch (version) {
David Benjamin458334a2016-12-15 13:53:25 -05002970 case TLS1_VERSION:
2971 return "TLSv1";
2972 case TLS1_1_VERSION:
2973 return "TLSv1.1";
2974 case TLS1_2_VERSION:
2975 return "TLSv1.2";
2976 case TLS1_3_VERSION:
2977 return "TLSv1.3";
2978 case DTLS1_VERSION:
2979 return "DTLSv1";
2980 case DTLS1_2_VERSION:
2981 return "DTLSv1.2";
2982 default:
2983 return "???";
2984 }
2985}
2986
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002987TEST_P(SSLVersionTest, Version) {
2988 ASSERT_TRUE(Connect());
David Benjamincb18ac22016-09-27 14:09:15 -04002989
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002990 EXPECT_EQ(SSL_version(client_.get()), version());
2991 EXPECT_EQ(SSL_version(server_.get()), version());
David Benjamincb18ac22016-09-27 14:09:15 -04002992
David Benjamin458334a2016-12-15 13:53:25 -05002993 // Test the version name is reported as expected.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002994 const char *version_name = GetVersionName(version());
2995 EXPECT_EQ(strcmp(version_name, SSL_get_version(client_.get())), 0);
2996 EXPECT_EQ(strcmp(version_name, SSL_get_version(server_.get())), 0);
David Benjamin458334a2016-12-15 13:53:25 -05002997
2998 // Test SSL_SESSION reports the same name.
2999 const char *client_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003000 SSL_SESSION_get_version(SSL_get_session(client_.get()));
David Benjamin458334a2016-12-15 13:53:25 -05003001 const char *server_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003002 SSL_SESSION_get_version(SSL_get_session(server_.get()));
3003 EXPECT_EQ(strcmp(version_name, client_name), 0);
3004 EXPECT_EQ(strcmp(version_name, server_name), 0);
David Benjamincb18ac22016-09-27 14:09:15 -04003005}
3006
David Benjamin9ef31f02016-10-31 18:01:13 -04003007// Tests that that |SSL_get_pending_cipher| is available during the ALPN
3008// selection callback.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003009TEST_P(SSLVersionTest, ALPNCipherAvailable) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003010 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
3011
David Benjamin9ef31f02016-10-31 18:01:13 -04003012 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003013 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
3014 sizeof(kALPNProtos)),
3015 0);
David Benjamin0fef3052016-11-18 15:11:10 +09003016
3017 // The ALPN callback does not fail the handshake on error, so have the
3018 // callback write a boolean.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003019 std::pair<uint16_t, bool> callback_state(version(), false);
David Benjamin0fef3052016-11-18 15:11:10 +09003020 SSL_CTX_set_alpn_select_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003021 server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09003022 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
3023 unsigned in_len, void *arg) -> int {
3024 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
3025 if (SSL_get_pending_cipher(ssl) != nullptr &&
3026 SSL_version(ssl) == state->first) {
3027 state->second = true;
3028 }
3029 return SSL_TLSEXT_ERR_NOACK;
3030 },
3031 &callback_state);
3032
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003033 ASSERT_TRUE(Connect());
David Benjamin0fef3052016-11-18 15:11:10 +09003034
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003035 ASSERT_TRUE(callback_state.second);
David Benjamin0fef3052016-11-18 15:11:10 +09003036}
3037
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003038TEST_P(SSLVersionTest, SSLClearSessionResumption) {
David Benjaminb79cc842016-12-07 15:57:14 -05003039 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
3040 // API pattern.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003041 if (version() == TLS1_3_VERSION) {
3042 return;
David Benjaminb79cc842016-12-07 15:57:14 -05003043 }
3044
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07003045 shed_handshake_config_ = false;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003046 ASSERT_TRUE(Connect());
David Benjaminb79cc842016-12-07 15:57:14 -05003047
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003048 EXPECT_FALSE(SSL_session_reused(client_.get()));
3049 EXPECT_FALSE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003050
3051 // Reset everything.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003052 ASSERT_TRUE(SSL_clear(client_.get()));
3053 ASSERT_TRUE(SSL_clear(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003054
3055 // Attempt to connect a second time.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003056 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003057
3058 // |SSL_clear| should implicitly offer the previous session to the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003059 EXPECT_TRUE(SSL_session_reused(client_.get()));
3060 EXPECT_TRUE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05003061}
3062
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07003063TEST_P(SSLVersionTest, SSLClearFailsWithShedding) {
3064 shed_handshake_config_ = false;
3065 ASSERT_TRUE(Connect());
3066 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
3067
3068 // Reset everything.
3069 ASSERT_TRUE(SSL_clear(client_.get()));
3070 ASSERT_TRUE(SSL_clear(server_.get()));
3071
3072 // Now enable shedding, and connect a second time.
3073 shed_handshake_config_ = true;
3074 ASSERT_TRUE(Connect());
3075 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
3076
3077 // |SSL_clear| should now fail.
3078 ASSERT_FALSE(SSL_clear(client_.get()));
3079 ASSERT_FALSE(SSL_clear(server_.get()));
3080}
3081
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003082static bool ChainsEqual(STACK_OF(X509) * chain,
3083 const std::vector<X509 *> &expected) {
David Benjamin1444c3a2016-12-20 17:23:11 -05003084 if (sk_X509_num(chain) != expected.size()) {
3085 return false;
3086 }
3087
3088 for (size_t i = 0; i < expected.size(); i++) {
3089 if (X509_cmp(sk_X509_value(chain, i), expected[i]) != 0) {
3090 return false;
3091 }
3092 }
3093
3094 return true;
3095}
3096
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003097TEST_P(SSLVersionTest, AutoChain) {
3098 cert_ = GetChainTestCertificate();
3099 ASSERT_TRUE(cert_);
3100 key_ = GetChainTestKey();
3101 ASSERT_TRUE(key_);
David Benjamin1444c3a2016-12-20 17:23:11 -05003102 bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003103 ASSERT_TRUE(intermediate);
3104
3105 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
3106 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin1444c3a2016-12-20 17:23:11 -05003107
3108 // Configure both client and server to accept any certificate. Add
3109 // |intermediate| to the cert store.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003110 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx_.get()),
3111 intermediate.get()));
3112 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(server_ctx_.get()),
3113 intermediate.get()));
3114 SSL_CTX_set_verify(client_ctx_.get(),
3115 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3116 nullptr);
3117 SSL_CTX_set_verify(server_ctx_.get(),
3118 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3119 nullptr);
3120 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
3121 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjamin1444c3a2016-12-20 17:23:11 -05003122
3123 // By default, the client and server should each only send the leaf.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003124 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05003125
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003126 EXPECT_TRUE(
3127 ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()), {cert_.get()}));
3128 EXPECT_TRUE(
3129 ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()), {cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003130
3131 // If auto-chaining is enabled, then the intermediate is sent.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003132 SSL_CTX_clear_mode(client_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
3133 SSL_CTX_clear_mode(server_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
3134 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05003135
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003136 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
3137 {cert_.get(), intermediate.get()}));
3138 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
3139 {cert_.get(), intermediate.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003140
3141 // Auto-chaining does not override explicitly-configured intermediates.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003142 ASSERT_TRUE(SSL_CTX_add1_chain_cert(client_ctx_.get(), cert_.get()));
3143 ASSERT_TRUE(SSL_CTX_add1_chain_cert(server_ctx_.get(), cert_.get()));
3144 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05003145
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003146 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
3147 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003148
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003149 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
3150 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05003151}
3152
David Benjamin48063c22017-01-01 23:56:36 -05003153static bool ExpectBadWriteRetry() {
3154 int err = ERR_get_error();
3155 if (ERR_GET_LIB(err) != ERR_LIB_SSL ||
3156 ERR_GET_REASON(err) != SSL_R_BAD_WRITE_RETRY) {
3157 char buf[ERR_ERROR_STRING_BUF_LEN];
3158 ERR_error_string_n(err, buf, sizeof(buf));
3159 fprintf(stderr, "Wanted SSL_R_BAD_WRITE_RETRY, got: %s.\n", buf);
3160 return false;
3161 }
3162
3163 if (ERR_peek_error() != 0) {
3164 fprintf(stderr, "Unexpected error following SSL_R_BAD_WRITE_RETRY.\n");
3165 return false;
3166 }
3167
3168 return true;
3169}
3170
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003171TEST_P(SSLVersionTest, SSLWriteRetry) {
3172 if (is_dtls()) {
3173 return;
David Benjamin48063c22017-01-01 23:56:36 -05003174 }
3175
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003176 for (bool enable_partial_write : {false, true}) {
3177 SCOPED_TRACE(enable_partial_write);
3178
David Benjamin48063c22017-01-01 23:56:36 -05003179 // Connect a client and server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003180 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
3181
3182 ASSERT_TRUE(Connect());
David Benjamin48063c22017-01-01 23:56:36 -05003183
3184 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003185 SSL_set_mode(client_.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003186 }
3187
3188 // Write without reading until the buffer is full and we have an unfinished
3189 // write. Keep a count so we may reread it again later. "hello!" will be
3190 // written in two chunks, "hello" and "!".
3191 char data[] = "hello!";
3192 static const int kChunkLen = 5; // The length of "hello".
3193 unsigned count = 0;
3194 for (;;) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003195 int ret = SSL_write(client_.get(), data, kChunkLen);
David Benjamin48063c22017-01-01 23:56:36 -05003196 if (ret <= 0) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003197 ASSERT_EQ(SSL_get_error(client_.get(), ret), SSL_ERROR_WANT_WRITE);
3198 break;
David Benjamin48063c22017-01-01 23:56:36 -05003199 }
3200
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003201 ASSERT_EQ(ret, 5);
David Benjamin48063c22017-01-01 23:56:36 -05003202
3203 count++;
3204 }
3205
3206 // Retrying with the same parameters is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003207 ASSERT_EQ(
3208 SSL_get_error(client_.get(), SSL_write(client_.get(), data, kChunkLen)),
3209 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003210
3211 // Retrying with the same buffer but shorter length is not legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003212 ASSERT_EQ(SSL_get_error(client_.get(),
3213 SSL_write(client_.get(), data, kChunkLen - 1)),
3214 SSL_ERROR_SSL);
3215 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05003216
3217 // Retrying with a different buffer pointer is not legal.
3218 char data2[] = "hello";
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003219 ASSERT_EQ(SSL_get_error(client_.get(),
3220 SSL_write(client_.get(), data2, kChunkLen)),
3221 SSL_ERROR_SSL);
3222 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05003223
3224 // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003225 SSL_set_mode(client_.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
3226 ASSERT_EQ(SSL_get_error(client_.get(),
3227 SSL_write(client_.get(), data2, kChunkLen)),
3228 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003229
3230 // |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| does not disable length checks.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003231 ASSERT_EQ(SSL_get_error(client_.get(),
3232 SSL_write(client_.get(), data2, kChunkLen - 1)),
3233 SSL_ERROR_SSL);
3234 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05003235
3236 // Retrying with a larger buffer is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003237 ASSERT_EQ(SSL_get_error(client_.get(),
3238 SSL_write(client_.get(), data, kChunkLen + 1)),
3239 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05003240
3241 // Drain the buffer.
3242 char buf[20];
3243 for (unsigned i = 0; i < count; i++) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003244 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
3245 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
David Benjamin48063c22017-01-01 23:56:36 -05003246 }
3247
3248 // Now that there is space, a retry with a larger buffer should flush the
3249 // pending record, skip over that many bytes of input (on assumption they
3250 // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE
3251 // is set, this will complete in two steps.
3252 char data3[] = "_____!";
3253 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003254 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen);
3255 ASSERT_EQ(SSL_write(client_.get(), data3 + kChunkLen, 1), 1);
3256 } else {
3257 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen + 1);
David Benjamin48063c22017-01-01 23:56:36 -05003258 }
3259
3260 // Check the last write was correct. The data will be spread over two
3261 // records, so SSL_read returns twice.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003262 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
3263 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
3264 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), 1);
3265 ASSERT_EQ(buf[0], '!');
David Benjamin48063c22017-01-01 23:56:36 -05003266 }
David Benjamin48063c22017-01-01 23:56:36 -05003267}
3268
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003269TEST_P(SSLVersionTest, RecordCallback) {
3270 for (bool test_server : {true, false}) {
3271 SCOPED_TRACE(test_server);
3272 ResetContexts();
David Benjamin5df5be12017-06-22 19:43:11 -04003273
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003274 bool read_seen = false;
3275 bool write_seen = false;
3276 auto cb = [&](int is_write, int cb_version, int cb_type, const void *buf,
3277 size_t len, SSL *ssl) {
3278 if (cb_type != SSL3_RT_HEADER) {
3279 return;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003280 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003281
3282 // The callback does not report a version for records.
3283 EXPECT_EQ(0, cb_version);
3284
3285 if (is_write) {
3286 write_seen = true;
3287 } else {
3288 read_seen = true;
3289 }
3290
3291 // Sanity-check that the record header is plausible.
3292 CBS cbs;
3293 CBS_init(&cbs, reinterpret_cast<const uint8_t *>(buf), len);
3294 uint8_t type;
3295 uint16_t record_version, length;
3296 ASSERT_TRUE(CBS_get_u8(&cbs, &type));
3297 ASSERT_TRUE(CBS_get_u16(&cbs, &record_version));
Steven Valdez64cc1212017-12-04 11:15:37 -05003298 EXPECT_EQ(record_version & 0xff00, version() & 0xff00);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003299 if (is_dtls()) {
3300 uint16_t epoch;
3301 ASSERT_TRUE(CBS_get_u16(&cbs, &epoch));
3302 EXPECT_TRUE(epoch == 0 || epoch == 1) << "Invalid epoch: " << epoch;
3303 ASSERT_TRUE(CBS_skip(&cbs, 6));
3304 }
3305 ASSERT_TRUE(CBS_get_u16(&cbs, &length));
3306 EXPECT_EQ(0u, CBS_len(&cbs));
3307 };
3308 using CallbackType = decltype(cb);
3309 SSL_CTX *ctx = test_server ? server_ctx_.get() : client_ctx_.get();
3310 SSL_CTX_set_msg_callback(
3311 ctx, [](int is_write, int cb_version, int cb_type, const void *buf,
3312 size_t len, SSL *ssl, void *arg) {
3313 CallbackType *cb_ptr = reinterpret_cast<CallbackType *>(arg);
3314 (*cb_ptr)(is_write, cb_version, cb_type, buf, len, ssl);
3315 });
3316 SSL_CTX_set_msg_callback_arg(ctx, &cb);
3317
3318 ASSERT_TRUE(Connect());
3319
3320 EXPECT_TRUE(read_seen);
3321 EXPECT_TRUE(write_seen);
David Benjamin0fef3052016-11-18 15:11:10 +09003322 }
David Benjamin9ef31f02016-10-31 18:01:13 -04003323}
3324
David Benjamina8614602017-09-06 15:40:19 -04003325TEST_P(SSLVersionTest, GetServerName) {
David Benjamina8614602017-09-06 15:40:19 -04003326 ClientConfig config;
3327 config.servername = "host1";
3328
3329 SSL_CTX_set_tlsext_servername_callback(
3330 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
3331 // During the handshake, |SSL_get_servername| must match |config|.
3332 ClientConfig *config_p = reinterpret_cast<ClientConfig *>(arg);
3333 EXPECT_STREQ(config_p->servername.c_str(),
3334 SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name));
3335 return SSL_TLSEXT_ERR_OK;
3336 });
3337 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), &config);
3338
3339 ASSERT_TRUE(Connect(config));
3340 // After the handshake, it must also be available.
3341 EXPECT_STREQ(config.servername.c_str(),
3342 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3343
3344 // Establish a session under host1.
3345 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3346 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3347 bssl::UniquePtr<SSL_SESSION> session =
3348 CreateClientSession(client_ctx_.get(), server_ctx_.get(), config);
3349
3350 // If the client resumes a session with a different name, |SSL_get_servername|
3351 // must return the new name.
3352 ASSERT_TRUE(session);
3353 config.session = session.get();
3354 config.servername = "host2";
3355 ASSERT_TRUE(Connect(config));
3356 EXPECT_STREQ(config.servername.c_str(),
3357 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3358}
3359
David Benjamin3d8f0802017-09-06 16:12:52 -04003360// Test that session cache mode bits are honored in the client session callback.
3361TEST_P(SSLVersionTest, ClientSessionCacheMode) {
3362 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_OFF);
3363 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3364
3365 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_CLIENT);
3366 EXPECT_TRUE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3367
3368 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_SERVER);
3369 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3370}
3371
Steven Valdez777a2392019-02-21 11:30:47 -05003372// Test that all versions survive tiny write buffers. In particular, TLS 1.3
3373// NewSessionTickets are written post-handshake. Servers that block
3374// |SSL_do_handshake| on writing them will deadlock if clients are not draining
3375// the buffer. Test that we do not do this.
3376TEST_P(SSLVersionTest, SmallBuffer) {
3377 // DTLS is a datagram protocol and requires packet-sized buffers.
3378 if (is_dtls()) {
3379 return;
3380 }
3381
3382 // Test both flushing NewSessionTickets with a zero-sized write and
3383 // non-zero-sized write.
3384 for (bool use_zero_write : {false, true}) {
3385 SCOPED_TRACE(use_zero_write);
3386
3387 g_last_session = nullptr;
3388 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3389 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
3390
3391 bssl::UniquePtr<SSL> client(SSL_new(client_ctx_.get())),
3392 server(SSL_new(server_ctx_.get()));
3393 ASSERT_TRUE(client);
3394 ASSERT_TRUE(server);
3395 SSL_set_connect_state(client.get());
3396 SSL_set_accept_state(server.get());
3397
3398 // Use a tiny buffer.
3399 BIO *bio1, *bio2;
3400 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 1, &bio2, 1));
3401
3402 // SSL_set_bio takes ownership.
3403 SSL_set_bio(client.get(), bio1, bio1);
3404 SSL_set_bio(server.get(), bio2, bio2);
3405
3406 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
3407 if (version() >= TLS1_3_VERSION) {
3408 // The post-handshake ticket should not have been processed yet.
3409 EXPECT_FALSE(g_last_session);
3410 }
3411
3412 if (use_zero_write) {
3413 ASSERT_TRUE(FlushNewSessionTickets(client.get(), server.get()));
3414 EXPECT_TRUE(g_last_session);
3415 }
3416
3417 // Send some data from server to client. If |use_zero_write| is false, this
3418 // will also flush the NewSessionTickets.
3419 static const char kMessage[] = "hello world";
3420 char buf[sizeof(kMessage)];
3421 for (;;) {
3422 int server_ret = SSL_write(server.get(), kMessage, sizeof(kMessage));
3423 int server_err = SSL_get_error(server.get(), server_ret);
3424 int client_ret = SSL_read(client.get(), buf, sizeof(buf));
3425 int client_err = SSL_get_error(client.get(), client_ret);
3426
3427 // The server will write a single record, so every iteration should see
3428 // |SSL_ERROR_WANT_WRITE| and |SSL_ERROR_WANT_READ|, until the final
3429 // iteration, where both will complete.
3430 if (server_ret > 0) {
3431 EXPECT_EQ(server_ret, static_cast<int>(sizeof(kMessage)));
3432 EXPECT_EQ(client_ret, static_cast<int>(sizeof(kMessage)));
3433 EXPECT_EQ(Bytes(buf), Bytes(kMessage));
3434 break;
3435 }
3436
3437 ASSERT_EQ(server_ret, -1);
3438 ASSERT_EQ(server_err, SSL_ERROR_WANT_WRITE);
3439 ASSERT_EQ(client_ret, -1);
3440 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
3441 }
3442
3443 // The NewSessionTickets should have been flushed and processed.
3444 EXPECT_TRUE(g_last_session);
3445 }
3446}
3447
Adam Langleye1e78132017-01-31 15:24:31 -08003448TEST(SSLTest, AddChainCertHack) {
3449 // Ensure that we don't accidently break the hack that we have in place to
3450 // keep curl and serf happy when they use an |X509| even after transfering
3451 // ownership.
3452
3453 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3454 ASSERT_TRUE(ctx);
3455 X509 *cert = GetTestCertificate().release();
3456 ASSERT_TRUE(cert);
3457 SSL_CTX_add0_chain_cert(ctx.get(), cert);
3458
3459 // This should not trigger a use-after-free.
3460 X509_cmp(cert, cert);
3461}
3462
David Benjaminb2ff2622017-02-03 17:06:18 -05003463TEST(SSLTest, GetCertificate) {
3464 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3465 ASSERT_TRUE(ctx);
3466 bssl::UniquePtr<X509> cert = GetTestCertificate();
3467 ASSERT_TRUE(cert);
3468 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
3469 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3470 ASSERT_TRUE(ssl);
3471
3472 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
3473 ASSERT_TRUE(cert2);
3474 X509 *cert3 = SSL_get_certificate(ssl.get());
3475 ASSERT_TRUE(cert3);
3476
3477 // The old and new certificates must be identical.
3478 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
3479 EXPECT_EQ(0, X509_cmp(cert.get(), cert3));
3480
3481 uint8_t *der = nullptr;
3482 long der_len = i2d_X509(cert.get(), &der);
3483 ASSERT_LT(0, der_len);
3484 bssl::UniquePtr<uint8_t> free_der(der);
3485
3486 uint8_t *der2 = nullptr;
3487 long der2_len = i2d_X509(cert2, &der2);
3488 ASSERT_LT(0, der2_len);
3489 bssl::UniquePtr<uint8_t> free_der2(der2);
3490
3491 uint8_t *der3 = nullptr;
3492 long der3_len = i2d_X509(cert3, &der3);
3493 ASSERT_LT(0, der3_len);
3494 bssl::UniquePtr<uint8_t> free_der3(der3);
3495
3496 // They must also encode identically.
David Benjamin7d7554b2017-02-04 11:48:59 -05003497 EXPECT_EQ(Bytes(der, der_len), Bytes(der2, der2_len));
3498 EXPECT_EQ(Bytes(der, der_len), Bytes(der3, der3_len));
David Benjaminb2ff2622017-02-03 17:06:18 -05003499}
3500
Adam Langleyd04ca952017-02-28 11:26:51 -08003501TEST(SSLTest, SetChainAndKeyMismatch) {
3502 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_with_buffers_method()));
3503 ASSERT_TRUE(ctx);
3504
3505 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3506 ASSERT_TRUE(key);
3507 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3508 ASSERT_TRUE(leaf);
3509 std::vector<CRYPTO_BUFFER*> chain = {
3510 leaf.get(),
3511 };
3512
3513 // Should fail because |GetTestKey| doesn't match the chain-test certificate.
3514 ASSERT_FALSE(SSL_CTX_set_chain_and_key(ctx.get(), &chain[0], chain.size(),
3515 key.get(), nullptr));
3516 ERR_clear_error();
3517}
3518
3519TEST(SSLTest, SetChainAndKey) {
3520 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3521 ASSERT_TRUE(client_ctx);
3522 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3523 ASSERT_TRUE(server_ctx);
3524
Adam Langley964256d2020-03-19 11:57:12 -07003525 ASSERT_EQ(nullptr, SSL_CTX_get0_chain(server_ctx.get()));
3526
Adam Langleyd04ca952017-02-28 11:26:51 -08003527 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3528 ASSERT_TRUE(key);
3529 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3530 ASSERT_TRUE(leaf);
3531 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3532 GetChainTestIntermediateBuffer();
3533 ASSERT_TRUE(intermediate);
3534 std::vector<CRYPTO_BUFFER*> chain = {
3535 leaf.get(), intermediate.get(),
3536 };
3537 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3538 chain.size(), key.get(), nullptr));
3539
Adam Langley964256d2020-03-19 11:57:12 -07003540 ASSERT_EQ(chain.size(),
3541 sk_CRYPTO_BUFFER_num(SSL_CTX_get0_chain(server_ctx.get())));
3542
David Benjamin3a1dd462017-07-11 16:13:10 -04003543 SSL_CTX_set_custom_verify(
3544 client_ctx.get(), SSL_VERIFY_PEER,
3545 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3546 return ssl_verify_ok;
3547 });
Adam Langleyd04ca952017-02-28 11:26:51 -08003548
3549 bssl::UniquePtr<SSL> client, server;
3550 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003551 server_ctx.get()));
Adam Langleyd04ca952017-02-28 11:26:51 -08003552}
3553
Matthew Braithwaite5301c102018-01-23 12:08:55 -08003554TEST(SSLTest, BuffersFailWithoutCustomVerify) {
3555 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3556 ASSERT_TRUE(client_ctx);
3557 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3558 ASSERT_TRUE(server_ctx);
3559
3560 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3561 ASSERT_TRUE(key);
3562 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3563 ASSERT_TRUE(leaf);
3564 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
3565 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3566 chain.size(), key.get(), nullptr));
3567
3568 // Without SSL_CTX_set_custom_verify(), i.e. with everything in the default
3569 // configuration, certificate verification should fail.
3570 bssl::UniquePtr<SSL> client, server;
3571 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3572 server_ctx.get()));
3573
3574 // Whereas with a verifier, the connection should succeed.
3575 SSL_CTX_set_custom_verify(
3576 client_ctx.get(), SSL_VERIFY_PEER,
3577 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3578 return ssl_verify_ok;
3579 });
3580 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3581 server_ctx.get()));
3582}
3583
3584TEST(SSLTest, CustomVerify) {
3585 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3586 ASSERT_TRUE(client_ctx);
3587 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3588 ASSERT_TRUE(server_ctx);
3589
3590 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3591 ASSERT_TRUE(key);
3592 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3593 ASSERT_TRUE(leaf);
3594 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
3595 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3596 chain.size(), key.get(), nullptr));
3597
3598 SSL_CTX_set_custom_verify(
3599 client_ctx.get(), SSL_VERIFY_PEER,
3600 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3601 return ssl_verify_ok;
3602 });
3603
3604 bssl::UniquePtr<SSL> client, server;
3605 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3606 server_ctx.get()));
3607
3608 // With SSL_VERIFY_PEER, ssl_verify_invalid should result in a dropped
3609 // connection.
3610 SSL_CTX_set_custom_verify(
3611 client_ctx.get(), SSL_VERIFY_PEER,
3612 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3613 return ssl_verify_invalid;
3614 });
3615
3616 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3617 server_ctx.get()));
3618
3619 // But with SSL_VERIFY_NONE, ssl_verify_invalid should not cause a dropped
3620 // connection.
3621 SSL_CTX_set_custom_verify(
3622 client_ctx.get(), SSL_VERIFY_NONE,
3623 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3624 return ssl_verify_invalid;
3625 });
3626
3627 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3628 server_ctx.get()));
3629}
3630
David Benjamin71dfad42017-07-16 17:27:39 -04003631TEST(SSLTest, ClientCABuffers) {
3632 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3633 ASSERT_TRUE(client_ctx);
3634 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3635 ASSERT_TRUE(server_ctx);
3636
3637 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3638 ASSERT_TRUE(key);
3639 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3640 ASSERT_TRUE(leaf);
3641 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3642 GetChainTestIntermediateBuffer();
3643 ASSERT_TRUE(intermediate);
3644 std::vector<CRYPTO_BUFFER *> chain = {
3645 leaf.get(),
3646 intermediate.get(),
3647 };
3648 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3649 chain.size(), key.get(), nullptr));
3650
3651 bssl::UniquePtr<CRYPTO_BUFFER> ca_name(
3652 CRYPTO_BUFFER_new(kTestName, sizeof(kTestName), nullptr));
3653 ASSERT_TRUE(ca_name);
3654 bssl::UniquePtr<STACK_OF(CRYPTO_BUFFER)> ca_names(
3655 sk_CRYPTO_BUFFER_new_null());
3656 ASSERT_TRUE(ca_names);
David Benjamin2908dd12018-06-29 17:46:42 -04003657 ASSERT_TRUE(PushToStack(ca_names.get(), std::move(ca_name)));
David Benjamin71dfad42017-07-16 17:27:39 -04003658 SSL_CTX_set0_client_CAs(server_ctx.get(), ca_names.release());
3659
3660 // Configure client and server to accept all certificates.
3661 SSL_CTX_set_custom_verify(
3662 client_ctx.get(), SSL_VERIFY_PEER,
3663 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3664 return ssl_verify_ok;
3665 });
3666 SSL_CTX_set_custom_verify(
3667 server_ctx.get(), SSL_VERIFY_PEER,
3668 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3669 return ssl_verify_ok;
3670 });
3671
3672 bool cert_cb_called = false;
3673 SSL_CTX_set_cert_cb(
3674 client_ctx.get(),
3675 [](SSL *ssl, void *arg) -> int {
David Benjamin5f001d12018-05-08 16:46:48 -04003676 const STACK_OF(CRYPTO_BUFFER) *peer_names =
David Benjamin71dfad42017-07-16 17:27:39 -04003677 SSL_get0_server_requested_CAs(ssl);
3678 EXPECT_EQ(1u, sk_CRYPTO_BUFFER_num(peer_names));
3679 CRYPTO_BUFFER *peer_name = sk_CRYPTO_BUFFER_value(peer_names, 0);
3680 EXPECT_EQ(Bytes(kTestName), Bytes(CRYPTO_BUFFER_data(peer_name),
3681 CRYPTO_BUFFER_len(peer_name)));
3682 *reinterpret_cast<bool *>(arg) = true;
3683 return 1;
3684 },
3685 &cert_cb_called);
3686
3687 bssl::UniquePtr<SSL> client, server;
3688 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003689 server_ctx.get()));
David Benjamin71dfad42017-07-16 17:27:39 -04003690 EXPECT_TRUE(cert_cb_called);
3691}
3692
David Benjamin91222b82017-03-09 20:10:56 -05003693// Configuring the empty cipher list, though an error, should still modify the
3694// configuration.
3695TEST(SSLTest, EmptyCipherList) {
3696 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3697 ASSERT_TRUE(ctx);
3698
3699 // Initially, the cipher list is not empty.
3700 EXPECT_NE(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3701
3702 // Configuring the empty cipher list fails.
3703 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), ""));
3704 ERR_clear_error();
3705
3706 // But the cipher list is still updated to empty.
3707 EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3708}
3709
Adam Langley4c341d02017-03-08 19:33:21 -08003710// ssl_test_ticket_aead_failure_mode enumerates the possible ways in which the
3711// test |SSL_TICKET_AEAD_METHOD| can fail.
3712enum ssl_test_ticket_aead_failure_mode {
3713 ssl_test_ticket_aead_ok = 0,
3714 ssl_test_ticket_aead_seal_fail,
3715 ssl_test_ticket_aead_open_soft_fail,
3716 ssl_test_ticket_aead_open_hard_fail,
3717};
3718
3719struct ssl_test_ticket_aead_state {
3720 unsigned retry_count;
3721 ssl_test_ticket_aead_failure_mode failure_mode;
3722};
3723
3724static int ssl_test_ticket_aead_ex_index_dup(CRYPTO_EX_DATA *to,
3725 const CRYPTO_EX_DATA *from,
3726 void **from_d, int index,
3727 long argl, void *argp) {
3728 abort();
3729}
3730
3731static void ssl_test_ticket_aead_ex_index_free(void *parent, void *ptr,
3732 CRYPTO_EX_DATA *ad, int index,
3733 long argl, void *argp) {
3734 auto state = reinterpret_cast<ssl_test_ticket_aead_state*>(ptr);
3735 if (state == nullptr) {
3736 return;
3737 }
3738
3739 OPENSSL_free(state);
3740}
3741
3742static CRYPTO_once_t g_ssl_test_ticket_aead_ex_index_once = CRYPTO_ONCE_INIT;
3743static int g_ssl_test_ticket_aead_ex_index;
3744
3745static int ssl_test_ticket_aead_get_ex_index() {
3746 CRYPTO_once(&g_ssl_test_ticket_aead_ex_index_once, [] {
3747 g_ssl_test_ticket_aead_ex_index = SSL_get_ex_new_index(
3748 0, nullptr, nullptr, ssl_test_ticket_aead_ex_index_dup,
3749 ssl_test_ticket_aead_ex_index_free);
3750 });
3751 return g_ssl_test_ticket_aead_ex_index;
3752}
3753
3754static size_t ssl_test_ticket_aead_max_overhead(SSL *ssl) {
3755 return 1;
3756}
3757
3758static int ssl_test_ticket_aead_seal(SSL *ssl, uint8_t *out, size_t *out_len,
3759 size_t max_out_len, const uint8_t *in,
3760 size_t in_len) {
3761 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3762 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3763
3764 if (state->failure_mode == ssl_test_ticket_aead_seal_fail ||
3765 max_out_len < in_len + 1) {
3766 return 0;
3767 }
3768
3769 OPENSSL_memmove(out, in, in_len);
3770 out[in_len] = 0xff;
3771 *out_len = in_len + 1;
3772
3773 return 1;
3774}
3775
3776static ssl_ticket_aead_result_t ssl_test_ticket_aead_open(
3777 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len,
3778 const uint8_t *in, size_t in_len) {
3779 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3780 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3781
3782 if (state->retry_count > 0) {
3783 state->retry_count--;
3784 return ssl_ticket_aead_retry;
3785 }
3786
3787 switch (state->failure_mode) {
3788 case ssl_test_ticket_aead_ok:
3789 break;
3790 case ssl_test_ticket_aead_seal_fail:
3791 // If |seal| failed then there shouldn't be any ticket to try and
3792 // decrypt.
3793 abort();
3794 break;
3795 case ssl_test_ticket_aead_open_soft_fail:
3796 return ssl_ticket_aead_ignore_ticket;
3797 case ssl_test_ticket_aead_open_hard_fail:
3798 return ssl_ticket_aead_error;
3799 }
3800
3801 if (in_len == 0 || in[in_len - 1] != 0xff) {
3802 return ssl_ticket_aead_ignore_ticket;
3803 }
3804
3805 if (max_out_len < in_len - 1) {
3806 return ssl_ticket_aead_error;
3807 }
3808
3809 OPENSSL_memmove(out, in, in_len - 1);
3810 *out_len = in_len - 1;
3811 return ssl_ticket_aead_success;
3812}
3813
3814static const SSL_TICKET_AEAD_METHOD kSSLTestTicketMethod = {
3815 ssl_test_ticket_aead_max_overhead,
3816 ssl_test_ticket_aead_seal,
3817 ssl_test_ticket_aead_open,
3818};
3819
3820static void ConnectClientAndServerWithTicketMethod(
3821 bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
3822 SSL_CTX *client_ctx, SSL_CTX *server_ctx, unsigned retry_count,
3823 ssl_test_ticket_aead_failure_mode failure_mode, SSL_SESSION *session) {
3824 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
3825 ASSERT_TRUE(client);
3826 ASSERT_TRUE(server);
3827 SSL_set_connect_state(client.get());
3828 SSL_set_accept_state(server.get());
3829
3830 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3831 OPENSSL_malloc(sizeof(ssl_test_ticket_aead_state)));
3832 ASSERT_TRUE(state);
3833 OPENSSL_memset(state, 0, sizeof(ssl_test_ticket_aead_state));
3834 state->retry_count = retry_count;
3835 state->failure_mode = failure_mode;
3836
3837 ASSERT_TRUE(SSL_set_ex_data(server.get(), ssl_test_ticket_aead_get_ex_index(),
3838 state));
3839
3840 SSL_set_session(client.get(), session);
3841
3842 BIO *bio1, *bio2;
3843 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
3844
3845 // SSL_set_bio takes ownership.
3846 SSL_set_bio(client.get(), bio1, bio1);
3847 SSL_set_bio(server.get(), bio2, bio2);
3848
3849 if (CompleteHandshakes(client.get(), server.get())) {
3850 *out_client = std::move(client);
3851 *out_server = std::move(server);
3852 } else {
3853 out_client->reset();
3854 out_server->reset();
3855 }
3856}
3857
David Benjaminc9775322018-04-13 16:39:12 -04003858using TicketAEADMethodParam =
3859 testing::tuple<uint16_t, unsigned, ssl_test_ticket_aead_failure_mode>;
3860
Adam Langley4c341d02017-03-08 19:33:21 -08003861class TicketAEADMethodTest
David Benjaminc9775322018-04-13 16:39:12 -04003862 : public ::testing::TestWithParam<TicketAEADMethodParam> {};
Adam Langley4c341d02017-03-08 19:33:21 -08003863
3864TEST_P(TicketAEADMethodTest, Resume) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04003865 bssl::UniquePtr<SSL_CTX> server_ctx =
3866 CreateContextWithTestCertificate(TLS_method());
Adam Langley4c341d02017-03-08 19:33:21 -08003867 ASSERT_TRUE(server_ctx);
3868 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
3869 ASSERT_TRUE(client_ctx);
3870
3871 const uint16_t version = testing::get<0>(GetParam());
3872 const unsigned retry_count = testing::get<1>(GetParam());
3873 const ssl_test_ticket_aead_failure_mode failure_mode =
3874 testing::get<2>(GetParam());
3875
Adam Langley4c341d02017-03-08 19:33:21 -08003876 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), version));
3877 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), version));
3878 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), version));
3879 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), version));
3880
3881 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
3882 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
3883 SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
3884 SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
David Benjamin707af292017-03-10 17:47:18 -05003885 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langley4c341d02017-03-08 19:33:21 -08003886
3887 SSL_CTX_set_ticket_aead_method(server_ctx.get(), &kSSLTestTicketMethod);
3888
3889 bssl::UniquePtr<SSL> client, server;
3890 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3891 server_ctx.get(), retry_count,
3892 failure_mode, nullptr);
3893 switch (failure_mode) {
3894 case ssl_test_ticket_aead_ok:
3895 case ssl_test_ticket_aead_open_hard_fail:
3896 case ssl_test_ticket_aead_open_soft_fail:
3897 ASSERT_TRUE(client);
3898 break;
3899 case ssl_test_ticket_aead_seal_fail:
3900 EXPECT_FALSE(client);
3901 return;
3902 }
3903 EXPECT_FALSE(SSL_session_reused(client.get()));
3904 EXPECT_FALSE(SSL_session_reused(server.get()));
3905
Steven Valdez777a2392019-02-21 11:30:47 -05003906 ASSERT_TRUE(FlushNewSessionTickets(client.get(), server.get()));
David Benjamin707af292017-03-10 17:47:18 -05003907 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
Adam Langley4c341d02017-03-08 19:33:21 -08003908 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3909 server_ctx.get(), retry_count,
David Benjamin707af292017-03-10 17:47:18 -05003910 failure_mode, session.get());
Adam Langley4c341d02017-03-08 19:33:21 -08003911 switch (failure_mode) {
3912 case ssl_test_ticket_aead_ok:
3913 ASSERT_TRUE(client);
3914 EXPECT_TRUE(SSL_session_reused(client.get()));
3915 EXPECT_TRUE(SSL_session_reused(server.get()));
3916 break;
3917 case ssl_test_ticket_aead_seal_fail:
3918 abort();
3919 break;
3920 case ssl_test_ticket_aead_open_hard_fail:
3921 EXPECT_FALSE(client);
3922 break;
3923 case ssl_test_ticket_aead_open_soft_fail:
3924 ASSERT_TRUE(client);
3925 EXPECT_FALSE(SSL_session_reused(client.get()));
3926 EXPECT_FALSE(SSL_session_reused(server.get()));
3927 }
3928}
3929
David Benjaminc9775322018-04-13 16:39:12 -04003930std::string TicketAEADMethodParamToString(
3931 const testing::TestParamInfo<TicketAEADMethodParam> &params) {
3932 std::string ret = GetVersionName(std::get<0>(params.param));
3933 // GTest only allows alphanumeric characters and '_' in the parameter
3934 // string. Additionally filter out the 'v' to get "TLS13" over "TLSv13".
3935 for (auto it = ret.begin(); it != ret.end();) {
3936 if (*it == '.' || *it == 'v') {
3937 it = ret.erase(it);
3938 } else {
3939 ++it;
3940 }
3941 }
3942 char retry_count[256];
3943 snprintf(retry_count, sizeof(retry_count), "%d", std::get<1>(params.param));
3944 ret += "_";
3945 ret += retry_count;
3946 ret += "Retries_";
3947 switch (std::get<2>(params.param)) {
3948 case ssl_test_ticket_aead_ok:
3949 ret += "OK";
3950 break;
3951 case ssl_test_ticket_aead_seal_fail:
3952 ret += "SealFail";
3953 break;
3954 case ssl_test_ticket_aead_open_soft_fail:
3955 ret += "OpenSoftFail";
3956 break;
3957 case ssl_test_ticket_aead_open_hard_fail:
3958 ret += "OpenHardFail";
3959 break;
3960 }
3961 return ret;
3962}
3963
David Benjaminbe7006a2019-04-09 18:05:02 -05003964INSTANTIATE_TEST_SUITE_P(
Adam Langley4c341d02017-03-08 19:33:21 -08003965 TicketAEADMethodTests, TicketAEADMethodTest,
David Benjaminc9775322018-04-13 16:39:12 -04003966 testing::Combine(testing::Values(TLS1_2_VERSION, TLS1_3_VERSION),
3967 testing::Values(0, 1, 2),
3968 testing::Values(ssl_test_ticket_aead_ok,
3969 ssl_test_ticket_aead_seal_fail,
3970 ssl_test_ticket_aead_open_soft_fail,
3971 ssl_test_ticket_aead_open_hard_fail)),
3972 TicketAEADMethodParamToString);
Adam Langley4c341d02017-03-08 19:33:21 -08003973
David Benjaminca743582017-06-15 17:51:35 -04003974TEST(SSLTest, SelectNextProto) {
3975 uint8_t *result;
3976 uint8_t result_len;
3977
3978 // If there is an overlap, it should be returned.
3979 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3980 SSL_select_next_proto(&result, &result_len,
3981 (const uint8_t *)"\1a\2bb\3ccc", 9,
3982 (const uint8_t *)"\1x\1y\1a\1z", 8));
3983 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
3984
3985 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3986 SSL_select_next_proto(&result, &result_len,
3987 (const uint8_t *)"\1a\2bb\3ccc", 9,
3988 (const uint8_t *)"\1x\1y\2bb\1z", 9));
3989 EXPECT_EQ(Bytes("bb"), Bytes(result, result_len));
3990
3991 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3992 SSL_select_next_proto(&result, &result_len,
3993 (const uint8_t *)"\1a\2bb\3ccc", 9,
3994 (const uint8_t *)"\1x\1y\3ccc\1z", 10));
3995 EXPECT_EQ(Bytes("ccc"), Bytes(result, result_len));
3996
3997 // Peer preference order takes precedence over local.
3998 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3999 SSL_select_next_proto(&result, &result_len,
4000 (const uint8_t *)"\1a\2bb\3ccc", 9,
4001 (const uint8_t *)"\3ccc\2bb\1a", 9));
4002 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
4003
4004 // If there is no overlap, return the first local protocol.
4005 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
4006 SSL_select_next_proto(&result, &result_len,
4007 (const uint8_t *)"\1a\2bb\3ccc", 9,
4008 (const uint8_t *)"\1x\2yy\3zzz", 9));
4009 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
4010
4011 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
4012 SSL_select_next_proto(&result, &result_len, nullptr, 0,
4013 (const uint8_t *)"\1x\2yy\3zzz", 9));
4014 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
4015}
4016
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004017TEST(SSLTest, SealRecord) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004018 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004019 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004020 ASSERT_TRUE(client_ctx);
4021 ASSERT_TRUE(server_ctx);
4022
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004023 bssl::UniquePtr<SSL> client, server;
4024 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004025 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004026
4027 const std::vector<uint8_t> record = {1, 2, 3, 4, 5};
4028 std::vector<uint8_t> prefix(
4029 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004030 body(record.size()),
4031 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004032 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4033 bssl::MakeSpan(body), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004034 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004035
4036 std::vector<uint8_t> sealed;
4037 sealed.insert(sealed.end(), prefix.begin(), prefix.end());
4038 sealed.insert(sealed.end(), body.begin(), body.end());
4039 sealed.insert(sealed.end(), suffix.begin(), suffix.end());
4040 std::vector<uint8_t> sealed_copy = sealed;
4041
4042 bssl::Span<uint8_t> plaintext;
4043 size_t record_len;
4044 uint8_t alert = 255;
4045 EXPECT_EQ(bssl::OpenRecord(server.get(), &plaintext, &record_len, &alert,
4046 bssl::MakeSpan(sealed)),
4047 bssl::OpenRecordResult::kOK);
4048 EXPECT_EQ(record_len, sealed.size());
4049 EXPECT_EQ(plaintext, record);
4050 EXPECT_EQ(255, alert);
4051}
4052
4053TEST(SSLTest, SealRecordInPlace) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004054 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004055 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004056 ASSERT_TRUE(client_ctx);
4057 ASSERT_TRUE(server_ctx);
4058
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004059 bssl::UniquePtr<SSL> client, server;
4060 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004061 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004062
4063 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
4064 std::vector<uint8_t> record = plaintext;
4065 std::vector<uint8_t> prefix(
4066 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004067 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004068 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4069 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004070 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004071 record.insert(record.begin(), prefix.begin(), prefix.end());
4072 record.insert(record.end(), suffix.begin(), suffix.end());
4073
4074 bssl::Span<uint8_t> result;
4075 size_t record_len;
4076 uint8_t alert;
4077 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
4078 bssl::MakeSpan(record)),
4079 bssl::OpenRecordResult::kOK);
4080 EXPECT_EQ(record_len, record.size());
4081 EXPECT_EQ(plaintext, result);
4082}
4083
4084TEST(SSLTest, SealRecordTrailingData) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004085 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004086 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004087 ASSERT_TRUE(client_ctx);
4088 ASSERT_TRUE(server_ctx);
4089
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004090 bssl::UniquePtr<SSL> client, server;
4091 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004092 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004093
4094 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
4095 std::vector<uint8_t> record = plaintext;
4096 std::vector<uint8_t> prefix(
4097 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004098 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004099 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4100 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004101 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004102 record.insert(record.begin(), prefix.begin(), prefix.end());
4103 record.insert(record.end(), suffix.begin(), suffix.end());
4104 record.insert(record.end(), {5, 4, 3, 2, 1});
4105
4106 bssl::Span<uint8_t> result;
4107 size_t record_len;
4108 uint8_t alert;
4109 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
4110 bssl::MakeSpan(record)),
4111 bssl::OpenRecordResult::kOK);
4112 EXPECT_EQ(record_len, record.size() - 5);
4113 EXPECT_EQ(plaintext, result);
4114}
4115
4116TEST(SSLTest, SealRecordInvalidSpanSize) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08004117 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
David Benjamin9b2cdb72021-04-01 23:21:53 -04004118 server_ctx(CreateContextWithTestCertificate(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004119 ASSERT_TRUE(client_ctx);
4120 ASSERT_TRUE(server_ctx);
4121
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004122 bssl::UniquePtr<SSL> client, server;
4123 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04004124 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004125
4126 std::vector<uint8_t> record = {1, 2, 3, 4, 5};
4127 std::vector<uint8_t> prefix(
4128 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004129 body(record.size()),
4130 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004131
4132 auto expect_err = []() {
4133 int err = ERR_get_error();
4134 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
4135 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_BUFFER_TOO_SMALL);
4136 ERR_clear_error();
4137 };
4138 EXPECT_FALSE(bssl::SealRecord(
4139 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004140 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004141 expect_err();
4142 EXPECT_FALSE(bssl::SealRecord(
4143 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004144 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004145 expect_err();
4146
4147 EXPECT_FALSE(
4148 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4149 bssl::MakeSpan(record.data(), record.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004150 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004151 expect_err();
4152 EXPECT_FALSE(
4153 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
4154 bssl::MakeSpan(record.data(), record.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004155 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004156 expect_err();
4157
4158 EXPECT_FALSE(bssl::SealRecord(
4159 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004160 bssl::MakeSpan(suffix.data(), suffix.size() - 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004161 expect_err();
4162 EXPECT_FALSE(bssl::SealRecord(
4163 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07004164 bssl::MakeSpan(suffix.data(), suffix.size() + 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07004165 expect_err();
4166}
4167
David Benjamin617b8182017-08-29 15:33:10 -04004168// The client should gracefully handle no suitable ciphers being enabled.
4169TEST(SSLTest, NoCiphersAvailable) {
4170 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4171 ASSERT_TRUE(ctx);
4172
4173 // Configure |client_ctx| with a cipher list that does not intersect with its
4174 // version configuration.
4175 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
4176 ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
4177 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
4178
4179 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
4180 ASSERT_TRUE(ssl);
4181 SSL_set_connect_state(ssl.get());
4182
4183 UniquePtr<BIO> rbio(BIO_new(BIO_s_mem())), wbio(BIO_new(BIO_s_mem()));
4184 ASSERT_TRUE(rbio);
4185 ASSERT_TRUE(wbio);
4186 SSL_set0_rbio(ssl.get(), rbio.release());
4187 SSL_set0_wbio(ssl.get(), wbio.release());
4188
4189 int ret = SSL_do_handshake(ssl.get());
4190 EXPECT_EQ(-1, ret);
4191 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), ret));
4192 uint32_t err = ERR_get_error();
4193 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
4194 EXPECT_EQ(SSL_R_NO_CIPHERS_AVAILABLE, ERR_GET_REASON(err));
4195}
4196
David Benjamina4bafd32017-10-03 15:06:29 -04004197TEST_P(SSLVersionTest, SessionVersion) {
4198 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4199 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4200
4201 bssl::UniquePtr<SSL_SESSION> session =
4202 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4203 ASSERT_TRUE(session);
4204 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
4205
4206 // Sessions in TLS 1.3 and later should be single-use.
4207 EXPECT_EQ(version() == TLS1_3_VERSION,
4208 !!SSL_SESSION_should_be_single_use(session.get()));
4209
4210 // Making fake sessions for testing works.
4211 session.reset(SSL_SESSION_new(client_ctx_.get()));
4212 ASSERT_TRUE(session);
4213 ASSERT_TRUE(SSL_SESSION_set_protocol_version(session.get(), version()));
4214 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
4215}
4216
David Benjaminfdb7a352017-10-12 17:34:18 -04004217TEST_P(SSLVersionTest, SSLPending) {
4218 UniquePtr<SSL> ssl(SSL_new(client_ctx_.get()));
4219 ASSERT_TRUE(ssl);
4220 EXPECT_EQ(0, SSL_pending(ssl.get()));
4221
4222 ASSERT_TRUE(Connect());
4223 EXPECT_EQ(0, SSL_pending(client_.get()));
4224
4225 ASSERT_EQ(5, SSL_write(server_.get(), "hello", 5));
4226 ASSERT_EQ(5, SSL_write(server_.get(), "world", 5));
4227 EXPECT_EQ(0, SSL_pending(client_.get()));
4228
4229 char buf[10];
4230 ASSERT_EQ(1, SSL_peek(client_.get(), buf, 1));
4231 EXPECT_EQ(5, SSL_pending(client_.get()));
4232
4233 ASSERT_EQ(1, SSL_read(client_.get(), buf, 1));
4234 EXPECT_EQ(4, SSL_pending(client_.get()));
4235
4236 ASSERT_EQ(4, SSL_read(client_.get(), buf, 10));
4237 EXPECT_EQ(0, SSL_pending(client_.get()));
4238
4239 ASSERT_EQ(2, SSL_read(client_.get(), buf, 2));
4240 EXPECT_EQ(3, SSL_pending(client_.get()));
4241}
4242
David Benjamina031b612017-10-11 20:48:25 -04004243// Test that post-handshake tickets consumed by |SSL_shutdown| are ignored.
4244TEST(SSLTest, ShutdownIgnoresTickets) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04004245 bssl::UniquePtr<SSL_CTX> ctx(CreateContextWithTestCertificate(TLS_method()));
David Benjamina031b612017-10-11 20:48:25 -04004246 ASSERT_TRUE(ctx);
4247 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_3_VERSION));
4248 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
4249
David Benjamina031b612017-10-11 20:48:25 -04004250 SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_BOTH);
4251
4252 bssl::UniquePtr<SSL> client, server;
4253 ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
4254
4255 SSL_CTX_sess_set_new_cb(ctx.get(), [](SSL *ssl, SSL_SESSION *session) -> int {
4256 ADD_FAILURE() << "New session callback called during SSL_shutdown";
4257 return 0;
4258 });
4259
4260 // Send close_notify.
4261 EXPECT_EQ(0, SSL_shutdown(server.get()));
4262 EXPECT_EQ(0, SSL_shutdown(client.get()));
4263
4264 // Receive close_notify.
4265 EXPECT_EQ(1, SSL_shutdown(server.get()));
4266 EXPECT_EQ(1, SSL_shutdown(client.get()));
4267}
4268
David Benjamin6cc352e2017-11-02 17:21:39 -04004269TEST(SSLTest, SignatureAlgorithmProperties) {
4270 EXPECT_EQ(EVP_PKEY_NONE, SSL_get_signature_algorithm_key_type(0x1234));
4271 EXPECT_EQ(nullptr, SSL_get_signature_algorithm_digest(0x1234));
4272 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(0x1234));
4273
4274 EXPECT_EQ(EVP_PKEY_RSA,
4275 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4276 EXPECT_EQ(EVP_md5_sha1(),
4277 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4278 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4279
4280 EXPECT_EQ(EVP_PKEY_EC, SSL_get_signature_algorithm_key_type(
4281 SSL_SIGN_ECDSA_SECP256R1_SHA256));
4282 EXPECT_EQ(EVP_sha256(), SSL_get_signature_algorithm_digest(
4283 SSL_SIGN_ECDSA_SECP256R1_SHA256));
4284 EXPECT_FALSE(
4285 SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_ECDSA_SECP256R1_SHA256));
4286
4287 EXPECT_EQ(EVP_PKEY_RSA,
David Benjamin6879e192018-04-13 16:01:02 -04004288 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04004289 EXPECT_EQ(EVP_sha384(),
David Benjamin6879e192018-04-13 16:01:02 -04004290 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PSS_RSAE_SHA384));
4291 EXPECT_TRUE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04004292}
4293
Adam Langley85967952018-07-03 08:04:58 -07004294static int XORCompressFunc(SSL *ssl, CBB *out, const uint8_t *in,
4295 size_t in_len) {
4296 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07004297 if (!CBB_add_u8(out, in[i] ^ 0x55)) {
Adam Langley85967952018-07-03 08:04:58 -07004298 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07004299 }
4300 }
4301
4302 SSL_set_app_data(ssl, XORCompressFunc);
4303
Adam Langley85967952018-07-03 08:04:58 -07004304 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07004305}
4306
Adam Langley85967952018-07-03 08:04:58 -07004307static int XORDecompressFunc(SSL *ssl, CRYPTO_BUFFER **out,
4308 size_t uncompressed_len, const uint8_t *in,
4309 size_t in_len) {
4310 if (in_len != uncompressed_len) {
4311 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07004312 }
4313
4314 uint8_t *data;
Adam Langley85967952018-07-03 08:04:58 -07004315 *out = CRYPTO_BUFFER_alloc(&data, uncompressed_len);
4316 if (*out == nullptr) {
4317 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07004318 }
4319
Adam Langley85967952018-07-03 08:04:58 -07004320 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07004321 data[i] = in[i] ^ 0x55;
4322 }
4323
4324 SSL_set_app_data(ssl, XORDecompressFunc);
4325
Adam Langley85967952018-07-03 08:04:58 -07004326 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07004327}
4328
4329TEST(SSLTest, CertCompression) {
4330 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04004331 bssl::UniquePtr<SSL_CTX> server_ctx(
4332 CreateContextWithTestCertificate(TLS_method()));
Adam Langley0080d832018-06-07 16:39:49 -07004333 ASSERT_TRUE(client_ctx);
4334 ASSERT_TRUE(server_ctx);
4335
Adam Langley0080d832018-06-07 16:39:49 -07004336 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
4337 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
4338 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
4339 client_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
4340 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
4341 server_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
4342
4343 bssl::UniquePtr<SSL> client, server;
4344 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4345 server_ctx.get()));
4346
4347 EXPECT_TRUE(SSL_get_app_data(client.get()) == XORDecompressFunc);
4348 EXPECT_TRUE(SSL_get_app_data(server.get()) == XORCompressFunc);
4349}
4350
Adam Langleyddb57cf2018-01-26 09:17:53 -08004351void MoveBIOs(SSL *dest, SSL *src) {
4352 BIO *rbio = SSL_get_rbio(src);
4353 BIO_up_ref(rbio);
4354 SSL_set0_rbio(dest, rbio);
4355
4356 BIO *wbio = SSL_get_wbio(src);
4357 BIO_up_ref(wbio);
4358 SSL_set0_wbio(dest, wbio);
4359
4360 SSL_set0_rbio(src, nullptr);
4361 SSL_set0_wbio(src, nullptr);
4362}
4363
4364TEST(SSLTest, Handoff) {
4365 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4366 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04004367 bssl::UniquePtr<SSL_CTX> handshaker_ctx(
4368 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004369 ASSERT_TRUE(client_ctx);
4370 ASSERT_TRUE(server_ctx);
4371 ASSERT_TRUE(handshaker_ctx);
4372
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004373 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_CLIENT);
4374 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langleyddb57cf2018-01-26 09:17:53 -08004375 SSL_CTX_set_handoff_mode(server_ctx.get(), 1);
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004376 uint8_t keys[48];
David Benjamin243b5cc2019-12-04 11:23:50 -05004377 SSL_CTX_get_tlsext_ticket_keys(server_ctx.get(), &keys, sizeof(keys));
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004378 SSL_CTX_set_tlsext_ticket_keys(handshaker_ctx.get(), &keys, sizeof(keys));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004379
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004380 for (bool early_data : {false, true}) {
4381 SCOPED_TRACE(early_data);
4382 for (bool is_resume : {false, true}) {
4383 SCOPED_TRACE(is_resume);
4384 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04004385 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
4386 server_ctx.get()));
4387 SSL_set_early_data_enabled(client.get(), early_data);
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004388 if (is_resume) {
4389 ASSERT_TRUE(g_last_session);
David Benjamin9b2cdb72021-04-01 23:21:53 -04004390 SSL_set_session(client.get(), g_last_session.get());
4391 if (early_data) {
4392 EXPECT_GT(g_last_session->ticket_max_early_data, 0u);
4393 }
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004394 }
David Benjamin9b2cdb72021-04-01 23:21:53 -04004395
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004396
4397 int client_ret = SSL_do_handshake(client.get());
4398 int client_err = SSL_get_error(client.get(), client_ret);
4399
4400 uint8_t byte_written;
David Benjamin9b2cdb72021-04-01 23:21:53 -04004401 if (early_data && is_resume) {
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004402 ASSERT_EQ(client_err, 0);
4403 EXPECT_TRUE(SSL_in_early_data(client.get()));
4404 // Attempt to write early data.
4405 byte_written = 43;
4406 EXPECT_EQ(SSL_write(client.get(), &byte_written, 1), 1);
4407 } else {
4408 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4409 }
4410
4411 int server_ret = SSL_do_handshake(server.get());
4412 int server_err = SSL_get_error(server.get(), server_ret);
4413 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
4414
4415 ScopedCBB cbb;
4416 Array<uint8_t> handoff;
4417 SSL_CLIENT_HELLO hello;
4418 ASSERT_TRUE(CBB_init(cbb.get(), 256));
4419 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
4420 ASSERT_TRUE(CBBFinishArray(cbb.get(), &handoff));
4421
4422 bssl::UniquePtr<SSL> handshaker(SSL_new(handshaker_ctx.get()));
4423 // Note split handshakes determines 0-RTT support, for both the current
4424 // handshake and newly-issued tickets, entirely by |handshaker|. There is
4425 // no need to call |SSL_set_early_data_enabled| on |server|.
4426 SSL_set_early_data_enabled(handshaker.get(), 1);
4427 ASSERT_TRUE(SSL_apply_handoff(handshaker.get(), handoff));
4428
4429 MoveBIOs(handshaker.get(), server.get());
4430
4431 int handshake_ret = SSL_do_handshake(handshaker.get());
4432 int handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
4433 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
4434
4435 // Double-check that additional calls to |SSL_do_handshake| continue
Adam Langley472d91c2020-02-18 12:12:35 -08004436 // to get |SSL_ERROR_HANDBACK|.
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004437 handshake_ret = SSL_do_handshake(handshaker.get());
4438 handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
4439 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
4440
4441 ScopedCBB cbb_handback;
4442 Array<uint8_t> handback;
4443 ASSERT_TRUE(CBB_init(cbb_handback.get(), 1024));
4444 ASSERT_TRUE(SSL_serialize_handback(handshaker.get(), cbb_handback.get()));
4445 ASSERT_TRUE(CBBFinishArray(cbb_handback.get(), &handback));
4446
4447 bssl::UniquePtr<SSL> server2(SSL_new(server_ctx.get()));
4448 ASSERT_TRUE(SSL_apply_handback(server2.get(), handback));
4449
4450 MoveBIOs(server2.get(), handshaker.get());
4451 ASSERT_TRUE(CompleteHandshakes(client.get(), server2.get()));
4452 EXPECT_EQ(is_resume, SSL_session_reused(client.get()));
4453
David Benjamin9b2cdb72021-04-01 23:21:53 -04004454 if (early_data && is_resume) {
Matthew Braithwaite4f3e8212020-01-08 16:56:48 -08004455 // In this case, one byte of early data has already been written above.
4456 EXPECT_TRUE(SSL_early_data_accepted(client.get()));
4457 } else {
4458 byte_written = 42;
4459 EXPECT_EQ(SSL_write(client.get(), &byte_written, 1), 1);
4460 }
4461 uint8_t byte;
4462 EXPECT_EQ(SSL_read(server2.get(), &byte, 1), 1);
4463 EXPECT_EQ(byte_written, byte);
4464
4465 byte = 44;
4466 EXPECT_EQ(SSL_write(server2.get(), &byte, 1), 1);
4467 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
4468 EXPECT_EQ(44, byte);
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004469 }
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004470 }
Adam Langleyddb57cf2018-01-26 09:17:53 -08004471}
4472
4473TEST(SSLTest, HandoffDeclined) {
4474 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04004475 bssl::UniquePtr<SSL_CTX> server_ctx(
4476 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004477 ASSERT_TRUE(client_ctx);
4478 ASSERT_TRUE(server_ctx);
4479
4480 SSL_CTX_set_handoff_mode(server_ctx.get(), 1);
4481 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
4482
Adam Langleyddb57cf2018-01-26 09:17:53 -08004483 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04004484 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
4485 server_ctx.get()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004486
4487 int client_ret = SSL_do_handshake(client.get());
4488 int client_err = SSL_get_error(client.get(), client_ret);
4489 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4490
4491 int server_ret = SSL_do_handshake(server.get());
4492 int server_err = SSL_get_error(server.get(), server_ret);
4493 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
4494
4495 ScopedCBB cbb;
Adam Langleyc9827e02019-04-12 14:46:50 -07004496 SSL_CLIENT_HELLO hello;
Adam Langleyddb57cf2018-01-26 09:17:53 -08004497 ASSERT_TRUE(CBB_init(cbb.get(), 256));
Adam Langleyc9827e02019-04-12 14:46:50 -07004498 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004499
4500 ASSERT_TRUE(SSL_decline_handoff(server.get()));
4501
4502 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
4503
4504 uint8_t byte = 42;
4505 EXPECT_EQ(SSL_write(client.get(), &byte, 1), 1);
4506 EXPECT_EQ(SSL_read(server.get(), &byte, 1), 1);
4507 EXPECT_EQ(42, byte);
4508
4509 byte = 43;
4510 EXPECT_EQ(SSL_write(server.get(), &byte, 1), 1);
4511 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
4512 EXPECT_EQ(43, byte);
4513}
4514
Adam Langley826ce152018-08-03 10:31:21 -07004515static std::string SigAlgsToString(Span<const uint16_t> sigalgs) {
4516 std::string ret = "{";
4517
4518 for (uint16_t v : sigalgs) {
4519 if (ret.size() > 1) {
4520 ret += ", ";
4521 }
4522
4523 char buf[8];
4524 snprintf(buf, sizeof(buf) - 1, "0x%02x", v);
4525 buf[sizeof(buf)-1] = 0;
4526 ret += std::string(buf);
4527 }
4528
4529 ret += "}";
4530 return ret;
4531}
4532
4533void ExpectSigAlgsEqual(Span<const uint16_t> expected,
4534 Span<const uint16_t> actual) {
4535 bool matches = false;
4536 if (expected.size() == actual.size()) {
4537 matches = true;
4538
4539 for (size_t i = 0; i < expected.size(); i++) {
4540 if (expected[i] != actual[i]) {
4541 matches = false;
4542 break;
4543 }
4544 }
4545 }
4546
4547 if (!matches) {
4548 ADD_FAILURE() << "expected: " << SigAlgsToString(expected)
4549 << " got: " << SigAlgsToString(actual);
4550 }
4551}
4552
4553TEST(SSLTest, SigAlgs) {
4554 static const struct {
4555 std::vector<int> input;
4556 bool ok;
4557 std::vector<uint16_t> expected;
4558 } kTests[] = {
4559 {{}, true, {}},
4560 {{1}, false, {}},
4561 {{1, 2, 3}, false, {}},
4562 {{NID_sha256, EVP_PKEY_ED25519}, false, {}},
4563 {{NID_sha256, EVP_PKEY_RSA, NID_sha256, EVP_PKEY_RSA}, false, {}},
4564
4565 {{NID_sha256, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA256}},
4566 {{NID_sha512, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA512}},
4567 {{NID_sha256, EVP_PKEY_RSA_PSS}, true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4568 {{NID_undef, EVP_PKEY_ED25519}, true, {SSL_SIGN_ED25519}},
4569 {{NID_undef, EVP_PKEY_ED25519, NID_sha384, EVP_PKEY_EC},
4570 true,
4571 {SSL_SIGN_ED25519, SSL_SIGN_ECDSA_SECP384R1_SHA384}},
4572 };
4573
4574 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4575
4576 unsigned n = 1;
4577 for (const auto &test : kTests) {
4578 SCOPED_TRACE(n++);
4579
4580 const bool ok =
4581 SSL_CTX_set1_sigalgs(ctx.get(), test.input.data(), test.input.size());
4582 EXPECT_EQ(ok, test.ok);
4583
4584 if (!ok) {
4585 ERR_clear_error();
4586 }
4587
4588 if (!test.ok) {
4589 continue;
4590 }
4591
4592 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
4593 }
4594}
4595
4596TEST(SSLTest, SigAlgsList) {
4597 static const struct {
4598 const char *input;
4599 bool ok;
4600 std::vector<uint16_t> expected;
4601 } kTests[] = {
4602 {"", false, {}},
4603 {":", false, {}},
4604 {"+", false, {}},
4605 {"RSA", false, {}},
4606 {"RSA+", false, {}},
4607 {"RSA+SHA256:", false, {}},
4608 {":RSA+SHA256:", false, {}},
4609 {":RSA+SHA256+:", false, {}},
4610 {"!", false, {}},
4611 {"\x01", false, {}},
4612 {"RSA+SHA256:RSA+SHA384:RSA+SHA256", false, {}},
4613 {"RSA-PSS+SHA256:rsa_pss_rsae_sha256", false, {}},
4614
4615 {"RSA+SHA256", true, {SSL_SIGN_RSA_PKCS1_SHA256}},
4616 {"RSA+SHA256:ed25519",
4617 true,
4618 {SSL_SIGN_RSA_PKCS1_SHA256, SSL_SIGN_ED25519}},
4619 {"ECDSA+SHA256:RSA+SHA512",
4620 true,
4621 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PKCS1_SHA512}},
4622 {"ecdsa_secp256r1_sha256:rsa_pss_rsae_sha256",
4623 true,
4624 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4625 {"RSA-PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4626 {"PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4627 };
4628
4629 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4630
4631 unsigned n = 1;
4632 for (const auto &test : kTests) {
4633 SCOPED_TRACE(n++);
4634
4635 const bool ok = SSL_CTX_set1_sigalgs_list(ctx.get(), test.input);
4636 EXPECT_EQ(ok, test.ok);
4637
4638 if (!ok) {
4639 if (test.ok) {
4640 ERR_print_errors_fp(stderr);
4641 }
4642 ERR_clear_error();
4643 }
4644
4645 if (!test.ok) {
4646 continue;
4647 }
4648
4649 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
4650 }
4651}
4652
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004653TEST(SSLTest, ApplyHandoffRemovesUnsupportedCiphers) {
4654 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4655 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
4656
4657 // handoff is a handoff message that has been artificially modified to pretend
4658 // that only cipher 0x0A is supported. When it is applied to |server|, all
4659 // ciphers but that one should be removed.
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004660 //
4661 // To make a new one of these, try sticking this in the |Handoff| test above:
4662 //
4663 // hexdump(stderr, "", handoff.data(), handoff.size());
4664 // sed -e 's/\(..\)/0x\1, /g'
4665 //
4666 // and modify serialize_features() to emit only cipher 0x0A.
4667
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004668 uint8_t handoff[] = {
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004669 0x30, 0x81, 0x9a, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
4670 0x00, 0x00, 0x7e, 0x03, 0x03, 0x30, 0x8e, 0x8f, 0x79, 0xd2, 0x87, 0x39,
4671 0xc2, 0x23, 0x23, 0x13, 0xca, 0x3c, 0x80, 0x44, 0xfd, 0x80, 0x83, 0x62,
4672 0x3c, 0xcc, 0xf8, 0x76, 0xd3, 0x62, 0xbb, 0x54, 0xe3, 0xc4, 0x39, 0x24,
4673 0xa5, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004674 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
4675 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004676 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
4677 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
4678 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
4679 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
4680 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x02, 0x00,
4681 0x0a, 0x04, 0x0a, 0x00, 0x15, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00,
4682 0x1d,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004683 };
4684
4685 EXPECT_EQ(20u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
4686 ASSERT_TRUE(
4687 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
4688 EXPECT_EQ(1u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
4689}
4690
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004691TEST(SSLTest, ApplyHandoffRemovesUnsupportedCurves) {
4692 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4693 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
4694
4695 // handoff is a handoff message that has been artificially modified to pretend
4696 // that only one curve is supported. When it is applied to |server|, all
4697 // curves but that one should be removed.
4698 //
4699 // See |ApplyHandoffRemovesUnsupportedCiphers| for how to make a new one of
4700 // these.
4701 uint8_t handoff[] = {
4702 0x30, 0x81, 0xc0, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
4703 0x00, 0x00, 0x7e, 0x03, 0x03, 0x98, 0x30, 0xce, 0xd9, 0xb0, 0xdf, 0x5f,
4704 0x82, 0x05, 0x4a, 0x43, 0x67, 0x7e, 0xdb, 0x6a, 0x4f, 0x21, 0x18, 0x4e,
4705 0x0d, 0x94, 0x63, 0x18, 0x8b, 0x54, 0x89, 0xdb, 0x8b, 0x1d, 0x84, 0xbc,
4706 0x09, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
4707 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
4708 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
4709 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
4710 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
4711 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
4712 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
4713 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x30, 0x00,
4714 0x02, 0x00, 0x0a, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x8c, 0x00, 0x8d, 0x00,
4715 0x9c, 0x00, 0x9d, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xc0, 0x09, 0xc0,
4716 0x0a, 0xc0, 0x13, 0xc0, 0x14, 0xc0, 0x2b, 0xc0, 0x2c, 0xc0, 0x2f, 0xc0,
4717 0x30, 0xc0, 0x35, 0xc0, 0x36, 0xcc, 0xa8, 0xcc, 0xa9, 0xcc, 0xac, 0x04,
4718 0x02, 0x00, 0x17,
4719 };
4720
4721 // The zero length means that the default list of groups is used.
4722 EXPECT_EQ(0u, server->config->supported_group_list.size());
4723 ASSERT_TRUE(
4724 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
4725 EXPECT_EQ(1u, server->config->supported_group_list.size());
4726}
4727
Adam Langleyba9ad662018-12-17 13:59:38 -08004728TEST(SSLTest, ZeroSizedWiteFlushesHandshakeMessages) {
4729 // If there are pending handshake mesages, an |SSL_write| of zero bytes should
4730 // flush them.
David Benjamin9b2cdb72021-04-01 23:21:53 -04004731 bssl::UniquePtr<SSL_CTX> server_ctx(
4732 CreateContextWithTestCertificate(TLS_method()));
Adam Langleyba9ad662018-12-17 13:59:38 -08004733 EXPECT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
4734 EXPECT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
Adam Langleyba9ad662018-12-17 13:59:38 -08004735
4736 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4737 EXPECT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
4738 EXPECT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
4739
4740 bssl::UniquePtr<SSL> client, server;
4741 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4742 server_ctx.get()));
4743
4744 BIO *client_wbio = SSL_get_wbio(client.get());
4745 EXPECT_EQ(0u, BIO_wpending(client_wbio));
4746 EXPECT_TRUE(SSL_key_update(client.get(), SSL_KEY_UPDATE_NOT_REQUESTED));
4747 EXPECT_EQ(0u, BIO_wpending(client_wbio));
4748 EXPECT_EQ(0, SSL_write(client.get(), nullptr, 0));
4749 EXPECT_NE(0u, BIO_wpending(client_wbio));
4750}
4751
David Benjamin5869eb32018-07-17 00:59:45 -04004752TEST_P(SSLVersionTest, VerifyBeforeCertRequest) {
4753 // Configure the server to request client certificates.
4754 SSL_CTX_set_custom_verify(
4755 server_ctx_.get(), SSL_VERIFY_PEER,
4756 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
4757
4758 // Configure the client to reject the server certificate.
4759 SSL_CTX_set_custom_verify(
4760 client_ctx_.get(), SSL_VERIFY_PEER,
4761 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_invalid; });
4762
4763 // cert_cb should not be called. Verification should fail first.
4764 SSL_CTX_set_cert_cb(client_ctx_.get(),
4765 [](SSL *ssl, void *arg) {
4766 ADD_FAILURE() << "cert_cb unexpectedly called";
4767 return 0;
4768 },
4769 nullptr);
4770
4771 bssl::UniquePtr<SSL> client, server;
4772 EXPECT_FALSE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
4773 server_ctx_.get()));
4774}
4775
David Benjamin492c9aa2018-08-31 16:35:22 -05004776// Test that ticket-based sessions on the client get fake session IDs.
4777TEST_P(SSLVersionTest, FakeIDsForTickets) {
4778 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4779 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4780
4781 bssl::UniquePtr<SSL_SESSION> session =
4782 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4783 ASSERT_TRUE(session);
4784
4785 EXPECT_TRUE(SSL_SESSION_has_ticket(session.get()));
4786 unsigned session_id_length;
4787 SSL_SESSION_get_id(session.get(), &session_id_length);
4788 EXPECT_NE(session_id_length, 0u);
4789}
4790
David Benjamin6c04bd12018-07-19 18:13:09 -04004791// These tests test multi-threaded behavior. They are intended to run with
4792// ThreadSanitizer.
David Benjamin5b33eff2018-09-22 16:52:48 -07004793#if defined(OPENSSL_THREADS)
David Benjamin6c04bd12018-07-19 18:13:09 -04004794TEST_P(SSLVersionTest, SessionCacheThreads) {
4795 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
4796 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4797 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4798
4799 if (version() == TLS1_3_VERSION) {
4800 // Our TLS 1.3 implementation does not support stateful resumption.
4801 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
4802 return;
4803 }
4804
4805 // Establish two client sessions to test with.
4806 bssl::UniquePtr<SSL_SESSION> session1 =
4807 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4808 ASSERT_TRUE(session1);
4809 bssl::UniquePtr<SSL_SESSION> session2 =
4810 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4811 ASSERT_TRUE(session2);
4812
4813 auto connect_with_session = [&](SSL_SESSION *session) {
4814 ClientConfig config;
4815 config.session = session;
4816 UniquePtr<SSL> client, server;
4817 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
4818 server_ctx_.get(), config));
4819 };
4820
4821 // Resume sessions in parallel with establishing new ones.
4822 {
4823 std::vector<std::thread> threads;
4824 threads.emplace_back([&] { connect_with_session(nullptr); });
4825 threads.emplace_back([&] { connect_with_session(nullptr); });
4826 threads.emplace_back([&] { connect_with_session(session1.get()); });
4827 threads.emplace_back([&] { connect_with_session(session1.get()); });
4828 threads.emplace_back([&] { connect_with_session(session2.get()); });
4829 threads.emplace_back([&] { connect_with_session(session2.get()); });
4830 for (auto &thread : threads) {
4831 thread.join();
4832 }
4833 }
4834
4835 // Hit the maximum session cache size across multiple threads
4836 size_t limit = SSL_CTX_sess_number(server_ctx_.get()) + 2;
4837 SSL_CTX_sess_set_cache_size(server_ctx_.get(), limit);
4838 {
4839 std::vector<std::thread> threads;
4840 for (int i = 0; i < 4; i++) {
4841 threads.emplace_back([&]() {
4842 connect_with_session(nullptr);
4843 EXPECT_LE(SSL_CTX_sess_number(server_ctx_.get()), limit);
4844 });
4845 }
4846 for (auto &thread : threads) {
4847 thread.join();
4848 }
4849 EXPECT_EQ(SSL_CTX_sess_number(server_ctx_.get()), limit);
4850 }
4851}
4852
4853TEST_P(SSLVersionTest, SessionTicketThreads) {
4854 for (bool renew_ticket : {false, true}) {
4855 SCOPED_TRACE(renew_ticket);
4856 ResetContexts();
4857 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4858 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4859 if (renew_ticket) {
4860 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
4861 }
4862
4863 // Establish two client sessions to test with.
4864 bssl::UniquePtr<SSL_SESSION> session1 =
4865 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4866 ASSERT_TRUE(session1);
4867 bssl::UniquePtr<SSL_SESSION> session2 =
4868 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4869 ASSERT_TRUE(session2);
4870
4871 auto connect_with_session = [&](SSL_SESSION *session) {
4872 ClientConfig config;
4873 config.session = session;
4874 UniquePtr<SSL> client, server;
4875 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
4876 server_ctx_.get(), config));
4877 };
4878
4879 // Resume sessions in parallel with establishing new ones.
4880 {
4881 std::vector<std::thread> threads;
4882 threads.emplace_back([&] { connect_with_session(nullptr); });
4883 threads.emplace_back([&] { connect_with_session(nullptr); });
4884 threads.emplace_back([&] { connect_with_session(session1.get()); });
4885 threads.emplace_back([&] { connect_with_session(session1.get()); });
4886 threads.emplace_back([&] { connect_with_session(session2.get()); });
4887 threads.emplace_back([&] { connect_with_session(session2.get()); });
4888 for (auto &thread : threads) {
4889 thread.join();
4890 }
4891 }
4892 }
4893}
4894
4895// SSL_CTX_get0_certificate needs to lock internally. Test this works.
4896TEST(SSLTest, GetCertificateThreads) {
4897 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4898 ASSERT_TRUE(ctx);
4899 bssl::UniquePtr<X509> cert = GetTestCertificate();
4900 ASSERT_TRUE(cert);
4901 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
4902
4903 // Existing code expects |SSL_CTX_get0_certificate| to be callable from two
4904 // threads concurrently. It originally was an immutable operation. Now we
4905 // implement it with a thread-safe cache, so it is worth testing.
4906 X509 *cert2_thread;
4907 std::thread thread(
4908 [&] { cert2_thread = SSL_CTX_get0_certificate(ctx.get()); });
4909 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
4910 thread.join();
4911
4912 EXPECT_EQ(cert2, cert2_thread);
4913 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
4914}
David Benjamin4cce9552018-12-13 12:20:54 -06004915
4916// Functions which access properties on the negotiated session are thread-safe
4917// where needed. Prior to TLS 1.3, clients resuming sessions and servers
4918// performing stateful resumption will share an underlying SSL_SESSION object,
4919// potentially across threads.
4920TEST_P(SSLVersionTest, SessionPropertiesThreads) {
4921 if (version() == TLS1_3_VERSION) {
4922 // Our TLS 1.3 implementation does not support stateful resumption.
4923 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
4924 return;
4925 }
4926
4927 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
4928 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4929 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4930
4931 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
4932 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
4933
4934 // Configure mutual authentication, so we have more session state.
4935 SSL_CTX_set_custom_verify(
4936 client_ctx_.get(), SSL_VERIFY_PEER,
4937 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
4938 SSL_CTX_set_custom_verify(
4939 server_ctx_.get(), SSL_VERIFY_PEER,
4940 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
4941
4942 // Establish a client session to test with.
4943 bssl::UniquePtr<SSL_SESSION> session =
4944 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4945 ASSERT_TRUE(session);
4946
4947 // Resume with it twice.
4948 UniquePtr<SSL> ssls[4];
4949 ClientConfig config;
4950 config.session = session.get();
4951 ASSERT_TRUE(ConnectClientAndServer(&ssls[0], &ssls[1], client_ctx_.get(),
4952 server_ctx_.get(), config));
4953 ASSERT_TRUE(ConnectClientAndServer(&ssls[2], &ssls[3], client_ctx_.get(),
4954 server_ctx_.get(), config));
4955
4956 // Read properties in parallel.
4957 auto read_properties = [](const SSL *ssl) {
4958 EXPECT_TRUE(SSL_get_peer_cert_chain(ssl));
4959 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(ssl));
4960 EXPECT_TRUE(peer);
4961 EXPECT_TRUE(SSL_get_current_cipher(ssl));
4962 EXPECT_TRUE(SSL_get_curve_id(ssl));
4963 };
4964
4965 std::vector<std::thread> threads;
4966 for (const auto &ssl_ptr : ssls) {
4967 const SSL *ssl = ssl_ptr.get();
4968 threads.emplace_back([=] { read_properties(ssl); });
4969 }
4970 for (auto &thread : threads) {
4971 thread.join();
4972 }
4973}
David Benjamina486c6c2019-03-28 18:32:38 -05004974#endif // OPENSSL_THREADS
David Benjamin6c04bd12018-07-19 18:13:09 -04004975
Steven Valdezc8e0f902018-07-14 11:23:01 -04004976constexpr size_t kNumQUICLevels = 4;
4977static_assert(ssl_encryption_initial < kNumQUICLevels,
4978 "kNumQUICLevels is wrong");
4979static_assert(ssl_encryption_early_data < kNumQUICLevels,
4980 "kNumQUICLevels is wrong");
4981static_assert(ssl_encryption_handshake < kNumQUICLevels,
4982 "kNumQUICLevels is wrong");
4983static_assert(ssl_encryption_application < kNumQUICLevels,
4984 "kNumQUICLevels is wrong");
4985
David Benjamin1e859052020-02-09 16:04:58 -05004986const char *LevelToString(ssl_encryption_level_t level) {
4987 switch (level) {
4988 case ssl_encryption_initial:
4989 return "initial";
4990 case ssl_encryption_early_data:
4991 return "early data";
4992 case ssl_encryption_handshake:
4993 return "handshake";
4994 case ssl_encryption_application:
4995 return "application";
4996 }
4997 return "<unknown>";
4998}
4999
Steven Valdezc8e0f902018-07-14 11:23:01 -04005000class MockQUICTransport {
5001 public:
David Benjamind6343572019-08-15 17:29:02 -04005002 enum class Role { kClient, kServer };
5003
5004 explicit MockQUICTransport(Role role) : role_(role) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005005 // The caller is expected to configure initial secrets.
5006 levels_[ssl_encryption_initial].write_secret = {1};
5007 levels_[ssl_encryption_initial].read_secret = {1};
5008 }
5009
5010 void set_peer(MockQUICTransport *peer) { peer_ = peer; }
5011
5012 bool has_alert() const { return has_alert_; }
5013 ssl_encryption_level_t alert_level() const { return alert_level_; }
5014 uint8_t alert() const { return alert_; }
5015
5016 bool PeerSecretsMatch(ssl_encryption_level_t level) const {
5017 return levels_[level].write_secret == peer_->levels_[level].read_secret &&
Steven Valdez384d0ea2018-11-06 10:45:36 -05005018 levels_[level].read_secret == peer_->levels_[level].write_secret &&
5019 levels_[level].cipher == peer_->levels_[level].cipher;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005020 }
5021
David Benjamin1e859052020-02-09 16:04:58 -05005022 bool HasReadSecret(ssl_encryption_level_t level) const {
5023 return !levels_[level].read_secret.empty();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005024 }
5025
David Benjamin1e859052020-02-09 16:04:58 -05005026 bool HasWriteSecret(ssl_encryption_level_t level) const {
5027 return !levels_[level].write_secret.empty();
5028 }
5029
David Benjamin5298ef92020-03-13 12:17:30 -04005030 void AllowOutOfOrderWrites() { allow_out_of_order_writes_ = true; }
5031
David Benjamin1e859052020-02-09 16:04:58 -05005032 bool SetReadSecret(ssl_encryption_level_t level, const SSL_CIPHER *cipher,
5033 Span<const uint8_t> secret) {
5034 if (HasReadSecret(level)) {
5035 ADD_FAILURE() << LevelToString(level) << " read secret configured twice";
5036 return false;
5037 }
5038
5039 if (role_ == Role::kClient && level == ssl_encryption_early_data) {
5040 ADD_FAILURE() << "Unexpected early data read secret";
5041 return false;
5042 }
5043
5044 ssl_encryption_level_t ack_level =
5045 level == ssl_encryption_early_data ? ssl_encryption_application : level;
5046 if (!HasWriteSecret(ack_level)) {
5047 ADD_FAILURE() << LevelToString(level)
5048 << " read secret configured before ACK write secret";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005049 return false;
5050 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05005051
5052 if (cipher == nullptr) {
David Benjamin1e859052020-02-09 16:04:58 -05005053 ADD_FAILURE() << "Unexpected null cipher";
Steven Valdez384d0ea2018-11-06 10:45:36 -05005054 return false;
5055 }
5056
David Benjamin1e859052020-02-09 16:04:58 -05005057 if (level != ssl_encryption_early_data &&
5058 SSL_CIPHER_get_id(cipher) != levels_[level].cipher) {
5059 ADD_FAILURE() << "Cipher suite inconsistent";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005060 return false;
5061 }
David Benjamind6343572019-08-15 17:29:02 -04005062
David Benjamin1e859052020-02-09 16:04:58 -05005063 levels_[level].read_secret.assign(secret.begin(), secret.end());
5064 levels_[level].cipher = SSL_CIPHER_get_id(cipher);
5065 return true;
5066 }
5067
5068 bool SetWriteSecret(ssl_encryption_level_t level, const SSL_CIPHER *cipher,
5069 Span<const uint8_t> secret) {
5070 if (HasWriteSecret(level)) {
5071 ADD_FAILURE() << LevelToString(level) << " write secret configured twice";
David Benjamind6343572019-08-15 17:29:02 -04005072 return false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005073 }
David Benjamind6343572019-08-15 17:29:02 -04005074
David Benjamin1e859052020-02-09 16:04:58 -05005075 if (role_ == Role::kServer && level == ssl_encryption_early_data) {
5076 ADD_FAILURE() << "Unexpected early data write secret";
5077 return false;
5078 }
5079
5080 if (cipher == nullptr) {
5081 ADD_FAILURE() << "Unexpected null cipher";
5082 return false;
5083 }
5084
5085 levels_[level].write_secret.assign(secret.begin(), secret.end());
Steven Valdez384d0ea2018-11-06 10:45:36 -05005086 levels_[level].cipher = SSL_CIPHER_get_id(cipher);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005087 return true;
5088 }
5089
5090 bool WriteHandshakeData(ssl_encryption_level_t level,
5091 Span<const uint8_t> data) {
5092 if (levels_[level].write_secret.empty()) {
David Benjamin1e859052020-02-09 16:04:58 -05005093 ADD_FAILURE() << LevelToString(level)
5094 << " write secret not yet configured";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005095 return false;
5096 }
David Benjamin5298ef92020-03-13 12:17:30 -04005097
5098 // Although the levels are conceptually separate, BoringSSL finishes writing
5099 // data from a previous level before installing keys for the next level.
5100 if (!allow_out_of_order_writes_) {
5101 switch (level) {
5102 case ssl_encryption_early_data:
5103 ADD_FAILURE() << "unexpected handshake data at early data level";
5104 return false;
5105 case ssl_encryption_initial:
5106 if (!levels_[ssl_encryption_handshake].write_secret.empty()) {
5107 ADD_FAILURE()
5108 << LevelToString(level)
5109 << " handshake data written after handshake keys installed";
5110 return false;
5111 }
5112 OPENSSL_FALLTHROUGH;
5113 case ssl_encryption_handshake:
5114 if (!levels_[ssl_encryption_application].write_secret.empty()) {
5115 ADD_FAILURE()
5116 << LevelToString(level)
5117 << " handshake data written after application keys installed";
5118 return false;
5119 }
5120 OPENSSL_FALLTHROUGH;
5121 case ssl_encryption_application:
5122 break;
5123 }
5124 }
5125
Steven Valdezc8e0f902018-07-14 11:23:01 -04005126 levels_[level].write_data.insert(levels_[level].write_data.end(),
5127 data.begin(), data.end());
5128 return true;
5129 }
5130
5131 bool SendAlert(ssl_encryption_level_t level, uint8_t alert_value) {
5132 if (has_alert_) {
5133 ADD_FAILURE() << "duplicate alert sent";
5134 return false;
5135 }
5136
5137 if (levels_[level].write_secret.empty()) {
David Benjamin1e859052020-02-09 16:04:58 -05005138 ADD_FAILURE() << LevelToString(level)
5139 << " write secret not yet configured";
Steven Valdezc8e0f902018-07-14 11:23:01 -04005140 return false;
5141 }
5142
5143 has_alert_ = true;
5144 alert_level_ = level;
5145 alert_ = alert_value;
5146 return true;
5147 }
5148
5149 bool ReadHandshakeData(std::vector<uint8_t> *out,
5150 ssl_encryption_level_t level,
5151 size_t num = std::numeric_limits<size_t>::max()) {
5152 if (levels_[level].read_secret.empty()) {
David Benjamind6343572019-08-15 17:29:02 -04005153 ADD_FAILURE() << "data read before keys configured in level " << level;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005154 return false;
5155 }
5156 // The peer may not have configured any keys yet.
5157 if (peer_->levels_[level].write_secret.empty()) {
David Benjamind0b97942019-08-21 12:54:20 -04005158 out->clear();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005159 return true;
5160 }
5161 // Check the peer computed the same key.
5162 if (peer_->levels_[level].write_secret != levels_[level].read_secret) {
David Benjamind6343572019-08-15 17:29:02 -04005163 ADD_FAILURE() << "peer write key does not match read key in level "
5164 << level;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005165 return false;
5166 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05005167 if (peer_->levels_[level].cipher != levels_[level].cipher) {
David Benjamind6343572019-08-15 17:29:02 -04005168 ADD_FAILURE() << "peer cipher does not match in level " << level;
Steven Valdez384d0ea2018-11-06 10:45:36 -05005169 return false;
5170 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04005171 std::vector<uint8_t> *peer_data = &peer_->levels_[level].write_data;
5172 num = std::min(num, peer_data->size());
5173 out->assign(peer_data->begin(), peer_data->begin() + num);
5174 peer_data->erase(peer_data->begin(), peer_data->begin() + num);
5175 return true;
5176 }
5177
5178 private:
David Benjamind6343572019-08-15 17:29:02 -04005179 Role role_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005180 MockQUICTransport *peer_ = nullptr;
5181
David Benjamin5298ef92020-03-13 12:17:30 -04005182 bool allow_out_of_order_writes_ = false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005183 bool has_alert_ = false;
5184 ssl_encryption_level_t alert_level_ = ssl_encryption_initial;
5185 uint8_t alert_ = 0;
5186
5187 struct Level {
5188 std::vector<uint8_t> write_data;
5189 std::vector<uint8_t> write_secret;
5190 std::vector<uint8_t> read_secret;
Steven Valdez384d0ea2018-11-06 10:45:36 -05005191 uint32_t cipher = 0;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005192 };
5193 Level levels_[kNumQUICLevels];
5194};
5195
5196class MockQUICTransportPair {
5197 public:
David Benjamind6343572019-08-15 17:29:02 -04005198 MockQUICTransportPair()
5199 : client_(MockQUICTransport::Role::kClient),
5200 server_(MockQUICTransport::Role::kServer) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005201 client_.set_peer(&server_);
David Benjamind6343572019-08-15 17:29:02 -04005202 server_.set_peer(&client_);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005203 }
5204
5205 ~MockQUICTransportPair() {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005206 client_.set_peer(nullptr);
David Benjamind6343572019-08-15 17:29:02 -04005207 server_.set_peer(nullptr);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005208 }
5209
5210 MockQUICTransport *client() { return &client_; }
5211 MockQUICTransport *server() { return &server_; }
5212
5213 bool SecretsMatch(ssl_encryption_level_t level) const {
David Benjamin1e859052020-02-09 16:04:58 -05005214 // We only need to check |HasReadSecret| and |HasWriteSecret| on |client_|.
5215 // |PeerSecretsMatch| checks that |server_| is analogously configured.
5216 return client_.PeerSecretsMatch(level) &&
5217 client_.HasWriteSecret(level) &&
5218 (level == ssl_encryption_early_data || client_.HasReadSecret(level));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005219 }
5220
5221 private:
5222 MockQUICTransport client_;
5223 MockQUICTransport server_;
5224};
5225
5226class QUICMethodTest : public testing::Test {
5227 protected:
5228 void SetUp() override {
5229 client_ctx_.reset(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04005230 server_ctx_ = CreateContextWithTestCertificate(TLS_method());
Steven Valdezc8e0f902018-07-14 11:23:01 -04005231 ASSERT_TRUE(client_ctx_);
5232 ASSERT_TRUE(server_ctx_);
5233
Steven Valdezc8e0f902018-07-14 11:23:01 -04005234 SSL_CTX_set_min_proto_version(server_ctx_.get(), TLS1_3_VERSION);
5235 SSL_CTX_set_max_proto_version(server_ctx_.get(), TLS1_3_VERSION);
5236 SSL_CTX_set_min_proto_version(client_ctx_.get(), TLS1_3_VERSION);
5237 SSL_CTX_set_max_proto_version(client_ctx_.get(), TLS1_3_VERSION);
Nick Harper74161f42020-07-24 15:35:27 -07005238
5239 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
5240 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
5241 sizeof(kALPNProtos)),
5242 0);
5243 SSL_CTX_set_alpn_select_cb(
5244 server_ctx_.get(),
5245 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
5246 unsigned in_len, void *arg) -> int {
5247 return SSL_select_next_proto(
5248 const_cast<uint8_t **>(out), out_len, in, in_len,
5249 kALPNProtos, sizeof(kALPNProtos)) == OPENSSL_NPN_NEGOTIATED
5250 ? SSL_TLSEXT_ERR_OK
5251 : SSL_TLSEXT_ERR_NOACK;
5252 },
5253 nullptr);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005254 }
5255
5256 static MockQUICTransport *TransportFromSSL(const SSL *ssl) {
5257 return ex_data_.Get(ssl);
5258 }
5259
5260 static bool ProvideHandshakeData(
5261 SSL *ssl, size_t num = std::numeric_limits<size_t>::max()) {
5262 MockQUICTransport *transport = TransportFromSSL(ssl);
5263 ssl_encryption_level_t level = SSL_quic_read_level(ssl);
5264 std::vector<uint8_t> data;
5265 return transport->ReadHandshakeData(&data, level, num) &&
5266 SSL_provide_quic_data(ssl, level, data.data(), data.size());
5267 }
5268
David Benjamin5298ef92020-03-13 12:17:30 -04005269 void AllowOutOfOrderWrites() {
5270 allow_out_of_order_writes_ = true;
5271 }
5272
Steven Valdezc8e0f902018-07-14 11:23:01 -04005273 bool CreateClientAndServer() {
5274 client_.reset(SSL_new(client_ctx_.get()));
5275 server_.reset(SSL_new(server_ctx_.get()));
5276 if (!client_ || !server_) {
5277 return false;
5278 }
5279
5280 SSL_set_connect_state(client_.get());
5281 SSL_set_accept_state(server_.get());
5282
David Benjamind6343572019-08-15 17:29:02 -04005283 transport_.reset(new MockQUICTransportPair);
5284 ex_data_.Set(client_.get(), transport_->client());
5285 ex_data_.Set(server_.get(), transport_->server());
David Benjamin5298ef92020-03-13 12:17:30 -04005286 if (allow_out_of_order_writes_) {
5287 transport_->client()->AllowOutOfOrderWrites();
5288 transport_->server()->AllowOutOfOrderWrites();
5289 }
Nick Harper7c522992020-04-30 14:15:49 -07005290 static const uint8_t client_transport_params[] = {0};
5291 if (!SSL_set_quic_transport_params(client_.get(), client_transport_params,
5292 sizeof(client_transport_params)) ||
5293 !SSL_set_quic_transport_params(server_.get(),
5294 server_transport_params_.data(),
5295 server_transport_params_.size()) ||
5296 !SSL_set_quic_early_data_context(
5297 server_.get(), server_quic_early_data_context_.data(),
5298 server_quic_early_data_context_.size())) {
Nick Harper72cff812020-03-26 18:06:16 -07005299 return false;
5300 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04005301 return true;
5302 }
5303
Nick Harper72cff812020-03-26 18:06:16 -07005304 enum class ExpectedError {
5305 kNoError,
5306 kClientError,
5307 kServerError,
5308 };
5309
David Benjamind6343572019-08-15 17:29:02 -04005310 // CompleteHandshakesForQUIC runs |SSL_do_handshake| on |client_| and
5311 // |server_| until each completes once. It returns true on success and false
5312 // on failure.
5313 bool CompleteHandshakesForQUIC() {
Nick Harper72cff812020-03-26 18:06:16 -07005314 return RunQUICHandshakesAndExpectError(ExpectedError::kNoError);
5315 }
5316
5317 // Runs |SSL_do_handshake| on |client_| and |server_| until each completes
5318 // once. If |expect_client_error| is true, it will return true only if the
5319 // client handshake failed. Otherwise, it returns true if both handshakes
5320 // succeed and false otherwise.
5321 bool RunQUICHandshakesAndExpectError(ExpectedError expected_error) {
David Benjamind6343572019-08-15 17:29:02 -04005322 bool client_done = false, server_done = false;
5323 while (!client_done || !server_done) {
5324 if (!client_done) {
5325 if (!ProvideHandshakeData(client_.get())) {
5326 ADD_FAILURE() << "ProvideHandshakeData(client_) failed";
5327 return false;
5328 }
5329 int client_ret = SSL_do_handshake(client_.get());
David Benjamin2fb729d2020-02-20 17:37:33 -05005330 int client_err = SSL_get_error(client_.get(), client_ret);
David Benjamind6343572019-08-15 17:29:02 -04005331 if (client_ret == 1) {
5332 client_done = true;
David Benjamin2fb729d2020-02-20 17:37:33 -05005333 } else if (client_ret != -1 || client_err != SSL_ERROR_WANT_READ) {
Nick Harper72cff812020-03-26 18:06:16 -07005334 if (expected_error == ExpectedError::kClientError) {
5335 return true;
5336 }
David Benjamin2fb729d2020-02-20 17:37:33 -05005337 ADD_FAILURE() << "Unexpected client output: " << client_ret << " "
5338 << client_err;
5339 return false;
David Benjamind6343572019-08-15 17:29:02 -04005340 }
5341 }
5342
5343 if (!server_done) {
5344 if (!ProvideHandshakeData(server_.get())) {
5345 ADD_FAILURE() << "ProvideHandshakeData(server_) failed";
5346 return false;
5347 }
5348 int server_ret = SSL_do_handshake(server_.get());
David Benjamin2fb729d2020-02-20 17:37:33 -05005349 int server_err = SSL_get_error(server_.get(), server_ret);
David Benjamind6343572019-08-15 17:29:02 -04005350 if (server_ret == 1) {
5351 server_done = true;
David Benjamin2fb729d2020-02-20 17:37:33 -05005352 } else if (server_ret != -1 || server_err != SSL_ERROR_WANT_READ) {
Nick Harper72cff812020-03-26 18:06:16 -07005353 if (expected_error == ExpectedError::kServerError) {
5354 return true;
5355 }
David Benjamin2fb729d2020-02-20 17:37:33 -05005356 ADD_FAILURE() << "Unexpected server output: " << server_ret << " "
5357 << server_err;
5358 return false;
David Benjamind6343572019-08-15 17:29:02 -04005359 }
5360 }
5361 }
Nick Harper72cff812020-03-26 18:06:16 -07005362 return expected_error == ExpectedError::kNoError;
David Benjamind6343572019-08-15 17:29:02 -04005363 }
5364
5365 bssl::UniquePtr<SSL_SESSION> CreateClientSessionForQUIC() {
5366 g_last_session = nullptr;
5367 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
5368 if (!CreateClientAndServer() ||
5369 !CompleteHandshakesForQUIC()) {
5370 return nullptr;
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005371 }
5372
David Benjamind6343572019-08-15 17:29:02 -04005373 // The server sent NewSessionTicket messages in the handshake.
5374 if (!ProvideHandshakeData(client_.get()) ||
5375 !SSL_process_quic_post_handshake(client_.get())) {
5376 return nullptr;
5377 }
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005378
David Benjamind6343572019-08-15 17:29:02 -04005379 return std::move(g_last_session);
5380 }
5381
5382 void ExpectHandshakeSuccess() {
5383 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_application));
5384 EXPECT_EQ(ssl_encryption_application, SSL_quic_read_level(client_.get()));
5385 EXPECT_EQ(ssl_encryption_application, SSL_quic_write_level(client_.get()));
5386 EXPECT_EQ(ssl_encryption_application, SSL_quic_read_level(server_.get()));
5387 EXPECT_EQ(ssl_encryption_application, SSL_quic_write_level(server_.get()));
5388 EXPECT_FALSE(transport_->client()->has_alert());
5389 EXPECT_FALSE(transport_->server()->has_alert());
5390
5391 // SSL_do_handshake is now idempotent.
5392 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
5393 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005394 }
5395
David Benjamin1e859052020-02-09 16:04:58 -05005396 // Returns a default SSL_QUIC_METHOD. Individual methods may be overwritten by
5397 // the test.
5398 SSL_QUIC_METHOD DefaultQUICMethod() {
5399 return SSL_QUIC_METHOD{
5400 SetReadSecretCallback, SetWriteSecretCallback, AddHandshakeDataCallback,
5401 FlushFlightCallback, SendAlertCallback,
5402 };
5403 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04005404
David Benjamin1e859052020-02-09 16:04:58 -05005405 static int SetReadSecretCallback(SSL *ssl, ssl_encryption_level_t level,
5406 const SSL_CIPHER *cipher,
5407 const uint8_t *secret, size_t secret_len) {
5408 return TransportFromSSL(ssl)->SetReadSecret(
5409 level, cipher, MakeConstSpan(secret, secret_len));
5410 }
5411
5412 static int SetWriteSecretCallback(SSL *ssl, ssl_encryption_level_t level,
5413 const SSL_CIPHER *cipher,
5414 const uint8_t *secret, size_t secret_len) {
5415 return TransportFromSSL(ssl)->SetWriteSecret(
5416 level, cipher, MakeConstSpan(secret, secret_len));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005417 }
5418
David Benjamincc9d9352018-10-30 19:45:22 -05005419 static int AddHandshakeDataCallback(SSL *ssl,
5420 enum ssl_encryption_level_t level,
5421 const uint8_t *data, size_t len) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005422 EXPECT_EQ(level, SSL_quic_write_level(ssl));
5423 return TransportFromSSL(ssl)->WriteHandshakeData(level,
5424 MakeConstSpan(data, len));
5425 }
5426
5427 static int FlushFlightCallback(SSL *ssl) { return 1; }
5428
5429 static int SendAlertCallback(SSL *ssl, ssl_encryption_level_t level,
5430 uint8_t alert) {
5431 EXPECT_EQ(level, SSL_quic_write_level(ssl));
5432 return TransportFromSSL(ssl)->SendAlert(level, alert);
5433 }
5434
5435 bssl::UniquePtr<SSL_CTX> client_ctx_;
5436 bssl::UniquePtr<SSL_CTX> server_ctx_;
5437
5438 static UnownedSSLExData<MockQUICTransport> ex_data_;
David Benjamind6343572019-08-15 17:29:02 -04005439 std::unique_ptr<MockQUICTransportPair> transport_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005440
5441 bssl::UniquePtr<SSL> client_;
5442 bssl::UniquePtr<SSL> server_;
David Benjamin5298ef92020-03-13 12:17:30 -04005443
Nick Harper7c522992020-04-30 14:15:49 -07005444 std::vector<uint8_t> server_transport_params_ = {1};
5445 std::vector<uint8_t> server_quic_early_data_context_ = {2};
5446
David Benjamin5298ef92020-03-13 12:17:30 -04005447 bool allow_out_of_order_writes_ = false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005448};
5449
5450UnownedSSLExData<MockQUICTransport> QUICMethodTest::ex_data_;
5451
David Benjaminfd863b62019-07-25 13:51:32 -04005452// Test a full handshake and resumption work.
Steven Valdezc8e0f902018-07-14 11:23:01 -04005453TEST_F(QUICMethodTest, Basic) {
David Benjamin1e859052020-02-09 16:04:58 -05005454 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005455
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005456 g_last_session = nullptr;
5457
5458 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5459 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005460 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5461 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
David Benjamind6343572019-08-15 17:29:02 -04005462
Steven Valdezc8e0f902018-07-14 11:23:01 -04005463 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04005464 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdezc8e0f902018-07-14 11:23:01 -04005465
David Benjamind6343572019-08-15 17:29:02 -04005466 ExpectHandshakeSuccess();
5467 EXPECT_FALSE(SSL_session_reused(client_.get()));
5468 EXPECT_FALSE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005469
5470 // The server sent NewSessionTicket messages in the handshake.
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005471 EXPECT_FALSE(g_last_session);
5472 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5473 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
5474 EXPECT_TRUE(g_last_session);
5475
5476 // Create a second connection to verify resumption works.
David Benjamind6343572019-08-15 17:29:02 -04005477 ASSERT_TRUE(CreateClientAndServer());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005478 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
5479 SSL_set_session(client_.get(), session.get());
5480
David Benjamind6343572019-08-15 17:29:02 -04005481 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005482
David Benjamind6343572019-08-15 17:29:02 -04005483 ExpectHandshakeSuccess();
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005484 EXPECT_TRUE(SSL_session_reused(client_.get()));
5485 EXPECT_TRUE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005486}
5487
David Benjaminfd863b62019-07-25 13:51:32 -04005488// Test that HelloRetryRequest in QUIC works.
5489TEST_F(QUICMethodTest, HelloRetryRequest) {
David Benjamin1e859052020-02-09 16:04:58 -05005490 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjaminfd863b62019-07-25 13:51:32 -04005491
5492 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5493 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5494
5495 // BoringSSL predicts the most preferred curve, so using different preferences
5496 // will trigger HelloRetryRequest.
5497 static const int kClientPrefs[] = {NID_X25519, NID_X9_62_prime256v1};
5498 ASSERT_TRUE(SSL_CTX_set1_curves(client_ctx_.get(), kClientPrefs,
5499 OPENSSL_ARRAY_SIZE(kClientPrefs)));
5500 static const int kServerPrefs[] = {NID_X9_62_prime256v1, NID_X25519};
5501 ASSERT_TRUE(SSL_CTX_set1_curves(server_ctx_.get(), kServerPrefs,
5502 OPENSSL_ARRAY_SIZE(kServerPrefs)));
5503
5504 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04005505 ASSERT_TRUE(CompleteHandshakesForQUIC());
5506 ExpectHandshakeSuccess();
5507}
David Benjaminfd863b62019-07-25 13:51:32 -04005508
Nick Harpere32549e2020-05-06 14:27:11 -07005509// Test that the client does not send a legacy_session_id in the ClientHello.
5510TEST_F(QUICMethodTest, NoLegacySessionId) {
5511 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
5512
5513 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5514 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5515 // Check that the session ID length is 0 in an early callback.
5516 SSL_CTX_set_select_certificate_cb(
5517 server_ctx_.get(),
5518 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
5519 EXPECT_EQ(client_hello->session_id_len, 0u);
5520 return ssl_select_cert_success;
5521 });
5522
5523 ASSERT_TRUE(CreateClientAndServer());
5524 ASSERT_TRUE(CompleteHandshakesForQUIC());
5525
5526 ExpectHandshakeSuccess();
5527}
5528
David Benjamin1e859052020-02-09 16:04:58 -05005529// Test that, even in a 1-RTT handshake, the server installs keys at the right
5530// time. Half-RTT keys are available early, but 1-RTT read keys are deferred.
5531TEST_F(QUICMethodTest, HalfRTTKeys) {
5532 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
5533
5534 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5535 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5536 ASSERT_TRUE(CreateClientAndServer());
5537
5538 // The client sends ClientHello.
5539 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5540 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client_.get(), -1));
5541
5542 // The server reads ClientHello and sends ServerHello..Finished.
5543 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5544 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
5545 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
5546
5547 // At this point, the server has half-RTT write keys, but it cannot access
5548 // 1-RTT read keys until client Finished.
5549 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
5550 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
5551
5552 // Finish up the client and server handshakes.
5553 ASSERT_TRUE(CompleteHandshakesForQUIC());
5554
5555 // Both sides can now exchange 1-RTT data.
5556 ExpectHandshakeSuccess();
5557}
5558
David Benjamind6343572019-08-15 17:29:02 -04005559TEST_F(QUICMethodTest, ZeroRTTAccept) {
David Benjamin1e859052020-02-09 16:04:58 -05005560 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjamind6343572019-08-15 17:29:02 -04005561
5562 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5563 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
5564 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
5565 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5566 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5567
5568 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
5569 ASSERT_TRUE(session);
5570
5571 ASSERT_TRUE(CreateClientAndServer());
5572 SSL_set_session(client_.get(), session.get());
5573
5574 // The client handshake should return immediately into the early data state.
5575 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
5576 EXPECT_TRUE(SSL_in_early_data(client_.get()));
5577 // The transport should have keys for sending 0-RTT data.
David Benjamin1e859052020-02-09 16:04:58 -05005578 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04005579
5580 // The server will consume the ClientHello and also enter the early data
5581 // state.
5582 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5583 ASSERT_EQ(SSL_do_handshake(server_.get()), 1);
5584 EXPECT_TRUE(SSL_in_early_data(server_.get()));
5585 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_early_data));
David Benjamin1e859052020-02-09 16:04:58 -05005586 // At this point, the server has half-RTT write keys, but it cannot access
5587 // 1-RTT read keys until client Finished.
5588 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
5589 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
David Benjamind6343572019-08-15 17:29:02 -04005590
5591 // Finish up the client and server handshakes.
5592 ASSERT_TRUE(CompleteHandshakesForQUIC());
5593
5594 // Both sides can now exchange 1-RTT data.
5595 ExpectHandshakeSuccess();
5596 EXPECT_TRUE(SSL_session_reused(client_.get()));
5597 EXPECT_TRUE(SSL_session_reused(server_.get()));
5598 EXPECT_FALSE(SSL_in_early_data(client_.get()));
5599 EXPECT_FALSE(SSL_in_early_data(server_.get()));
5600 EXPECT_TRUE(SSL_early_data_accepted(client_.get()));
5601 EXPECT_TRUE(SSL_early_data_accepted(server_.get()));
Nick Harper5e086952020-09-30 13:59:14 -07005602
5603 // Finish handling post-handshake messages after the first 0-RTT resumption.
5604 EXPECT_TRUE(ProvideHandshakeData(client_.get()));
5605 EXPECT_TRUE(SSL_process_quic_post_handshake(client_.get()));
5606
5607 // Perform a second 0-RTT resumption attempt, and confirm that 0-RTT is
5608 // accepted again.
5609 ASSERT_TRUE(CreateClientAndServer());
5610 SSL_set_session(client_.get(), g_last_session.get());
5611
5612 // The client handshake should return immediately into the early data state.
5613 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
5614 EXPECT_TRUE(SSL_in_early_data(client_.get()));
5615 // The transport should have keys for sending 0-RTT data.
5616 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
5617
5618 // The server will consume the ClientHello and also enter the early data
5619 // state.
5620 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5621 ASSERT_EQ(SSL_do_handshake(server_.get()), 1);
5622 EXPECT_TRUE(SSL_in_early_data(server_.get()));
5623 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_early_data));
5624 // At this point, the server has half-RTT write keys, but it cannot access
5625 // 1-RTT read keys until client Finished.
5626 EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
5627 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
5628
5629 // Finish up the client and server handshakes.
5630 ASSERT_TRUE(CompleteHandshakesForQUIC());
5631
5632 // Both sides can now exchange 1-RTT data.
5633 ExpectHandshakeSuccess();
5634 EXPECT_TRUE(SSL_session_reused(client_.get()));
5635 EXPECT_TRUE(SSL_session_reused(server_.get()));
5636 EXPECT_FALSE(SSL_in_early_data(client_.get()));
5637 EXPECT_FALSE(SSL_in_early_data(server_.get()));
5638 EXPECT_TRUE(SSL_early_data_accepted(client_.get()));
5639 EXPECT_TRUE(SSL_early_data_accepted(server_.get()));
5640 EXPECT_EQ(SSL_get_early_data_reason(client_.get()), ssl_early_data_accepted);
5641 EXPECT_EQ(SSL_get_early_data_reason(server_.get()), ssl_early_data_accepted);
David Benjamind6343572019-08-15 17:29:02 -04005642}
5643
Nick Harper7c522992020-04-30 14:15:49 -07005644TEST_F(QUICMethodTest, ZeroRTTRejectMismatchedParameters) {
5645 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
5646
5647 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5648 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
5649 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
5650 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5651 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5652
5653
5654 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
5655 ASSERT_TRUE(session);
5656
Nick Harper85194322020-05-20 16:59:29 -07005657 ASSERT_TRUE(CreateClientAndServer());
5658 static const uint8_t new_context[] = {4};
5659 ASSERT_TRUE(SSL_set_quic_early_data_context(server_.get(), new_context,
5660 sizeof(new_context)));
5661 SSL_set_session(client_.get(), session.get());
Nick Harper7c522992020-04-30 14:15:49 -07005662
Nick Harper85194322020-05-20 16:59:29 -07005663 // The client handshake should return immediately into the early data
5664 // state.
5665 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
5666 EXPECT_TRUE(SSL_in_early_data(client_.get()));
5667 // The transport should have keys for sending 0-RTT data.
5668 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
Nick Harper7c522992020-04-30 14:15:49 -07005669
Nick Harper85194322020-05-20 16:59:29 -07005670 // The server will consume the ClientHello, but it will not accept 0-RTT.
5671 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5672 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
5673 EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
5674 EXPECT_FALSE(SSL_in_early_data(server_.get()));
5675 EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_early_data));
Nick Harper7c522992020-04-30 14:15:49 -07005676
Nick Harper85194322020-05-20 16:59:29 -07005677 // The client consumes the server response and signals 0-RTT rejection.
5678 for (;;) {
5679 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5680 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
5681 int err = SSL_get_error(client_.get(), -1);
5682 if (err == SSL_ERROR_EARLY_DATA_REJECTED) {
5683 break;
Nick Harper7c522992020-04-30 14:15:49 -07005684 }
Nick Harper85194322020-05-20 16:59:29 -07005685 ASSERT_EQ(SSL_ERROR_WANT_READ, err);
Nick Harper7c522992020-04-30 14:15:49 -07005686 }
Nick Harper85194322020-05-20 16:59:29 -07005687
5688 // As in TLS over TCP, 0-RTT rejection is sticky.
5689 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
5690 ASSERT_EQ(SSL_ERROR_EARLY_DATA_REJECTED, SSL_get_error(client_.get(), -1));
5691
5692 // Finish up the client and server handshakes.
5693 SSL_reset_early_data_reject(client_.get());
5694 ASSERT_TRUE(CompleteHandshakesForQUIC());
5695
5696 // Both sides can now exchange 1-RTT data.
5697 ExpectHandshakeSuccess();
5698 EXPECT_TRUE(SSL_session_reused(client_.get()));
5699 EXPECT_TRUE(SSL_session_reused(server_.get()));
5700 EXPECT_FALSE(SSL_in_early_data(client_.get()));
5701 EXPECT_FALSE(SSL_in_early_data(server_.get()));
5702 EXPECT_FALSE(SSL_early_data_accepted(client_.get()));
5703 EXPECT_FALSE(SSL_early_data_accepted(server_.get()));
5704}
5705
5706TEST_F(QUICMethodTest, NoZeroRTTTicketWithoutEarlyDataContext) {
5707 server_quic_early_data_context_ = {};
5708 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
5709
5710 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5711 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
5712 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
5713 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5714 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5715
5716 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
5717 ASSERT_TRUE(session);
5718 EXPECT_FALSE(SSL_SESSION_early_data_capable(session.get()));
Nick Harper7c522992020-04-30 14:15:49 -07005719}
5720
David Benjamind6343572019-08-15 17:29:02 -04005721TEST_F(QUICMethodTest, ZeroRTTReject) {
David Benjamin1e859052020-02-09 16:04:58 -05005722 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjamind6343572019-08-15 17:29:02 -04005723
5724 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5725 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
5726 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
5727 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5728 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5729
5730 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
5731 ASSERT_TRUE(session);
5732
5733 for (bool reject_hrr : {false, true}) {
5734 SCOPED_TRACE(reject_hrr);
5735
5736 ASSERT_TRUE(CreateClientAndServer());
5737 if (reject_hrr) {
5738 // Configure the server to prefer P-256, which will reject 0-RTT via
5739 // HelloRetryRequest.
5740 int p256 = NID_X9_62_prime256v1;
5741 ASSERT_TRUE(SSL_set1_curves(server_.get(), &p256, 1));
5742 } else {
5743 // Disable 0-RTT on the server, so it will reject it.
5744 SSL_set_early_data_enabled(server_.get(), 0);
David Benjaminfd863b62019-07-25 13:51:32 -04005745 }
David Benjamind6343572019-08-15 17:29:02 -04005746 SSL_set_session(client_.get(), session.get());
David Benjaminfd863b62019-07-25 13:51:32 -04005747
David Benjamind6343572019-08-15 17:29:02 -04005748 // The client handshake should return immediately into the early data state.
5749 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
5750 EXPECT_TRUE(SSL_in_early_data(client_.get()));
5751 // The transport should have keys for sending 0-RTT data.
David Benjamin1e859052020-02-09 16:04:58 -05005752 EXPECT_TRUE(
5753 transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04005754
5755 // The server will consume the ClientHello, but it will not accept 0-RTT.
David Benjaminfd863b62019-07-25 13:51:32 -04005756 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
David Benjamind6343572019-08-15 17:29:02 -04005757 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
5758 EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
5759 EXPECT_FALSE(SSL_in_early_data(server_.get()));
David Benjamin1e859052020-02-09 16:04:58 -05005760 EXPECT_FALSE(
5761 transport_->server()->HasReadSecret(ssl_encryption_early_data));
David Benjamind6343572019-08-15 17:29:02 -04005762
5763 // The client consumes the server response and signals 0-RTT rejection.
5764 for (;;) {
5765 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5766 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
5767 int err = SSL_get_error(client_.get(), -1);
5768 if (err == SSL_ERROR_EARLY_DATA_REJECTED) {
5769 break;
5770 }
5771 ASSERT_EQ(SSL_ERROR_WANT_READ, err);
David Benjaminfd863b62019-07-25 13:51:32 -04005772 }
5773
David Benjamind6343572019-08-15 17:29:02 -04005774 // As in TLS over TCP, 0-RTT rejection is sticky.
5775 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
5776 ASSERT_EQ(SSL_ERROR_EARLY_DATA_REJECTED, SSL_get_error(client_.get(), -1));
5777
5778 // Finish up the client and server handshakes.
5779 SSL_reset_early_data_reject(client_.get());
5780 ASSERT_TRUE(CompleteHandshakesForQUIC());
5781
5782 // Both sides can now exchange 1-RTT data.
5783 ExpectHandshakeSuccess();
5784 EXPECT_TRUE(SSL_session_reused(client_.get()));
5785 EXPECT_TRUE(SSL_session_reused(server_.get()));
5786 EXPECT_FALSE(SSL_in_early_data(client_.get()));
5787 EXPECT_FALSE(SSL_in_early_data(server_.get()));
5788 EXPECT_FALSE(SSL_early_data_accepted(client_.get()));
5789 EXPECT_FALSE(SSL_early_data_accepted(server_.get()));
David Benjaminfd863b62019-07-25 13:51:32 -04005790 }
David Benjaminfd863b62019-07-25 13:51:32 -04005791}
5792
David Benjaminee0716f2019-11-19 14:16:28 +08005793TEST_F(QUICMethodTest, NoZeroRTTKeysBeforeReverify) {
David Benjamin1e859052020-02-09 16:04:58 -05005794 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
David Benjaminee0716f2019-11-19 14:16:28 +08005795
5796 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5797 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
5798 SSL_CTX_set_reverify_on_resume(client_ctx_.get(), 1);
5799 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
5800 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5801 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5802
5803 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
5804 ASSERT_TRUE(session);
5805
5806 ASSERT_TRUE(CreateClientAndServer());
5807 SSL_set_session(client_.get(), session.get());
5808
5809 // Configure the certificate (re)verification to never complete. The client
5810 // handshake should pause.
5811 SSL_set_custom_verify(
5812 client_.get(), SSL_VERIFY_PEER,
5813 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
5814 return ssl_verify_retry;
5815 });
5816 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5817 ASSERT_EQ(SSL_get_error(client_.get(), -1),
5818 SSL_ERROR_WANT_CERTIFICATE_VERIFY);
5819
5820 // The early data keys have not yet been released.
David Benjamin1e859052020-02-09 16:04:58 -05005821 EXPECT_FALSE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjaminee0716f2019-11-19 14:16:28 +08005822
5823 // After the verification completes, the handshake progresses to the 0-RTT
5824 // point and releases keys.
5825 SSL_set_custom_verify(
5826 client_.get(), SSL_VERIFY_PEER,
5827 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
5828 return ssl_verify_ok;
5829 });
5830 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
5831 EXPECT_TRUE(SSL_in_early_data(client_.get()));
David Benjamin1e859052020-02-09 16:04:58 -05005832 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
David Benjaminee0716f2019-11-19 14:16:28 +08005833}
5834
Steven Valdezc8e0f902018-07-14 11:23:01 -04005835// Test only releasing data to QUIC one byte at a time on request, to maximize
5836// state machine pauses. Additionally, test that existing asynchronous callbacks
5837// still work.
5838TEST_F(QUICMethodTest, Async) {
David Benjamin1e859052020-02-09 16:04:58 -05005839 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005840
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 // Install an asynchronous certificate callback.
5846 bool cert_cb_ok = false;
5847 SSL_set_cert_cb(server_.get(),
5848 [](SSL *, void *arg) -> int {
5849 return *static_cast<bool *>(arg) ? 1 : -1;
5850 },
5851 &cert_cb_ok);
5852
5853 for (;;) {
5854 int client_ret = SSL_do_handshake(client_.get());
5855 if (client_ret != 1) {
5856 ASSERT_EQ(client_ret, -1);
5857 ASSERT_EQ(SSL_get_error(client_.get(), client_ret), SSL_ERROR_WANT_READ);
5858 ASSERT_TRUE(ProvideHandshakeData(client_.get(), 1));
5859 }
5860
5861 int server_ret = SSL_do_handshake(server_.get());
5862 if (server_ret != 1) {
5863 ASSERT_EQ(server_ret, -1);
5864 int ssl_err = SSL_get_error(server_.get(), server_ret);
5865 switch (ssl_err) {
5866 case SSL_ERROR_WANT_READ:
5867 ASSERT_TRUE(ProvideHandshakeData(server_.get(), 1));
5868 break;
5869 case SSL_ERROR_WANT_X509_LOOKUP:
5870 ASSERT_FALSE(cert_cb_ok);
5871 cert_cb_ok = true;
5872 break;
5873 default:
5874 FAIL() << "Unexpected SSL_get_error result: " << ssl_err;
5875 }
5876 }
5877
5878 if (client_ret == 1 && server_ret == 1) {
5879 break;
5880 }
5881 }
5882
David Benjamind6343572019-08-15 17:29:02 -04005883 ExpectHandshakeSuccess();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005884}
5885
5886// Test buffering write data until explicit flushes.
5887TEST_F(QUICMethodTest, Buffered) {
David Benjamin5298ef92020-03-13 12:17:30 -04005888 AllowOutOfOrderWrites();
5889
Steven Valdezc8e0f902018-07-14 11:23:01 -04005890 struct BufferedFlight {
5891 std::vector<uint8_t> data[kNumQUICLevels];
5892 };
5893 static UnownedSSLExData<BufferedFlight> buffered_flights;
5894
David Benjamincc9d9352018-10-30 19:45:22 -05005895 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
5896 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005897 BufferedFlight *flight = buffered_flights.Get(ssl);
5898 flight->data[level].insert(flight->data[level].end(), data, data + len);
5899 return 1;
5900 };
5901
5902 auto flush_flight = [](SSL *ssl) -> int {
5903 BufferedFlight *flight = buffered_flights.Get(ssl);
5904 for (size_t level = 0; level < kNumQUICLevels; level++) {
5905 if (!flight->data[level].empty()) {
5906 if (!TransportFromSSL(ssl)->WriteHandshakeData(
5907 static_cast<ssl_encryption_level_t>(level),
5908 flight->data[level])) {
5909 return 0;
5910 }
5911 flight->data[level].clear();
5912 }
5913 }
5914 return 1;
5915 };
5916
David Benjamin1e859052020-02-09 16:04:58 -05005917 SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
5918 quic_method.add_handshake_data = add_handshake_data;
5919 quic_method.flush_flight = flush_flight;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005920
5921 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5922 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5923 ASSERT_TRUE(CreateClientAndServer());
5924
5925 BufferedFlight client_flight, server_flight;
5926 buffered_flights.Set(client_.get(), &client_flight);
5927 buffered_flights.Set(server_.get(), &server_flight);
5928
David Benjamind6343572019-08-15 17:29:02 -04005929 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdezc8e0f902018-07-14 11:23:01 -04005930
David Benjamind6343572019-08-15 17:29:02 -04005931 ExpectHandshakeSuccess();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005932}
5933
5934// Test that excess data at one level is rejected. That is, if a single
5935// |SSL_provide_quic_data| call included both ServerHello and
5936// EncryptedExtensions in a single chunk, BoringSSL notices and rejects this on
5937// key change.
5938TEST_F(QUICMethodTest, ExcessProvidedData) {
David Benjamin5298ef92020-03-13 12:17:30 -04005939 AllowOutOfOrderWrites();
5940
David Benjamincc9d9352018-10-30 19:45:22 -05005941 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
5942 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005943 // Switch everything to the initial level.
5944 return TransportFromSSL(ssl)->WriteHandshakeData(ssl_encryption_initial,
5945 MakeConstSpan(data, len));
5946 };
5947
David Benjamin1e859052020-02-09 16:04:58 -05005948 SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
5949 quic_method.add_handshake_data = add_handshake_data;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005950
5951 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5952 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5953 ASSERT_TRUE(CreateClientAndServer());
5954
5955 // Send the ClientHello and ServerHello through Finished.
5956 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5957 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
5958 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5959 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
5960 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
5961
5962 // The client is still waiting for the ServerHello at initial
5963 // encryption.
5964 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
5965
David Benjamincc9d9352018-10-30 19:45:22 -05005966 // |add_handshake_data| incorrectly wrote everything at the initial level, so
5967 // this queues up ServerHello through Finished in one chunk.
Steven Valdezc8e0f902018-07-14 11:23:01 -04005968 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5969
5970 // The client reads ServerHello successfully, but then rejects the buffered
5971 // EncryptedExtensions on key change.
5972 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5973 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_SSL);
5974 uint32_t err = ERR_get_error();
5975 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
David Benjaminf9cc26f2020-02-09 16:49:31 -05005976 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_EXCESS_HANDSHAKE_DATA);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005977
David Benjamin1e859052020-02-09 16:04:58 -05005978 // The client sends an alert in response to this. The alert is sent at
5979 // handshake level because we install write secrets before read secrets and
5980 // the error is discovered when installing the read secret. (How to send
5981 // alerts on protocol syntax errors near key changes is ambiguous in general.)
David Benjamind6343572019-08-15 17:29:02 -04005982 ASSERT_TRUE(transport_->client()->has_alert());
David Benjamin1e859052020-02-09 16:04:58 -05005983 EXPECT_EQ(transport_->client()->alert_level(), ssl_encryption_handshake);
David Benjamind6343572019-08-15 17:29:02 -04005984 EXPECT_EQ(transport_->client()->alert(), SSL_AD_UNEXPECTED_MESSAGE);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005985
David Benjamin5298ef92020-03-13 12:17:30 -04005986 // Sanity-check handshake secrets. The error is discovered while setting the
5987 // read secret, so only the write secret has been installed.
David Benjamin1e859052020-02-09 16:04:58 -05005988 EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_handshake));
David Benjamin5298ef92020-03-13 12:17:30 -04005989 EXPECT_FALSE(transport_->client()->HasReadSecret(ssl_encryption_handshake));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005990}
5991
5992// Test that |SSL_provide_quic_data| will reject data at the wrong level.
5993TEST_F(QUICMethodTest, ProvideWrongLevel) {
David Benjamin1e859052020-02-09 16:04:58 -05005994 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005995
5996 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5997 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5998 ASSERT_TRUE(CreateClientAndServer());
5999
6000 // Send the ClientHello and ServerHello through Finished.
6001 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6002 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
6003 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6004 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6005 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
6006
6007 // The client is still waiting for the ServerHello at initial
6008 // encryption.
6009 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
6010
6011 // Data cannot be provided at the next level.
6012 std::vector<uint8_t> data;
6013 ASSERT_TRUE(
David Benjamind6343572019-08-15 17:29:02 -04006014 transport_->client()->ReadHandshakeData(&data, ssl_encryption_initial));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006015 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_handshake,
6016 data.data(), data.size()));
6017 ERR_clear_error();
6018
6019 // Progress to EncryptedExtensions.
6020 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
6021 data.data(), data.size()));
6022 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6023 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
6024 ASSERT_EQ(ssl_encryption_handshake, SSL_quic_read_level(client_.get()));
6025
6026 // Data cannot be provided at the previous level.
6027 ASSERT_TRUE(
David Benjamind6343572019-08-15 17:29:02 -04006028 transport_->client()->ReadHandshakeData(&data, ssl_encryption_handshake));
Steven Valdezc8e0f902018-07-14 11:23:01 -04006029 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
6030 data.data(), data.size()));
6031}
6032
6033TEST_F(QUICMethodTest, TooMuchData) {
David Benjamin1e859052020-02-09 16:04:58 -05006034 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdezc8e0f902018-07-14 11:23:01 -04006035
6036 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6037 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6038 ASSERT_TRUE(CreateClientAndServer());
6039
6040 size_t limit =
6041 SSL_quic_max_handshake_flight_len(client_.get(), ssl_encryption_initial);
6042 uint8_t b = 0;
6043 for (size_t i = 0; i < limit; i++) {
6044 ASSERT_TRUE(
6045 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
6046 }
6047
6048 EXPECT_FALSE(
6049 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
6050}
6051
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006052// Provide invalid post-handshake data.
6053TEST_F(QUICMethodTest, BadPostHandshake) {
David Benjamin1e859052020-02-09 16:04:58 -05006054 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006055
6056 g_last_session = nullptr;
6057
6058 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6059 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6060 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6061 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6062 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04006063 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006064
6065 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
6066 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
David Benjamind6343572019-08-15 17:29:02 -04006067 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_application));
6068 EXPECT_FALSE(transport_->client()->has_alert());
6069 EXPECT_FALSE(transport_->server()->has_alert());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05006070
6071 // Junk sent as part of post-handshake data should cause an error.
6072 uint8_t kJunk[] = {0x17, 0x0, 0x0, 0x4, 0xB, 0xE, 0xE, 0xF};
6073 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_application,
6074 kJunk, sizeof(kJunk)));
6075 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 0);
6076}
6077
Nick Harper80ddfc72020-03-11 18:26:31 -07006078static void ExpectReceivedTransportParamsEqual(const SSL *ssl,
6079 Span<const uint8_t> expected) {
6080 const uint8_t *received;
6081 size_t received_len;
6082 SSL_get_peer_quic_transport_params(ssl, &received, &received_len);
6083 ASSERT_EQ(received_len, expected.size());
6084 EXPECT_EQ(Bytes(received, received_len), Bytes(expected));
6085}
6086
6087TEST_F(QUICMethodTest, SetTransportParameters) {
6088 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6089 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6090 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6091
6092 ASSERT_TRUE(CreateClientAndServer());
6093 uint8_t kClientParams[] = {1, 2, 3, 4};
6094 uint8_t kServerParams[] = {5, 6, 7};
6095 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6096 sizeof(kClientParams)));
6097 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6098 sizeof(kServerParams)));
6099
6100 ASSERT_TRUE(CompleteHandshakesForQUIC());
6101 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6102 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6103}
6104
6105TEST_F(QUICMethodTest, SetTransportParamsInCallback) {
6106 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
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 ASSERT_TRUE(CreateClientAndServer());
6111 uint8_t kClientParams[] = {1, 2, 3, 4};
6112 static uint8_t kServerParams[] = {5, 6, 7};
6113 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6114 sizeof(kClientParams)));
6115 SSL_CTX_set_tlsext_servername_callback(
6116 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
6117 EXPECT_TRUE(SSL_set_quic_transport_params(ssl, kServerParams,
6118 sizeof(kServerParams)));
6119 return SSL_TLSEXT_ERR_OK;
6120 });
6121
6122 ASSERT_TRUE(CompleteHandshakesForQUIC());
6123 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6124 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6125}
6126
Nick Harper6bfd25c2020-03-30 17:15:19 -07006127TEST_F(QUICMethodTest, ForbidCrossProtocolResumptionClient) {
6128 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6129
6130 g_last_session = nullptr;
6131
6132 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6133 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6134 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6135 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6136
6137 ASSERT_TRUE(CreateClientAndServer());
6138 ASSERT_TRUE(CompleteHandshakesForQUIC());
6139
6140 ExpectHandshakeSuccess();
6141 EXPECT_FALSE(SSL_session_reused(client_.get()));
6142 EXPECT_FALSE(SSL_session_reused(server_.get()));
6143
6144 // The server sent NewSessionTicket messages in the handshake.
6145 EXPECT_FALSE(g_last_session);
6146 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6147 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
6148 EXPECT_TRUE(g_last_session);
6149
6150 // Pretend that g_last_session came from a TLS-over-TCP connection.
6151 g_last_session.get()->is_quic = false;
6152
6153 // Create a second connection and verify that resumption does not occur with
6154 // a session from a non-QUIC connection. This tests that the client does not
6155 // offer over QUIC a session believed to be received over TCP. The server
6156 // believes this is a QUIC session, so if the client offered the session, the
6157 // server would have resumed it.
6158 ASSERT_TRUE(CreateClientAndServer());
6159 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
6160 SSL_set_session(client_.get(), session.get());
6161
6162 ASSERT_TRUE(CompleteHandshakesForQUIC());
6163 ExpectHandshakeSuccess();
6164 EXPECT_FALSE(SSL_session_reused(client_.get()));
6165 EXPECT_FALSE(SSL_session_reused(server_.get()));
6166}
6167
6168TEST_F(QUICMethodTest, ForbidCrossProtocolResumptionServer) {
6169 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6170
6171 g_last_session = nullptr;
6172
6173 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6174 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6175 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6176 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6177
6178 ASSERT_TRUE(CreateClientAndServer());
6179 ASSERT_TRUE(CompleteHandshakesForQUIC());
6180
6181 ExpectHandshakeSuccess();
6182 EXPECT_FALSE(SSL_session_reused(client_.get()));
6183 EXPECT_FALSE(SSL_session_reused(server_.get()));
6184
6185 // The server sent NewSessionTicket messages in the handshake.
6186 EXPECT_FALSE(g_last_session);
6187 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6188 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
6189 EXPECT_TRUE(g_last_session);
6190
6191 // Attempt a resumption with g_last_session using TLS_method.
6192 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
6193 ASSERT_TRUE(client_ctx);
6194
6195 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), nullptr));
6196
6197 bssl::UniquePtr<SSL> client(SSL_new(client_ctx.get())),
6198 server(SSL_new(server_ctx_.get()));
6199 ASSERT_TRUE(client);
6200 ASSERT_TRUE(server);
6201 SSL_set_connect_state(client.get());
6202 SSL_set_accept_state(server.get());
6203
6204 // The TLS-over-TCP client will refuse to resume with a quic session, so
6205 // mark is_quic = false to bypass the client check to test the server check.
6206 g_last_session.get()->is_quic = false;
6207 SSL_set_session(client.get(), g_last_session.get());
6208
6209 BIO *bio1, *bio2;
6210 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
6211
6212 // SSL_set_bio takes ownership.
6213 SSL_set_bio(client.get(), bio1, bio1);
6214 SSL_set_bio(server.get(), bio2, bio2);
6215 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
6216
6217 EXPECT_FALSE(SSL_session_reused(client.get()));
6218 EXPECT_FALSE(SSL_session_reused(server.get()));
6219}
6220
Nick Harper72cff812020-03-26 18:06:16 -07006221TEST_F(QUICMethodTest, ClientRejectsMissingTransportParams) {
6222 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6223 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6224 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6225
6226 ASSERT_TRUE(CreateClientAndServer());
6227 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), nullptr, 0));
6228 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
6229}
6230
6231TEST_F(QUICMethodTest, ServerRejectsMissingTransportParams) {
6232 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6233 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6234 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6235
6236 ASSERT_TRUE(CreateClientAndServer());
6237 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), nullptr, 0));
6238 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kClientError));
6239}
6240
David Schinazi3d8b8c32021-01-14 11:25:49 -08006241TEST_F(QUICMethodTest, QuicLegacyCodepointEnabled) {
6242 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6243 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6244 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6245
6246 ASSERT_TRUE(CreateClientAndServer());
6247 uint8_t kClientParams[] = {1, 2, 3, 4};
6248 uint8_t kServerParams[] = {5, 6, 7};
6249 SSL_set_quic_use_legacy_codepoint(client_.get(), 1);
6250 SSL_set_quic_use_legacy_codepoint(server_.get(), 1);
6251 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6252 sizeof(kClientParams)));
6253 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6254 sizeof(kServerParams)));
6255
6256 ASSERT_TRUE(CompleteHandshakesForQUIC());
6257 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6258 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6259}
6260
6261TEST_F(QUICMethodTest, QuicLegacyCodepointDisabled) {
6262 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6263 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6264 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6265
6266 ASSERT_TRUE(CreateClientAndServer());
6267 uint8_t kClientParams[] = {1, 2, 3, 4};
6268 uint8_t kServerParams[] = {5, 6, 7};
6269 SSL_set_quic_use_legacy_codepoint(client_.get(), 0);
6270 SSL_set_quic_use_legacy_codepoint(server_.get(), 0);
6271 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6272 sizeof(kClientParams)));
6273 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6274 sizeof(kServerParams)));
6275
6276 ASSERT_TRUE(CompleteHandshakesForQUIC());
6277 ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
6278 ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
6279}
6280
6281TEST_F(QUICMethodTest, QuicLegacyCodepointClientOnly) {
6282 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6283 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6284 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6285
6286 ASSERT_TRUE(CreateClientAndServer());
6287 uint8_t kClientParams[] = {1, 2, 3, 4};
6288 uint8_t kServerParams[] = {5, 6, 7};
6289 SSL_set_quic_use_legacy_codepoint(client_.get(), 1);
6290 SSL_set_quic_use_legacy_codepoint(server_.get(), 0);
6291 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6292 sizeof(kClientParams)));
6293 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6294 sizeof(kServerParams)));
6295
6296 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
6297}
6298
6299TEST_F(QUICMethodTest, QuicLegacyCodepointServerOnly) {
6300 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6301 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6302 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6303
6304 ASSERT_TRUE(CreateClientAndServer());
6305 uint8_t kClientParams[] = {1, 2, 3, 4};
6306 uint8_t kServerParams[] = {5, 6, 7};
6307 SSL_set_quic_use_legacy_codepoint(client_.get(), 0);
6308 SSL_set_quic_use_legacy_codepoint(server_.get(), 1);
6309 ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
6310 sizeof(kClientParams)));
6311 ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
6312 sizeof(kServerParams)));
6313
6314 ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
6315}
6316
David Benjaminc47bfce2021-01-20 17:10:32 -05006317// Test that the default QUIC code point is consistent with
6318// |TLSEXT_TYPE_quic_transport_parameters|. This test ensures we remember to
6319// update the two values together.
6320TEST_F(QUICMethodTest, QuicCodePointDefault) {
6321 const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6322 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6323 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6324 SSL_CTX_set_select_certificate_cb(
6325 server_ctx_.get(),
6326 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
6327 const uint8_t *data;
6328 size_t len;
6329 if (!SSL_early_callback_ctx_extension_get(
6330 client_hello, TLSEXT_TYPE_quic_transport_parameters, &data,
6331 &len)) {
6332 ADD_FAILURE() << "Could not find quic_transport_parameters extension";
6333 return ssl_select_cert_error;
6334 }
6335 return ssl_select_cert_success;
6336 });
6337
6338 ASSERT_TRUE(CreateClientAndServer());
6339 ASSERT_TRUE(CompleteHandshakesForQUIC());
6340}
6341
Adam Langley7540cc22019-04-18 09:56:13 -07006342extern "C" {
6343int BORINGSSL_enum_c_type_test(void);
6344}
6345
6346TEST(SSLTest, EnumTypes) {
6347 EXPECT_EQ(sizeof(int), sizeof(ssl_private_key_result_t));
6348 EXPECT_EQ(1, BORINGSSL_enum_c_type_test());
6349}
6350
David Benjaminb29e1e12019-05-06 14:44:46 -05006351TEST_P(SSLVersionTest, DoubleSSLError) {
6352 // Connect the inner SSL connections.
6353 ASSERT_TRUE(Connect());
6354
6355 // Make a pair of |BIO|s which wrap |client_| and |server_|.
6356 UniquePtr<BIO_METHOD> bio_method(BIO_meth_new(0, nullptr));
6357 ASSERT_TRUE(bio_method);
6358 ASSERT_TRUE(BIO_meth_set_read(
6359 bio_method.get(), [](BIO *bio, char *out, int len) -> int {
6360 SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
6361 int ret = SSL_read(ssl, out, len);
6362 int ssl_ret = SSL_get_error(ssl, ret);
6363 if (ssl_ret == SSL_ERROR_WANT_READ) {
6364 BIO_set_retry_read(bio);
6365 }
6366 return ret;
6367 }));
6368 ASSERT_TRUE(BIO_meth_set_write(
6369 bio_method.get(), [](BIO *bio, const char *in, int len) -> int {
6370 SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
6371 int ret = SSL_write(ssl, in, len);
6372 int ssl_ret = SSL_get_error(ssl, ret);
6373 if (ssl_ret == SSL_ERROR_WANT_WRITE) {
6374 BIO_set_retry_write(bio);
6375 }
6376 return ret;
6377 }));
6378 ASSERT_TRUE(BIO_meth_set_ctrl(
6379 bio_method.get(), [](BIO *bio, int cmd, long larg, void *parg) -> long {
6380 // |SSL| objects require |BIO_flush| support.
6381 if (cmd == BIO_CTRL_FLUSH) {
6382 return 1;
6383 }
6384 return 0;
6385 }));
6386
6387 UniquePtr<BIO> client_bio(BIO_new(bio_method.get()));
6388 ASSERT_TRUE(client_bio);
6389 BIO_set_data(client_bio.get(), client_.get());
6390 BIO_set_init(client_bio.get(), 1);
6391
6392 UniquePtr<BIO> server_bio(BIO_new(bio_method.get()));
6393 ASSERT_TRUE(server_bio);
6394 BIO_set_data(server_bio.get(), server_.get());
6395 BIO_set_init(server_bio.get(), 1);
6396
6397 // Wrap the inner connections in another layer of SSL.
6398 UniquePtr<SSL> client_outer(SSL_new(client_ctx_.get()));
6399 ASSERT_TRUE(client_outer);
6400 SSL_set_connect_state(client_outer.get());
6401 SSL_set_bio(client_outer.get(), client_bio.get(), client_bio.get());
6402 client_bio.release(); // |SSL_set_bio| takes ownership.
6403
6404 UniquePtr<SSL> server_outer(SSL_new(server_ctx_.get()));
6405 ASSERT_TRUE(server_outer);
6406 SSL_set_accept_state(server_outer.get());
6407 SSL_set_bio(server_outer.get(), server_bio.get(), server_bio.get());
6408 server_bio.release(); // |SSL_set_bio| takes ownership.
6409
6410 // Configure |client_outer| to reject the server certificate.
6411 SSL_set_custom_verify(
6412 client_outer.get(), SSL_VERIFY_PEER,
6413 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
6414 return ssl_verify_invalid;
6415 });
6416
6417 for (;;) {
6418 int client_ret = SSL_do_handshake(client_outer.get());
6419 int client_err = SSL_get_error(client_outer.get(), client_ret);
6420 if (client_err != SSL_ERROR_WANT_READ &&
6421 client_err != SSL_ERROR_WANT_WRITE) {
6422 // The client handshake should terminate on a certificate verification
6423 // error.
6424 EXPECT_EQ(SSL_ERROR_SSL, client_err);
6425 uint32_t err = ERR_peek_error();
6426 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
6427 EXPECT_EQ(SSL_R_CERTIFICATE_VERIFY_FAILED, ERR_GET_REASON(err));
6428 break;
6429 }
6430
6431 // Run the server handshake and continue.
6432 int server_ret = SSL_do_handshake(server_outer.get());
6433 int server_err = SSL_get_error(server_outer.get(), server_ret);
6434 ASSERT_TRUE(server_err == SSL_ERROR_NONE ||
6435 server_err == SSL_ERROR_WANT_READ ||
6436 server_err == SSL_ERROR_WANT_WRITE);
6437 }
6438}
6439
David Benjamin1b819472020-06-09 14:01:02 -04006440TEST_P(SSLVersionTest, SameKeyResume) {
6441 uint8_t key[48];
6442 RAND_bytes(key, sizeof(key));
6443
6444 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
6445 ASSERT_TRUE(server_ctx2);
6446 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
6447 ASSERT_TRUE(
6448 SSL_CTX_set_tlsext_ticket_keys(server_ctx_.get(), key, sizeof(key)));
6449 ASSERT_TRUE(
6450 SSL_CTX_set_tlsext_ticket_keys(server_ctx2.get(), key, sizeof(key)));
6451
6452 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6453 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
6454 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
6455
6456 // Establish a session for |server_ctx_|.
6457 bssl::UniquePtr<SSL_SESSION> session =
6458 CreateClientSession(client_ctx_.get(), server_ctx_.get());
6459 ASSERT_TRUE(session);
6460 ClientConfig config;
6461 config.session = session.get();
6462
6463 // Resuming with |server_ctx_| again works.
6464 bssl::UniquePtr<SSL> client, server;
6465 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6466 server_ctx_.get(), config));
6467 EXPECT_TRUE(SSL_session_reused(client.get()));
6468 EXPECT_TRUE(SSL_session_reused(server.get()));
6469
6470 // Resuming with |server_ctx2| also works.
6471 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6472 server_ctx2.get(), config));
6473 EXPECT_TRUE(SSL_session_reused(client.get()));
6474 EXPECT_TRUE(SSL_session_reused(server.get()));
6475}
6476
6477TEST_P(SSLVersionTest, DifferentKeyNoResume) {
6478 uint8_t key1[48], key2[48];
6479 RAND_bytes(key1, sizeof(key1));
6480 RAND_bytes(key2, sizeof(key2));
6481
6482 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
6483 ASSERT_TRUE(server_ctx2);
6484 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
6485 ASSERT_TRUE(
6486 SSL_CTX_set_tlsext_ticket_keys(server_ctx_.get(), key1, sizeof(key1)));
6487 ASSERT_TRUE(
6488 SSL_CTX_set_tlsext_ticket_keys(server_ctx2.get(), key2, sizeof(key2)));
6489
6490 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6491 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
6492 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
6493
6494 // Establish a session for |server_ctx_|.
6495 bssl::UniquePtr<SSL_SESSION> session =
6496 CreateClientSession(client_ctx_.get(), server_ctx_.get());
6497 ASSERT_TRUE(session);
6498 ClientConfig config;
6499 config.session = session.get();
6500
6501 // Resuming with |server_ctx_| again works.
6502 bssl::UniquePtr<SSL> client, server;
6503 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6504 server_ctx_.get(), config));
6505 EXPECT_TRUE(SSL_session_reused(client.get()));
6506 EXPECT_TRUE(SSL_session_reused(server.get()));
6507
6508 // Resuming with |server_ctx2| does not work.
6509 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6510 server_ctx2.get(), config));
6511 EXPECT_FALSE(SSL_session_reused(client.get()));
6512 EXPECT_FALSE(SSL_session_reused(server.get()));
6513}
6514
6515TEST_P(SSLVersionTest, UnrelatedServerNoResume) {
6516 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
6517 ASSERT_TRUE(server_ctx2);
6518 ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
6519
6520 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6521 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
6522 SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
6523
6524 // Establish a session for |server_ctx_|.
6525 bssl::UniquePtr<SSL_SESSION> session =
6526 CreateClientSession(client_ctx_.get(), server_ctx_.get());
6527 ASSERT_TRUE(session);
6528 ClientConfig config;
6529 config.session = session.get();
6530
6531 // Resuming with |server_ctx_| again works.
6532 bssl::UniquePtr<SSL> client, server;
6533 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6534 server_ctx_.get(), config));
6535 EXPECT_TRUE(SSL_session_reused(client.get()));
6536 EXPECT_TRUE(SSL_session_reused(server.get()));
6537
6538 // Resuming with |server_ctx2| does not work.
6539 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6540 server_ctx2.get(), config));
6541 EXPECT_FALSE(SSL_session_reused(client.get()));
6542 EXPECT_FALSE(SSL_session_reused(server.get()));
6543}
6544
Adam Langley47cefed2021-05-26 13:36:40 -07006545Span<const uint8_t> SessionIDOf(const SSL* ssl) {
6546 const SSL_SESSION *session = SSL_get_session(ssl);
6547 unsigned len;
6548 const uint8_t *data = SSL_SESSION_get_id(session, &len);
6549 return MakeConstSpan(data, len);
6550}
6551
6552TEST_P(SSLVersionTest, TicketSessionIDsMatch) {
6553 // This checks that the session IDs at client and server match after a ticket
6554 // resumption. It's unclear whether this should be true, but Envoy depends
6555 // on it in their tests so this will give an early signal if we break it.
6556 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6557 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
6558
6559 bssl::UniquePtr<SSL_SESSION> session =
6560 CreateClientSession(client_ctx_.get(), server_ctx_.get());
6561
6562 bssl::UniquePtr<SSL> client, server;
6563 ClientConfig config;
6564 config.session = session.get();
6565 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6566 server_ctx_.get(), config));
6567 EXPECT_TRUE(SSL_session_reused(client.get()));
6568 EXPECT_TRUE(SSL_session_reused(server.get()));
6569
6570 EXPECT_EQ(Bytes(SessionIDOf(client.get())), Bytes(SessionIDOf(server.get())));
6571}
6572
David Benjamin0e7dbd52019-05-15 16:01:18 -04006573TEST(SSLTest, WriteWhileExplicitRenegotiate) {
David Benjamin9b2cdb72021-04-01 23:21:53 -04006574 bssl::UniquePtr<SSL_CTX> ctx(CreateContextWithTestCertificate(TLS_method()));
David Benjamin0e7dbd52019-05-15 16:01:18 -04006575 ASSERT_TRUE(ctx);
6576
David Benjamin0e7dbd52019-05-15 16:01:18 -04006577 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_2_VERSION));
6578 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_2_VERSION));
6579 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
6580 ctx.get(), "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"));
6581
6582 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04006583 ASSERT_TRUE(CreateClientAndServer(&client, &server, ctx.get(), ctx.get()));
David Benjamin0e7dbd52019-05-15 16:01:18 -04006584 SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_explicit);
David Benjamin9b2cdb72021-04-01 23:21:53 -04006585 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
David Benjamin0e7dbd52019-05-15 16:01:18 -04006586
6587 static const uint8_t kInput[] = {'h', 'e', 'l', 'l', 'o'};
6588
6589 // Write "hello" until the buffer is full, so |client| has a pending write.
6590 size_t num_writes = 0;
6591 for (;;) {
6592 int ret = SSL_write(client.get(), kInput, sizeof(kInput));
6593 if (ret != int(sizeof(kInput))) {
6594 ASSERT_EQ(-1, ret);
6595 ASSERT_EQ(SSL_ERROR_WANT_WRITE, SSL_get_error(client.get(), ret));
6596 break;
6597 }
6598 num_writes++;
6599 }
6600
6601 // Encrypt a HelloRequest.
6602 uint8_t in[] = {SSL3_MT_HELLO_REQUEST, 0, 0, 0};
6603#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
6604 // Fuzzer-mode records are unencrypted.
6605 uint8_t record[5 + sizeof(in)];
6606 record[0] = SSL3_RT_HANDSHAKE;
6607 record[1] = 3;
6608 record[2] = 3; // TLS 1.2
6609 record[3] = 0;
6610 record[4] = sizeof(record) - 5;
6611 memcpy(record + 5, in, sizeof(in));
6612#else
6613 // Extract key material from |server|.
6614 static const size_t kKeyLen = 32;
6615 static const size_t kNonceLen = 12;
6616 ASSERT_EQ(2u * (kKeyLen + kNonceLen), SSL_get_key_block_len(server.get()));
6617 uint8_t key_block[2u * (kKeyLen + kNonceLen)];
6618 ASSERT_TRUE(
6619 SSL_generate_key_block(server.get(), key_block, sizeof(key_block)));
6620 Span<uint8_t> key = MakeSpan(key_block + kKeyLen, kKeyLen);
6621 Span<uint8_t> nonce =
6622 MakeSpan(key_block + kKeyLen + kKeyLen + kNonceLen, kNonceLen);
6623
6624 uint8_t ad[13];
6625 uint64_t seq = SSL_get_write_sequence(server.get());
6626 for (size_t i = 0; i < 8; i++) {
6627 // The nonce is XORed with the sequence number.
6628 nonce[11 - i] ^= uint8_t(seq);
6629 ad[7 - i] = uint8_t(seq);
6630 seq >>= 8;
6631 }
6632
6633 ad[8] = SSL3_RT_HANDSHAKE;
6634 ad[9] = 3;
6635 ad[10] = 3; // TLS 1.2
6636 ad[11] = 0;
6637 ad[12] = sizeof(in);
6638
6639 uint8_t record[5 + sizeof(in) + 16];
6640 record[0] = SSL3_RT_HANDSHAKE;
6641 record[1] = 3;
6642 record[2] = 3; // TLS 1.2
6643 record[3] = 0;
6644 record[4] = sizeof(record) - 5;
6645
6646 ScopedEVP_AEAD_CTX aead;
6647 ASSERT_TRUE(EVP_AEAD_CTX_init(aead.get(), EVP_aead_chacha20_poly1305(),
6648 key.data(), key.size(),
6649 EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr));
6650 size_t len;
6651 ASSERT_TRUE(EVP_AEAD_CTX_seal(aead.get(), record + 5, &len,
6652 sizeof(record) - 5, nonce.data(), nonce.size(),
6653 in, sizeof(in), ad, sizeof(ad)));
6654 ASSERT_EQ(sizeof(record) - 5, len);
6655#endif // BORINGSSL_UNSAFE_FUZZER_MODE
6656
6657 ASSERT_EQ(int(sizeof(record)),
6658 BIO_write(SSL_get_wbio(server.get()), record, sizeof(record)));
6659
6660 // |SSL_read| should pick up the HelloRequest.
6661 uint8_t byte;
6662 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
6663 ASSERT_EQ(SSL_ERROR_WANT_RENEGOTIATE, SSL_get_error(client.get(), -1));
6664
6665 // Drain the data from the |client|.
6666 uint8_t buf[sizeof(kInput)];
6667 for (size_t i = 0; i < num_writes; i++) {
6668 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
6669 EXPECT_EQ(Bytes(buf), Bytes(kInput));
6670 }
6671
6672 // |client| should be able to finish the pending write and continue to write,
6673 // despite the paused HelloRequest.
6674 ASSERT_EQ(int(sizeof(kInput)),
6675 SSL_write(client.get(), kInput, sizeof(kInput)));
6676 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
6677 EXPECT_EQ(Bytes(buf), Bytes(kInput));
6678
6679 ASSERT_EQ(int(sizeof(kInput)),
6680 SSL_write(client.get(), kInput, sizeof(kInput)));
6681 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
6682 EXPECT_EQ(Bytes(buf), Bytes(kInput));
6683
6684 // |SSL_read| is stuck until we acknowledge the HelloRequest.
6685 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
6686 ASSERT_EQ(SSL_ERROR_WANT_RENEGOTIATE, SSL_get_error(client.get(), -1));
6687
6688 ASSERT_TRUE(SSL_renegotiate(client.get()));
6689 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
6690 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
6691
6692 // We never renegotiate as a server.
6693 ASSERT_EQ(-1, SSL_read(server.get(), buf, sizeof(buf)));
6694 ASSERT_EQ(SSL_ERROR_SSL, SSL_get_error(server.get(), -1));
6695 uint32_t err = ERR_get_error();
6696 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
6697 EXPECT_EQ(SSL_R_NO_RENEGOTIATION, ERR_GET_REASON(err));
6698}
6699
David Benjaminf9e0cda2020-03-23 18:29:09 -04006700
6701TEST(SSLTest, CopyWithoutEarlyData) {
6702 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04006703 bssl::UniquePtr<SSL_CTX> server_ctx(
6704 CreateContextWithTestCertificate(TLS_method()));
David Benjaminf9e0cda2020-03-23 18:29:09 -04006705 ASSERT_TRUE(client_ctx);
6706 ASSERT_TRUE(server_ctx);
6707
David Benjaminf9e0cda2020-03-23 18:29:09 -04006708 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
6709 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
6710 SSL_CTX_set_early_data_enabled(client_ctx.get(), 1);
6711 SSL_CTX_set_early_data_enabled(server_ctx.get(), 1);
6712
6713 bssl::UniquePtr<SSL_SESSION> session =
6714 CreateClientSession(client_ctx.get(), server_ctx.get());
6715 ASSERT_TRUE(session);
6716
6717 // The client should attempt early data with |session|.
David Benjaminf9e0cda2020-03-23 18:29:09 -04006718 bssl::UniquePtr<SSL> client, server;
David Benjamin9b2cdb72021-04-01 23:21:53 -04006719 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
6720 server_ctx.get()));
6721 SSL_set_session(client.get(), session.get());
6722 SSL_set_early_data_enabled(client.get(), 1);
David Benjaminf9e0cda2020-03-23 18:29:09 -04006723 ASSERT_EQ(1, SSL_do_handshake(client.get()));
6724 EXPECT_TRUE(SSL_in_early_data(client.get()));
6725
6726 // |SSL_SESSION_copy_without_early_data| should disable early data but
6727 // still resume the session.
6728 bssl::UniquePtr<SSL_SESSION> session2(
6729 SSL_SESSION_copy_without_early_data(session.get()));
6730 ASSERT_TRUE(session2);
6731 EXPECT_NE(session.get(), session2.get());
David Benjamin9b2cdb72021-04-01 23:21:53 -04006732 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
6733 server_ctx.get()));
6734 SSL_set_session(client.get(), session2.get());
6735 SSL_set_early_data_enabled(client.get(), 1);
6736 EXPECT_TRUE(CompleteHandshakes(client.get(), server.get()));
David Benjaminf9e0cda2020-03-23 18:29:09 -04006737 EXPECT_TRUE(SSL_session_reused(client.get()));
6738 EXPECT_EQ(ssl_early_data_unsupported_for_session,
6739 SSL_get_early_data_reason(client.get()));
6740
6741 // |SSL_SESSION_copy_without_early_data| should be a reference count increase
6742 // when passed an early-data-incapable session.
6743 bssl::UniquePtr<SSL_SESSION> session3(
6744 SSL_SESSION_copy_without_early_data(session2.get()));
6745 EXPECT_EQ(session2.get(), session3.get());
6746}
6747
Adam Langley53a17f52020-05-26 14:44:07 -07006748TEST(SSLTest, ProcessTLS13NewSessionTicket) {
6749 // Configure client and server to negotiate TLS 1.3 only.
Adam Langley53a17f52020-05-26 14:44:07 -07006750 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04006751 bssl::UniquePtr<SSL_CTX> server_ctx(
6752 CreateContextWithTestCertificate(TLS_method()));
Adam Langley53a17f52020-05-26 14:44:07 -07006753 ASSERT_TRUE(client_ctx);
6754 ASSERT_TRUE(server_ctx);
6755 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
6756 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
6757 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
6758 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
Adam Langley53a17f52020-05-26 14:44:07 -07006759
6760 bssl::UniquePtr<SSL> client, server;
6761 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
6762 server_ctx.get()));
6763 EXPECT_EQ(TLS1_3_VERSION, SSL_version(client.get()));
6764
6765 // Process a TLS 1.3 NewSessionTicket.
6766 static const uint8_t kTicket[] = {
6767 0x04, 0x00, 0x00, 0xb2, 0x00, 0x02, 0xa3, 0x00, 0x04, 0x03, 0x02, 0x01,
6768 0x01, 0x00, 0x00, 0xa0, 0x01, 0x06, 0x09, 0x11, 0x16, 0x19, 0x21, 0x26,
6769 0x29, 0x31, 0x36, 0x39, 0x41, 0x46, 0x49, 0x51, 0x03, 0x06, 0x09, 0x13,
6770 0x16, 0x19, 0x23, 0x26, 0x29, 0x33, 0x36, 0x39, 0x43, 0x46, 0x49, 0x53,
6771 0xf7, 0x00, 0x29, 0xec, 0xf2, 0xc4, 0xa4, 0x41, 0xfc, 0x30, 0x17, 0x2e,
6772 0x9f, 0x7c, 0xa8, 0xaf, 0x75, 0x70, 0xf0, 0x1f, 0xc7, 0x98, 0xf7, 0xcf,
6773 0x5a, 0x5a, 0x6b, 0x5b, 0xfe, 0xf1, 0xe7, 0x3a, 0xe8, 0xf7, 0x6c, 0xd2,
6774 0xa8, 0xa6, 0x92, 0x5b, 0x96, 0x8d, 0xde, 0xdb, 0xd3, 0x20, 0x6a, 0xcb,
6775 0x69, 0x06, 0xf4, 0x91, 0x85, 0x2e, 0xe6, 0x5e, 0x0c, 0x59, 0xf2, 0x9e,
6776 0x9b, 0x79, 0x91, 0x24, 0x7e, 0x4a, 0x32, 0x3d, 0xbe, 0x4b, 0x80, 0x70,
6777 0xaf, 0xd0, 0x1d, 0xe2, 0xca, 0x05, 0x35, 0x09, 0x09, 0x05, 0x0f, 0xbb,
6778 0xc4, 0xae, 0xd7, 0xc4, 0xed, 0xd7, 0xae, 0x35, 0xc8, 0x73, 0x63, 0x78,
6779 0x64, 0xc9, 0x7a, 0x1f, 0xed, 0x7a, 0x9a, 0x47, 0x44, 0xfd, 0x50, 0xf7,
6780 0xb7, 0xe0, 0x64, 0xa9, 0x02, 0xc1, 0x5c, 0x23, 0x18, 0x3f, 0xc4, 0xcf,
6781 0x72, 0x02, 0x59, 0x2d, 0xe1, 0xaa, 0x61, 0x72, 0x00, 0x04, 0x5a, 0x5a,
6782 0x00, 0x00,
6783 };
6784 bssl::UniquePtr<SSL_SESSION> session(SSL_process_tls13_new_session_ticket(
6785 client.get(), kTicket, sizeof(kTicket)));
6786 ASSERT_TRUE(session);
6787 ASSERT_TRUE(SSL_SESSION_has_ticket(session.get()));
6788
6789 uint8_t *session_buf = nullptr;
6790 size_t session_length = 0;
6791 ASSERT_TRUE(
6792 SSL_SESSION_to_bytes(session.get(), &session_buf, &session_length));
6793 bssl::UniquePtr<uint8_t> session_buf_free(session_buf);
6794 ASSERT_TRUE(session_buf);
6795 ASSERT_GT(session_length, 0u);
6796
6797 // Servers cannot call |SSL_process_tls13_new_session_ticket|.
6798 ASSERT_FALSE(SSL_process_tls13_new_session_ticket(server.get(), kTicket,
6799 sizeof(kTicket)));
6800
6801 // Clients cannot call |SSL_process_tls13_new_session_ticket| before the
6802 // handshake completes.
6803 bssl::UniquePtr<SSL> client2(SSL_new(client_ctx.get()));
6804 ASSERT_TRUE(client2);
6805 SSL_set_connect_state(client2.get());
6806 ASSERT_FALSE(SSL_process_tls13_new_session_ticket(client2.get(), kTicket,
6807 sizeof(kTicket)));
6808}
6809
David Benjamin3989c992020-10-09 14:12:06 -04006810TEST(SSLTest, BIO) {
6811 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin9b2cdb72021-04-01 23:21:53 -04006812 bssl::UniquePtr<SSL_CTX> server_ctx(
6813 CreateContextWithTestCertificate(TLS_method()));
David Benjamin3989c992020-10-09 14:12:06 -04006814 ASSERT_TRUE(client_ctx);
6815 ASSERT_TRUE(server_ctx);
6816
David Benjamin3989c992020-10-09 14:12:06 -04006817 for (bool take_ownership : {true, false}) {
6818 // For simplicity, get the handshake out of the way first.
6819 bssl::UniquePtr<SSL> client, server;
6820 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
6821 server_ctx.get()));
6822
6823 // Wrap |client| in an SSL BIO.
6824 bssl::UniquePtr<BIO> client_bio(BIO_new(BIO_f_ssl()));
6825 ASSERT_TRUE(client_bio);
6826 ASSERT_EQ(1, BIO_set_ssl(client_bio.get(), client.get(), take_ownership));
6827 if (take_ownership) {
6828 client.release();
6829 }
6830
6831 // Flushing the BIO should not crash.
6832 EXPECT_EQ(1, BIO_flush(client_bio.get()));
6833
6834 // Exchange some data.
6835 EXPECT_EQ(5, BIO_write(client_bio.get(), "hello", 5));
6836 uint8_t buf[5];
6837 ASSERT_EQ(5, SSL_read(server.get(), buf, sizeof(buf)));
6838 EXPECT_EQ(Bytes("hello"), Bytes(buf));
6839
6840 EXPECT_EQ(5, SSL_write(server.get(), "world", 5));
6841 ASSERT_EQ(5, BIO_read(client_bio.get(), buf, sizeof(buf)));
6842 EXPECT_EQ(Bytes("world"), Bytes(buf));
6843
6844 // |BIO_should_read| should work.
6845 EXPECT_EQ(-1, BIO_read(client_bio.get(), buf, sizeof(buf)));
6846 EXPECT_TRUE(BIO_should_read(client_bio.get()));
6847
6848 // Writing data should eventually exceed the buffer size and fail, reporting
6849 // |BIO_should_write|.
6850 int ret;
6851 for (int i = 0; i < 1024; i++) {
6852 std::vector<uint8_t> buffer(1024);
6853 ret = BIO_write(client_bio.get(), buffer.data(), buffer.size());
6854 if (ret <= 0) {
6855 break;
6856 }
6857 }
6858 EXPECT_EQ(-1, ret);
6859 EXPECT_TRUE(BIO_should_write(client_bio.get()));
6860 }
6861}
6862
David Benjamin12a3e7e2021-04-13 11:47:36 -04006863TEST(SSLTest, ALPNConfig) {
6864 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
6865 ASSERT_TRUE(ctx);
6866 bssl::UniquePtr<X509> cert = GetTestCertificate();
6867 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
6868 ASSERT_TRUE(cert);
6869 ASSERT_TRUE(key);
6870 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
6871 ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
6872
6873 // Set up some machinery to check the configured ALPN against what is actually
6874 // sent over the wire. Note that the ALPN callback is only called when the
6875 // client offers ALPN.
6876 std::vector<uint8_t> observed_alpn;
6877 SSL_CTX_set_alpn_select_cb(
6878 ctx.get(),
6879 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
6880 unsigned in_len, void *arg) -> int {
6881 std::vector<uint8_t> *observed_alpn_ptr =
6882 static_cast<std::vector<uint8_t> *>(arg);
6883 observed_alpn_ptr->assign(in, in + in_len);
6884 return SSL_TLSEXT_ERR_NOACK;
6885 },
6886 &observed_alpn);
6887 auto check_alpn_proto = [&](Span<const uint8_t> expected) {
6888 observed_alpn.clear();
6889 bssl::UniquePtr<SSL> client, server;
6890 EXPECT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
6891 EXPECT_EQ(Bytes(expected), Bytes(observed_alpn));
6892 };
6893
6894 // Note that |SSL_CTX_set_alpn_protos|'s return value is reversed.
6895 static const uint8_t kValidList[] = {0x03, 'f', 'o', 'o',
6896 0x03, 'b', 'a', 'r'};
6897 EXPECT_EQ(0,
6898 SSL_CTX_set_alpn_protos(ctx.get(), kValidList, sizeof(kValidList)));
6899 check_alpn_proto(kValidList);
6900
6901 // Invalid lists are rejected.
6902 static const uint8_t kInvalidList[] = {0x04, 'f', 'o', 'o'};
6903 EXPECT_EQ(1, SSL_CTX_set_alpn_protos(ctx.get(), kInvalidList,
6904 sizeof(kInvalidList)));
6905
6906 // Empty lists are valid and are interpreted as disabling ALPN.
6907 EXPECT_EQ(0, SSL_CTX_set_alpn_protos(ctx.get(), nullptr, 0));
6908 check_alpn_proto({});
6909}
6910
David Benjamin2f3958a2021-04-16 11:55:23 -04006911// Test that the key usage checker can correctly handle issuerUID and
6912// subjectUID. See https://crbug.com/1199744.
6913TEST(SSLTest, KeyUsageWithUIDs) {
6914 static const char kGoodKeyUsage[] = R"(
6915-----BEGIN CERTIFICATE-----
6916MIIB7DCCAZOgAwIBAgIJANlMBNpJfb/rMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYT
6917AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn
6918aXRzIFB0eSBMdGQwHhcNMTQwNDIzMjMyMTU3WhcNMTQwNTIzMjMyMTU3WjBFMQsw
6919CQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJu
6920ZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp
69214r9ln5e+Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsW
6922Ghz1HX7xlC1Lz3IiwYEEABI0VoIEABI0VqNgMF4wHQYDVR0OBBYEFKuE0qyrlfCC
6923ThZ4B1VXX+QmjYLRMB8GA1UdIwQYMBaAFKuE0qyrlfCCThZ4B1VXX+QmjYLRMA4G
6924A1UdDwEB/wQEAwIHgDAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0cAMEQCIEWJ
692534EcqW5MHwLIA1hZ2Tj/jV2QjN02KLxis9mFsqDKAiAMlMTkzsM51vVs9Ohqa+Rc
69264Z7qDhjIhiF4dM0uEDYRVA==
6927-----END CERTIFICATE-----
6928)";
6929 static const char kBadKeyUsage[] = R"(
6930-----BEGIN CERTIFICATE-----
6931MIIB7jCCAZOgAwIBAgIJANlMBNpJfb/rMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYT
6932AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn
6933aXRzIFB0eSBMdGQwHhcNMTQwNDIzMjMyMTU3WhcNMTQwNTIzMjMyMTU3WjBFMQsw
6934CQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJu
6935ZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp
69364r9ln5e+Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsW
6937Ghz1HX7xlC1Lz3IiwYEEABI0VoIEABI0VqNgMF4wHQYDVR0OBBYEFKuE0qyrlfCC
6938ThZ4B1VXX+QmjYLRMB8GA1UdIwQYMBaAFKuE0qyrlfCCThZ4B1VXX+QmjYLRMA4G
6939A1UdDwEB/wQEAwIDCDAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0kAMEYCIQC6
6940taYBUDu2gcZC6EMk79FBHArYI0ucF+kzvETegZCbBAIhANtObFec5gtso/47moPD
6941RHrQbWsFUakETXL9QMlegh5t
6942-----END CERTIFICATE-----
6943)";
6944
6945 bssl::UniquePtr<X509> good = CertFromPEM(kGoodKeyUsage);
6946 ASSERT_TRUE(good);
6947 bssl::UniquePtr<X509> bad = CertFromPEM(kBadKeyUsage);
6948 ASSERT_TRUE(bad);
6949
6950 // We check key usage when configuring EC certificates to distinguish ECDSA
6951 // and ECDH.
6952 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
6953 ASSERT_TRUE(ctx);
6954 EXPECT_TRUE(SSL_CTX_use_certificate(ctx.get(), good.get()));
6955 EXPECT_FALSE(SSL_CTX_use_certificate(ctx.get(), bad.get()));
6956}
6957
David Benjamin9b2cdb72021-04-01 23:21:53 -04006958// Test that |SSL_can_release_private_key| reports true as early as expected.
6959// The internal asserts in the library check we do not report true too early.
6960TEST(SSLTest, CanReleasePrivateKey) {
6961 bssl::UniquePtr<SSL_CTX> client_ctx =
6962 CreateContextWithTestCertificate(TLS_method());
6963 ASSERT_TRUE(client_ctx);
6964 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
6965
6966 // Note this assumes the transport buffer is large enough to fit the client
6967 // and server first flights. We check this with |SSL_ERROR_WANT_READ|. If the
6968 // transport buffer was too small it would return |SSL_ERROR_WANT_WRITE|.
6969 auto check_first_server_round_trip = [&](SSL *client, SSL *server) {
6970 // Write the ClientHello.
6971 ASSERT_EQ(-1, SSL_do_handshake(client));
6972 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client, -1));
6973
6974 // Consume the ClientHello and write the server flight.
6975 ASSERT_EQ(-1, SSL_do_handshake(server));
6976 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server, -1));
6977
6978 EXPECT_TRUE(SSL_can_release_private_key(server));
6979 };
6980
6981 {
6982 SCOPED_TRACE("TLS 1.2 ECDHE");
6983 bssl::UniquePtr<SSL_CTX> server_ctx(
6984 CreateContextWithTestCertificate(TLS_method()));
6985 ASSERT_TRUE(server_ctx);
6986 ASSERT_TRUE(
6987 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
6988 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
6989 server_ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
6990 // Configure the server to request client certificates, so we can also test
6991 // the client half.
6992 SSL_CTX_set_custom_verify(
6993 server_ctx.get(), SSL_VERIFY_PEER,
6994 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
6995 bssl::UniquePtr<SSL> client, server;
6996 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
6997 server_ctx.get()));
6998 check_first_server_round_trip(client.get(), server.get());
6999
7000 // Consume the server flight and write the client response. The client still
7001 // has a Finished message to consume but can also release its key early.
7002 ASSERT_EQ(-1, SSL_do_handshake(client.get()));
7003 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
7004 EXPECT_TRUE(SSL_can_release_private_key(client.get()));
7005
7006 // However, a client that has not disabled renegotiation can never release
7007 // the key.
7008 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7009 server_ctx.get()));
7010 SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_freely);
7011 check_first_server_round_trip(client.get(), server.get());
7012 ASSERT_EQ(-1, SSL_do_handshake(client.get()));
7013 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
7014 EXPECT_FALSE(SSL_can_release_private_key(client.get()));
7015 }
7016
7017 {
7018 SCOPED_TRACE("TLS 1.2 resumption");
7019 bssl::UniquePtr<SSL_CTX> server_ctx(
7020 CreateContextWithTestCertificate(TLS_method()));
7021 ASSERT_TRUE(server_ctx);
7022 ASSERT_TRUE(
7023 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
7024 bssl::UniquePtr<SSL_SESSION> session =
7025 CreateClientSession(client_ctx.get(), server_ctx.get());
7026 ASSERT_TRUE(session);
7027 bssl::UniquePtr<SSL> client, server;
7028 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7029 server_ctx.get()));
7030 SSL_set_session(client.get(), session.get());
7031 check_first_server_round_trip(client.get(), server.get());
7032 }
7033
7034 {
7035 SCOPED_TRACE("TLS 1.3 1-RTT");
7036 bssl::UniquePtr<SSL_CTX> server_ctx(
7037 CreateContextWithTestCertificate(TLS_method()));
7038 ASSERT_TRUE(server_ctx);
7039 ASSERT_TRUE(
7040 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
7041 bssl::UniquePtr<SSL> client, server;
7042 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7043 server_ctx.get()));
7044 check_first_server_round_trip(client.get(), server.get());
7045 }
7046
7047 {
7048 SCOPED_TRACE("TLS 1.3 resumption");
7049 bssl::UniquePtr<SSL_CTX> server_ctx(
7050 CreateContextWithTestCertificate(TLS_method()));
7051 ASSERT_TRUE(server_ctx);
7052 ASSERT_TRUE(
7053 SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
7054 bssl::UniquePtr<SSL_SESSION> session =
7055 CreateClientSession(client_ctx.get(), server_ctx.get());
7056 ASSERT_TRUE(session);
7057 bssl::UniquePtr<SSL> client, server;
7058 ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
7059 server_ctx.get()));
7060 SSL_set_session(client.get(), session.get());
7061 check_first_server_round_trip(client.get(), server.get());
7062 }
7063}
7064
Martin Kreichgauer72912d22017-08-04 12:06:43 -07007065} // namespace
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -07007066BSSL_NAMESPACE_END