blob: 8fbf698e28757c5f6d52fde7bb431b000b95d680 [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>
David Benjaminbb0a17c2014-09-20 15:35:39 -040032#include <openssl/err.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040033#include <openssl/hmac.h>
David Benjaminde942382016-02-11 12:02:01 -050034#include <openssl/pem.h>
David Benjamin25490f22016-07-14 00:22:54 -040035#include <openssl/sha.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040036#include <openssl/ssl.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040037#include <openssl/rand.h>
David Benjaminde942382016-02-11 12:02:01 -050038#include <openssl/x509.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040039
Steven Valdez87eab492016-06-27 16:34:59 -040040#include "internal.h"
Steven Valdezcb966542016-08-17 16:56:14 -040041#include "../crypto/internal.h"
Sigbjorn Vik2b23d242015-06-29 15:07:26 +020042#include "../crypto/test/test_util.h"
43
David Benjamin721e8b72016-08-03 13:13:17 -040044#if defined(OPENSSL_WINDOWS)
David Benjaminc11ea9422017-08-29 16:33:21 -040045// Windows defines struct timeval in winsock2.h.
David Benjamin721e8b72016-08-03 13:13:17 -040046OPENSSL_MSVC_PRAGMA(warning(push, 3))
47#include <winsock2.h>
48OPENSSL_MSVC_PRAGMA(warning(pop))
49#else
50#include <sys/time.h>
51#endif
52
David Benjamin5b33eff2018-09-22 16:52:48 -070053#if defined(OPENSSL_THREADS)
David Benjamin6c04bd12018-07-19 18:13:09 -040054#include <thread>
55#endif
56
David Benjamin1d77e562015-03-22 17:22:08 -040057
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -070058BSSL_NAMESPACE_BEGIN
Martin Kreichgauer72912d22017-08-04 12:06:43 -070059
60namespace {
61
Martin Kreichgauer1a663262017-08-16 14:54:04 -070062#define TRACED_CALL(code) \
63 do { \
64 SCOPED_TRACE("<- called from here"); \
65 code; \
66 if (::testing::Test::HasFatalFailure()) { \
67 return; \
68 } \
69 } while (false)
70
Martin Kreichgauer72912d22017-08-04 12:06:43 -070071struct VersionParam {
72 uint16_t version;
73 enum { is_tls, is_dtls } ssl_method;
74 const char name[8];
75};
76
77static const size_t kTicketKeyLen = 48;
78
79static const VersionParam kAllVersions[] = {
Martin Kreichgauer72912d22017-08-04 12:06:43 -070080 {TLS1_VERSION, VersionParam::is_tls, "TLS1"},
81 {TLS1_1_VERSION, VersionParam::is_tls, "TLS1_1"},
82 {TLS1_2_VERSION, VersionParam::is_tls, "TLS1_2"},
Martin Kreichgauer72912d22017-08-04 12:06:43 -070083 {TLS1_3_VERSION, VersionParam::is_tls, "TLS1_3"},
Martin Kreichgauer72912d22017-08-04 12:06:43 -070084 {DTLS1_VERSION, VersionParam::is_dtls, "DTLS1"},
85 {DTLS1_2_VERSION, VersionParam::is_dtls, "DTLS1_2"},
86};
87
David Benjamin1d77e562015-03-22 17:22:08 -040088struct ExpectedCipher {
89 unsigned long id;
David Benjaminbb0a17c2014-09-20 15:35:39 -040090 int in_group_flag;
David Benjamin1d77e562015-03-22 17:22:08 -040091};
David Benjaminbb0a17c2014-09-20 15:35:39 -040092
David Benjamin1d77e562015-03-22 17:22:08 -040093struct CipherTest {
94 // The rule string to apply.
David Benjaminbb0a17c2014-09-20 15:35:39 -040095 const char *rule;
David Benjaminfb974e62015-12-16 19:34:22 -050096 // The list of expected ciphers, in order.
97 std::vector<ExpectedCipher> expected;
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -080098 // True if this cipher list should fail in strict mode.
99 bool strict_fail;
David Benjamin1d77e562015-03-22 17:22:08 -0400100};
David Benjaminbb0a17c2014-09-20 15:35:39 -0400101
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100102struct CurveTest {
103 // The rule string to apply.
104 const char *rule;
105 // The list of expected curves, in order.
106 std::vector<uint16_t> expected;
107};
108
Steven Valdezc8e0f902018-07-14 11:23:01 -0400109template <typename T>
110class UnownedSSLExData {
111 public:
112 UnownedSSLExData() {
113 index_ = SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
114 }
115
116 T *Get(const SSL *ssl) {
117 return index_ < 0 ? nullptr
118 : static_cast<T *>(SSL_get_ex_data(ssl, index_));
119 }
120
121 bool Set(SSL *ssl, T *t) {
122 return index_ >= 0 && SSL_set_ex_data(ssl, index_, t);
123 }
124
125 private:
126 int index_;
127};
128
David Benjaminfb974e62015-12-16 19:34:22 -0500129static const CipherTest kCipherTests[] = {
130 // Selecting individual ciphers should work.
131 {
132 "ECDHE-ECDSA-CHACHA20-POLY1305:"
133 "ECDHE-RSA-CHACHA20-POLY1305:"
134 "ECDHE-ECDSA-AES128-GCM-SHA256:"
135 "ECDHE-RSA-AES128-GCM-SHA256",
136 {
137 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500138 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500139 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
140 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
141 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800142 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500143 },
144 // + reorders selected ciphers to the end, keeping their relative order.
145 {
146 "ECDHE-ECDSA-CHACHA20-POLY1305:"
147 "ECDHE-RSA-CHACHA20-POLY1305:"
148 "ECDHE-ECDSA-AES128-GCM-SHA256:"
149 "ECDHE-RSA-AES128-GCM-SHA256:"
150 "+aRSA",
151 {
152 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500153 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
154 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500155 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
156 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800157 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500158 },
159 // ! banishes ciphers from future selections.
160 {
161 "!aRSA:"
162 "ECDHE-ECDSA-CHACHA20-POLY1305:"
163 "ECDHE-RSA-CHACHA20-POLY1305:"
164 "ECDHE-ECDSA-AES128-GCM-SHA256:"
165 "ECDHE-RSA-AES128-GCM-SHA256",
166 {
167 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500168 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
169 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800170 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500171 },
172 // Multiple masks can be ANDed in a single rule.
173 {
174 "kRSA+AESGCM+AES128",
175 {
176 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
177 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800178 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500179 },
180 // - removes selected ciphers, but preserves their order for future
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700181 // selections. Select AES_128_GCM, but order the key exchanges RSA,
David Benjaminfb974e62015-12-16 19:34:22 -0500182 // ECDHE_RSA.
183 {
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700184 "ALL:-kECDHE:"
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700185 "-kRSA:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500186 "AESGCM+AES128+aRSA",
187 {
188 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500189 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
190 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800191 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500192 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800193 // Unknown selectors are no-ops, except in strict mode.
David Benjaminfb974e62015-12-16 19:34:22 -0500194 {
195 "ECDHE-ECDSA-CHACHA20-POLY1305:"
196 "ECDHE-RSA-CHACHA20-POLY1305:"
197 "ECDHE-ECDSA-AES128-GCM-SHA256:"
198 "ECDHE-RSA-AES128-GCM-SHA256:"
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800199 "BOGUS1",
David Benjaminfb974e62015-12-16 19:34:22 -0500200 {
201 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500202 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500203 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
204 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
205 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800206 true,
207 },
208 // Unknown selectors are no-ops, except in strict mode.
209 {
210 "ECDHE-ECDSA-CHACHA20-POLY1305:"
211 "ECDHE-RSA-CHACHA20-POLY1305:"
212 "ECDHE-ECDSA-AES128-GCM-SHA256:"
213 "ECDHE-RSA-AES128-GCM-SHA256:"
214 "-BOGUS2:+BOGUS3:!BOGUS4",
215 {
216 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
217 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
218 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
219 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
220 },
221 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500222 },
223 // Square brackets specify equi-preference groups.
224 {
225 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
226 "[ECDHE-RSA-CHACHA20-POLY1305]:"
227 "ECDHE-RSA-AES128-GCM-SHA256",
228 {
229 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
David Benjaminfb974e62015-12-16 19:34:22 -0500230 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley2e839242017-01-19 15:12:44 -0800231 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500232 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
233 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800234 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500235 },
David Benjamin6fff3862017-06-21 21:07:04 -0400236 // Standard names may be used instead of OpenSSL names.
237 {
238 "[TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256|"
David Benjaminbf5f1922017-07-01 11:13:53 -0400239 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256]:"
David Benjamin6fff3862017-06-21 21:07:04 -0400240 "[TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256]:"
241 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
242 {
243 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
244 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
245 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
246 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
247 },
248 false,
249 },
David Benjaminfb974e62015-12-16 19:34:22 -0500250 // @STRENGTH performs a stable strength-sort of the selected ciphers and
251 // only the selected ciphers.
252 {
253 // To simplify things, banish all but {ECDHE_RSA,RSA} x
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700254 // {CHACHA20,AES_256_CBC,AES_128_CBC} x SHA1.
David Benjamin6e678ee2018-04-16 19:54:42 -0400255 "!AESGCM:!3DES:"
David Benjaminfb974e62015-12-16 19:34:22 -0500256 // Order some ciphers backwards by strength.
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700257 "ALL:-CHACHA20:-AES256:-AES128:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500258 // Select ECDHE ones and sort them by strength. Ties should resolve
259 // based on the order above.
260 "kECDHE:@STRENGTH:-ALL:"
261 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
262 // by strength. Then RSA, backwards by strength.
263 "aRSA",
264 {
265 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
266 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500267 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500268 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
269 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
270 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800271 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500272 },
David Benjaminbf5f1922017-07-01 11:13:53 -0400273 // Additional masks after @STRENGTH get silently discarded.
274 //
275 // TODO(davidben): Make this an error. If not silently discarded, they get
276 // interpreted as + opcodes which are very different.
277 {
278 "ECDHE-RSA-AES128-GCM-SHA256:"
279 "ECDHE-RSA-AES256-GCM-SHA384:"
280 "@STRENGTH+AES256",
281 {
282 {TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
283 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
284 },
285 false,
286 },
287 {
288 "ECDHE-RSA-AES128-GCM-SHA256:"
289 "ECDHE-RSA-AES256-GCM-SHA384:"
290 "@STRENGTH+AES256:"
291 "ECDHE-RSA-CHACHA20-POLY1305",
292 {
293 {TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
294 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
295 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
296 },
297 false,
298 },
David Benjaminfb974e62015-12-16 19:34:22 -0500299 // Exact ciphers may not be used in multi-part rules; they are treated
300 // as unknown aliases.
301 {
302 "ECDHE-ECDSA-AES128-GCM-SHA256:"
303 "ECDHE-RSA-AES128-GCM-SHA256:"
304 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
305 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
306 {
307 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
308 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
309 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800310 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500311 },
312 // SSLv3 matches everything that existed before TLS 1.2.
313 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400314 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!SSLv3",
David Benjaminfb974e62015-12-16 19:34:22 -0500315 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400316 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500317 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800318 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500319 },
320 // TLSv1.2 matches everything added in TLS 1.2.
321 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400322 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!TLSv1.2",
David Benjaminfb974e62015-12-16 19:34:22 -0500323 {
324 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
325 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800326 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500327 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800328 // The two directives have no intersection. But each component is valid, so
329 // even in strict mode it is accepted.
David Benjaminfb974e62015-12-16 19:34:22 -0500330 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400331 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!TLSv1.2+SSLv3",
David Benjaminfb974e62015-12-16 19:34:22 -0500332 {
333 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400334 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500335 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800336 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500337 },
Adam Langley22df6912017-07-25 12:27:37 -0700338 // Spaces, semi-colons and commas are separators.
339 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400340 "AES128-SHA: ECDHE-RSA-AES128-GCM-SHA256 AES256-SHA ,ECDHE-ECDSA-AES128-GCM-SHA256 ; AES128-GCM-SHA256",
Adam Langley22df6912017-07-25 12:27:37 -0700341 {
342 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400343 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley22df6912017-07-25 12:27:37 -0700344 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400345 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley22df6912017-07-25 12:27:37 -0700346 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
347 },
348 // …but not in strict mode.
349 true,
350 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400351};
352
353static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400354 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400355 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
356 "RSA]",
357 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400358 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400359 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400360 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400361 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400362 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400363 "",
364 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400365 // COMPLEMENTOFDEFAULT is empty.
366 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400367 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400368 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400369 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400370 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
371 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
372 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
373 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
Adam Langleyf99f2442016-10-02 09:53:38 -0700374 // Opcode supplied, but missing selector.
375 "+",
Adam Langley22df6912017-07-25 12:27:37 -0700376 // Spaces are forbidden in equal-preference groups.
377 "[AES128-SHA | AES128-SHA256]",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400378};
379
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700380static const char *kMustNotIncludeNull[] = {
381 "ALL",
382 "DEFAULT",
David Benjamind6e9eec2015-11-18 09:48:55 -0500383 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700384 "FIPS",
385 "SHA",
386 "SHA1",
387 "RSA",
388 "SSLv3",
389 "TLSv1",
390 "TLSv1.2",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700391};
392
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100393static const CurveTest kCurveTests[] = {
394 {
395 "P-256",
396 { SSL_CURVE_SECP256R1 },
397 },
398 {
Adam Langley7b935932018-11-12 13:53:42 -0800399 "P-256:CECPQ2",
400 { SSL_CURVE_SECP256R1, SSL_CURVE_CECPQ2 },
401 },
402
403 {
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100404 "P-256:P-384:P-521:X25519",
405 {
406 SSL_CURVE_SECP256R1,
407 SSL_CURVE_SECP384R1,
408 SSL_CURVE_SECP521R1,
409 SSL_CURVE_X25519,
410 },
411 },
David Benjamin6dda1662017-11-02 20:44:26 -0400412 {
413 "prime256v1:secp384r1:secp521r1:x25519",
414 {
415 SSL_CURVE_SECP256R1,
416 SSL_CURVE_SECP384R1,
417 SSL_CURVE_SECP521R1,
418 SSL_CURVE_X25519,
419 },
420 },
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100421};
422
423static const char *kBadCurvesLists[] = {
424 "",
425 ":",
426 "::",
427 "P-256::X25519",
428 "RSA:P-256",
429 "P-256:RSA",
430 "X25519:P-256:",
431 ":X25519:P-256",
432};
433
David Benjamin70dbf042017-08-08 18:51:37 -0400434static std::string CipherListToString(SSL_CTX *ctx) {
David Benjamin1d77e562015-03-22 17:22:08 -0400435 bool in_group = false;
David Benjamine11726a2017-04-23 12:14:28 -0400436 std::string ret;
David Benjamin70dbf042017-08-08 18:51:37 -0400437 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
438 for (size_t i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
439 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
440 if (!in_group && SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400441 ret += "\t[\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400442 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400443 }
David Benjamine11726a2017-04-23 12:14:28 -0400444 ret += "\t";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400445 if (in_group) {
David Benjamine11726a2017-04-23 12:14:28 -0400446 ret += " ";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400447 }
David Benjamine11726a2017-04-23 12:14:28 -0400448 ret += SSL_CIPHER_get_name(cipher);
449 ret += "\n";
David Benjamin70dbf042017-08-08 18:51:37 -0400450 if (in_group && !SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400451 ret += "\t]\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400452 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400453 }
454 }
David Benjamine11726a2017-04-23 12:14:28 -0400455 return ret;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400456}
457
David Benjamin70dbf042017-08-08 18:51:37 -0400458static bool CipherListsEqual(SSL_CTX *ctx,
David Benjamine11726a2017-04-23 12:14:28 -0400459 const std::vector<ExpectedCipher> &expected) {
David Benjamin70dbf042017-08-08 18:51:37 -0400460 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
461 if (sk_SSL_CIPHER_num(ciphers) != expected.size()) {
David Benjamin1d77e562015-03-22 17:22:08 -0400462 return false;
David Benjamin65226252015-02-05 16:49:47 -0500463 }
464
David Benjamine11726a2017-04-23 12:14:28 -0400465 for (size_t i = 0; i < expected.size(); i++) {
David Benjamin70dbf042017-08-08 18:51:37 -0400466 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
David Benjamine11726a2017-04-23 12:14:28 -0400467 if (expected[i].id != SSL_CIPHER_get_id(cipher) ||
David Benjamin70dbf042017-08-08 18:51:37 -0400468 expected[i].in_group_flag != !!SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400469 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400470 }
471 }
472
David Benjamin1d77e562015-03-22 17:22:08 -0400473 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400474}
475
Daniel McArdleff746c12019-09-16 12:35:05 -0400476TEST(GrowableArrayTest, Resize) {
477 GrowableArray<size_t> array;
478 ASSERT_TRUE(array.empty());
479 EXPECT_EQ(array.size(), 0u);
480
481 ASSERT_TRUE(array.Push(42));
482 ASSERT_TRUE(!array.empty());
483 EXPECT_EQ(array.size(), 1u);
484
485 // Force a resize operation to occur
486 for (size_t i = 0; i < 16; i++) {
487 ASSERT_TRUE(array.Push(i + 1));
488 }
489
490 EXPECT_EQ(array.size(), 17u);
491
492 // Verify that expected values are still contained in array
493 for (size_t i = 0; i < array.size(); i++) {
494 EXPECT_EQ(array[i], i == 0 ? 42 : i);
495 }
496}
497
498TEST(GrowableArrayTest, MoveConstructor) {
499 GrowableArray<size_t> array;
500 for (size_t i = 0; i < 100; i++) {
501 ASSERT_TRUE(array.Push(i));
502 }
503
504 GrowableArray<size_t> array_moved(std::move(array));
505 for (size_t i = 0; i < 100; i++) {
506 EXPECT_EQ(array_moved[i], i);
507 }
508}
509
510TEST(GrowableArrayTest, GrowableArrayContainingGrowableArrays) {
511 // Representative example of a struct that contains a GrowableArray.
512 struct TagAndArray {
513 size_t tag;
514 GrowableArray<size_t> array;
515 };
516
517 GrowableArray<TagAndArray> array;
518 for (size_t i = 0; i < 100; i++) {
519 TagAndArray elem;
520 elem.tag = i;
521 for (size_t j = 0; j < i; j++) {
522 ASSERT_TRUE(elem.array.Push(j));
523 }
524 ASSERT_TRUE(array.Push(std::move(elem)));
525 }
526 EXPECT_EQ(array.size(), static_cast<size_t>(100));
527
528 GrowableArray<TagAndArray> array_moved(std::move(array));
529 EXPECT_EQ(array_moved.size(), static_cast<size_t>(100));
530 size_t count = 0;
531 for (const TagAndArray &elem : array_moved) {
532 // Test the square bracket operator returns the same value as iteration.
533 EXPECT_EQ(&elem, &array_moved[count]);
534
535 EXPECT_EQ(elem.tag, count);
536 EXPECT_EQ(elem.array.size(), count);
537 for (size_t j = 0; j < count; j++) {
538 EXPECT_EQ(elem.array[j], j);
539 }
540 count++;
541 }
542}
543
David Benjamine11726a2017-04-23 12:14:28 -0400544TEST(SSLTest, CipherRules) {
545 for (const CipherTest &t : kCipherTests) {
546 SCOPED_TRACE(t.rule);
547 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
548 ASSERT_TRUE(ctx);
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700549
David Benjamine11726a2017-04-23 12:14:28 -0400550 // Test lax mode.
551 ASSERT_TRUE(SSL_CTX_set_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400552 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400553 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400554 << CipherListToString(ctx.get());
David Benjamine11726a2017-04-23 12:14:28 -0400555
556 // Test strict mode.
557 if (t.strict_fail) {
558 EXPECT_FALSE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
559 } else {
560 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400561 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400562 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400563 << CipherListToString(ctx.get());
David Benjaminbb0a17c2014-09-20 15:35:39 -0400564 }
565 }
566
David Benjaminfb974e62015-12-16 19:34:22 -0500567 for (const char *rule : kBadRules) {
David Benjamine11726a2017-04-23 12:14:28 -0400568 SCOPED_TRACE(rule);
569 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
570 ASSERT_TRUE(ctx);
571
572 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), rule));
David Benjaminbb0a17c2014-09-20 15:35:39 -0400573 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400574 }
575
David Benjaminfb974e62015-12-16 19:34:22 -0500576 for (const char *rule : kMustNotIncludeNull) {
David Benjamine11726a2017-04-23 12:14:28 -0400577 SCOPED_TRACE(rule);
578 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
579 ASSERT_TRUE(ctx);
580
581 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400582 for (const SSL_CIPHER *cipher : SSL_CTX_get_ciphers(ctx.get())) {
David Benjamine3bb51c2017-08-22 23:16:02 -0700583 EXPECT_NE(NID_undef, SSL_CIPHER_get_cipher_nid(cipher));
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700584 }
585 }
David Benjaminbb0a17c2014-09-20 15:35:39 -0400586}
David Benjamin2e521212014-07-16 14:37:51 -0400587
David Benjamine11726a2017-04-23 12:14:28 -0400588TEST(SSLTest, CurveRules) {
589 for (const CurveTest &t : kCurveTests) {
590 SCOPED_TRACE(t.rule);
591 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
592 ASSERT_TRUE(ctx);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100593
David Benjamine11726a2017-04-23 12:14:28 -0400594 ASSERT_TRUE(SSL_CTX_set1_curves_list(ctx.get(), t.rule));
David Benjamin0ce090a2018-07-02 20:24:40 -0400595 ASSERT_EQ(t.expected.size(), ctx->supported_group_list.size());
David Benjamine11726a2017-04-23 12:14:28 -0400596 for (size_t i = 0; i < t.expected.size(); i++) {
597 EXPECT_EQ(t.expected[i], ctx->supported_group_list[i]);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100598 }
599 }
600
601 for (const char *rule : kBadCurvesLists) {
David Benjamine11726a2017-04-23 12:14:28 -0400602 SCOPED_TRACE(rule);
603 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
604 ASSERT_TRUE(ctx);
605
606 EXPECT_FALSE(SSL_CTX_set1_curves_list(ctx.get(), rule));
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100607 ERR_clear_error();
608 }
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100609}
610
Adam Langley364f7a62016-12-12 10:51:00 -0800611// kOpenSSLSession is a serialized SSL_SESSION.
Adam Langley10f97f32016-07-12 08:09:33 -0700612static const char kOpenSSLSession[] =
Adam Langley364f7a62016-12-12 10:51:00 -0800613 "MIIFqgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700614 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
615 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
616 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
617 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
618 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
619 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
620 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
621 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
622 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
623 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
624 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
625 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
626 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
627 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
628 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
629 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
630 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
631 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
632 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
633 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
634 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
635 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
636 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
637 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
638 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
639 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
640 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
641 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
642 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
Adam Langley364f7a62016-12-12 10:51:00 -0800643 "i4gv7Y5oliyntgMBAQA=";
Adam Langley10f97f32016-07-12 08:09:33 -0700644
645// kCustomSession is a custom serialized SSL_SESSION generated by
646// filling in missing fields from |kOpenSSLSession|. This includes
647// providing |peer_sha256|, so |peer| is not serialized.
648static const char kCustomSession[] =
David Benjamina8614602017-09-06 15:40:19 -0400649 "MIIBZAIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700650 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
David Benjamina8614602017-09-06 15:40:19 -0400651 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUqAcEBXdvcmxkqQUCAwGJwKqBpwSB"
652 "pBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38"
653 "VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd"
654 "3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hg"
655 "b+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYGBgYGBgYGBgYGBgYGBgYGBgYG"
656 "BgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
Adam Langley10f97f32016-07-12 08:09:33 -0700657
658// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
659static const char kBoringSSLSession[] =
660 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
661 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
662 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
663 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
664 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
665 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
666 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
667 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
668 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
669 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
670 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
671 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
672 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
673 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
674 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
675 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
676 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
677 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
678 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
679 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
680 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
681 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
682 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
683 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
684 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
685 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
686 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
687 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
688 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
689 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
690 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
691 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
692 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
693 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
694 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
695 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
696 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
697 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
698 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
699 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
700 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
701 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
702 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
703 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
704 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
705 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
706 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
707 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
708 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
709 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
710 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
711 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
712 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
713 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
714 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
715 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
716 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
717 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
718 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
719 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
720 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
721 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
722 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
723 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
724 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
725 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
726 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
727 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
728 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
729 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
730 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
731 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
732 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
733 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
734 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
735 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
736 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
737 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
738 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
739 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
740 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
741 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
742 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
743 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
744 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
745 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
746 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
747 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
748 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
749 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
750 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
751 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
752 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
753 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
754 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
755
756// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
757// the final (optional) element of |kCustomSession| with tag number 30.
758static const char kBadSessionExtraField[] =
759 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
760 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
761 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
762 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
763 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
764 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
765 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
766 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
767
768// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
769// the version of |kCustomSession| with 2.
770static const char kBadSessionVersion[] =
771 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
772 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
773 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
774 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
775 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
776 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
777 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
778 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
779
780// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
781// appended.
782static const char kBadSessionTrailingData[] =
783 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
784 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
785 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
786 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
787 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
788 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
789 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
790 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
791
David Benjamin1d77e562015-03-22 17:22:08 -0400792static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400793 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400794 if (!EVP_DecodedLength(&len, strlen(in))) {
795 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400796 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400797 }
798
David Benjamin1d77e562015-03-22 17:22:08 -0400799 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800800 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400801 strlen(in))) {
802 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400803 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400804 }
David Benjamin1d77e562015-03-22 17:22:08 -0400805 out->resize(len);
806 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400807}
808
David Benjamina486c6c2019-03-28 18:32:38 -0500809TEST(SSLTest, SessionEncoding) {
810 for (const char *input_b64 : {
811 kOpenSSLSession,
812 kCustomSession,
813 kBoringSSLSession,
814 }) {
815 SCOPED_TRACE(std::string(input_b64));
816 // Decode the input.
817 std::vector<uint8_t> input;
818 ASSERT_TRUE(DecodeBase64(&input, input_b64));
David Benjamin751e8892014-10-19 00:59:36 -0400819
David Benjamina486c6c2019-03-28 18:32:38 -0500820 // Verify the SSL_SESSION decodes.
821 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
822 ASSERT_TRUE(ssl_ctx);
823 bssl::UniquePtr<SSL_SESSION> session(
824 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
825 ASSERT_TRUE(session) << "SSL_SESSION_from_bytes failed";
826
827 // Verify the SSL_SESSION encoding round-trips.
828 size_t encoded_len;
829 bssl::UniquePtr<uint8_t> encoded;
830 uint8_t *encoded_raw;
831 ASSERT_TRUE(SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len))
832 << "SSL_SESSION_to_bytes failed";
833 encoded.reset(encoded_raw);
834 EXPECT_EQ(Bytes(encoded.get(), encoded_len), Bytes(input))
835 << "SSL_SESSION_to_bytes did not round-trip";
836
837 // Verify the SSL_SESSION also decodes with the legacy API.
838 const uint8_t *cptr = input.data();
839 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
840 ASSERT_TRUE(session) << "d2i_SSL_SESSION failed";
841 EXPECT_EQ(cptr, input.data() + input.size());
842
843 // Verify the SSL_SESSION encoding round-trips via the legacy API.
844 int len = i2d_SSL_SESSION(session.get(), NULL);
845 ASSERT_GT(len, 0) << "i2d_SSL_SESSION failed";
846 ASSERT_EQ(static_cast<size_t>(len), input.size())
847 << "i2d_SSL_SESSION(NULL) returned invalid length";
848
849 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
850 ASSERT_TRUE(encoded);
851
852 uint8_t *ptr = encoded.get();
853 len = i2d_SSL_SESSION(session.get(), &ptr);
854 ASSERT_GT(len, 0) << "i2d_SSL_SESSION failed";
855 ASSERT_EQ(static_cast<size_t>(len), input.size())
856 << "i2d_SSL_SESSION(NULL) returned invalid length";
857 ASSERT_EQ(ptr, encoded.get() + input.size())
858 << "i2d_SSL_SESSION did not advance ptr correctly";
859 EXPECT_EQ(Bytes(encoded.get(), encoded_len), Bytes(input))
860 << "SSL_SESSION_to_bytes did not round-trip";
David Benjamin751e8892014-10-19 00:59:36 -0400861 }
862
David Benjamina486c6c2019-03-28 18:32:38 -0500863 for (const char *input_b64 : {
864 kBadSessionExtraField,
865 kBadSessionVersion,
866 kBadSessionTrailingData,
867 }) {
868 SCOPED_TRACE(std::string(input_b64));
869 std::vector<uint8_t> input;
870 ASSERT_TRUE(DecodeBase64(&input, input_b64));
David Benjamin751e8892014-10-19 00:59:36 -0400871
David Benjamina486c6c2019-03-28 18:32:38 -0500872 // Verify that the SSL_SESSION fails to decode.
873 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
874 ASSERT_TRUE(ssl_ctx);
875 bssl::UniquePtr<SSL_SESSION> session(
876 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
877 EXPECT_FALSE(session) << "SSL_SESSION_from_bytes unexpectedly succeeded";
878 ERR_clear_error();
David Benjamin3cac4502014-10-21 01:46:30 -0400879 }
David Benjaminf297e022015-05-28 19:55:29 -0400880}
881
David Benjamin321fcdc2017-04-24 11:42:42 -0400882static void ExpectDefaultVersion(uint16_t min_version, uint16_t max_version,
883 const SSL_METHOD *(*method)(void)) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700884 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
David Benjamin321fcdc2017-04-24 11:42:42 -0400885 ASSERT_TRUE(ctx);
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -0700886 EXPECT_EQ(min_version, SSL_CTX_get_min_proto_version(ctx.get()));
887 EXPECT_EQ(max_version, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjamin321fcdc2017-04-24 11:42:42 -0400888}
889
890TEST(SSLTest, DefaultVersion) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -0800891 ExpectDefaultVersion(TLS1_VERSION, TLS1_3_VERSION, &TLS_method);
David Benjamin321fcdc2017-04-24 11:42:42 -0400892 ExpectDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method);
893 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method);
894 ExpectDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method);
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -0700895 ExpectDefaultVersion(DTLS1_VERSION, DTLS1_2_VERSION, &DTLS_method);
896 ExpectDefaultVersion(DTLS1_VERSION, DTLS1_VERSION, &DTLSv1_method);
897 ExpectDefaultVersion(DTLS1_2_VERSION, DTLS1_2_VERSION, &DTLSv1_2_method);
David Benjamin82c9e902014-12-12 15:55:27 -0500898}
899
David Benjamin348f0d82017-08-10 16:06:27 -0400900TEST(SSLTest, CipherProperties) {
David Benjamin6fff3862017-06-21 21:07:04 -0400901 static const struct {
902 int id;
903 const char *standard_name;
David Benjamin348f0d82017-08-10 16:06:27 -0400904 int cipher_nid;
905 int digest_nid;
906 int kx_nid;
907 int auth_nid;
David Benjaminb1b76ae2017-09-21 17:03:34 -0400908 int prf_nid;
David Benjamin6fff3862017-06-21 21:07:04 -0400909 } kTests[] = {
David Benjamin348f0d82017-08-10 16:06:27 -0400910 {
911 SSL3_CK_RSA_DES_192_CBC3_SHA,
912 "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
913 NID_des_ede3_cbc,
914 NID_sha1,
915 NID_kx_rsa,
916 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400917 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400918 },
919 {
920 TLS1_CK_RSA_WITH_AES_128_SHA,
921 "TLS_RSA_WITH_AES_128_CBC_SHA",
922 NID_aes_128_cbc,
923 NID_sha1,
924 NID_kx_rsa,
925 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400926 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400927 },
928 {
929 TLS1_CK_PSK_WITH_AES_256_CBC_SHA,
930 "TLS_PSK_WITH_AES_256_CBC_SHA",
931 NID_aes_256_cbc,
932 NID_sha1,
933 NID_kx_psk,
934 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400935 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400936 },
937 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400938 TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA,
939 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
David Benjamin348f0d82017-08-10 16:06:27 -0400940 NID_aes_128_cbc,
David Benjamin6e678ee2018-04-16 19:54:42 -0400941 NID_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400942 NID_kx_ecdhe,
943 NID_auth_rsa,
David Benjamin6e678ee2018-04-16 19:54:42 -0400944 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400945 },
946 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400947 TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA,
948 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
David Benjamin348f0d82017-08-10 16:06:27 -0400949 NID_aes_256_cbc,
David Benjamin6e678ee2018-04-16 19:54:42 -0400950 NID_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400951 NID_kx_ecdhe,
952 NID_auth_rsa,
David Benjamin6e678ee2018-04-16 19:54:42 -0400953 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400954 },
955 {
956 TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
957 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
958 NID_aes_128_gcm,
959 NID_undef,
960 NID_kx_ecdhe,
961 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400962 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400963 },
964 {
965 TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
966 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
967 NID_aes_128_gcm,
968 NID_undef,
969 NID_kx_ecdhe,
970 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400971 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400972 },
973 {
974 TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
975 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
976 NID_aes_256_gcm,
977 NID_undef,
978 NID_kx_ecdhe,
979 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400980 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -0400981 },
982 {
983 TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
984 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
985 NID_aes_128_cbc,
986 NID_sha1,
987 NID_kx_ecdhe,
988 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400989 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400990 },
991 {
992 TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
993 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
994 NID_chacha20_poly1305,
995 NID_undef,
996 NID_kx_ecdhe,
997 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400998 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400999 },
1000 {
1001 TLS1_CK_AES_256_GCM_SHA384,
1002 "TLS_AES_256_GCM_SHA384",
1003 NID_aes_256_gcm,
1004 NID_undef,
1005 NID_kx_any,
1006 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001007 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -04001008 },
1009 {
1010 TLS1_CK_AES_128_GCM_SHA256,
1011 "TLS_AES_128_GCM_SHA256",
1012 NID_aes_128_gcm,
1013 NID_undef,
1014 NID_kx_any,
1015 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001016 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -04001017 },
1018 {
1019 TLS1_CK_CHACHA20_POLY1305_SHA256,
1020 "TLS_CHACHA20_POLY1305_SHA256",
1021 NID_chacha20_poly1305,
1022 NID_undef,
1023 NID_kx_any,
1024 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -04001025 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -04001026 },
David Benjamin6fff3862017-06-21 21:07:04 -04001027 };
David Benjamin65226252015-02-05 16:49:47 -05001028
David Benjamin6fff3862017-06-21 21:07:04 -04001029 for (const auto &t : kTests) {
1030 SCOPED_TRACE(t.standard_name);
David Benjamine11726a2017-04-23 12:14:28 -04001031
1032 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(t.id & 0xffff);
1033 ASSERT_TRUE(cipher);
David Benjamin6fff3862017-06-21 21:07:04 -04001034 EXPECT_STREQ(t.standard_name, SSL_CIPHER_standard_name(cipher));
1035
David Benjamine11726a2017-04-23 12:14:28 -04001036 bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
1037 ASSERT_TRUE(rfc_name);
David Benjamin6fff3862017-06-21 21:07:04 -04001038 EXPECT_STREQ(t.standard_name, rfc_name.get());
David Benjamin348f0d82017-08-10 16:06:27 -04001039
1040 EXPECT_EQ(t.cipher_nid, SSL_CIPHER_get_cipher_nid(cipher));
1041 EXPECT_EQ(t.digest_nid, SSL_CIPHER_get_digest_nid(cipher));
1042 EXPECT_EQ(t.kx_nid, SSL_CIPHER_get_kx_nid(cipher));
1043 EXPECT_EQ(t.auth_nid, SSL_CIPHER_get_auth_nid(cipher));
David Benjaminb1b76ae2017-09-21 17:03:34 -04001044 EXPECT_EQ(t.prf_nid, SSL_CIPHER_get_prf_nid(cipher));
David Benjamin65226252015-02-05 16:49:47 -05001045 }
David Benjamin65226252015-02-05 16:49:47 -05001046}
1047
Steven Valdeza833c352016-11-01 13:39:36 -04001048// CreateSessionWithTicket returns a sample |SSL_SESSION| with the specified
1049// version and ticket length or nullptr on failure.
1050static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(uint16_t version,
1051 size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -04001052 std::vector<uint8_t> der;
1053 if (!DecodeBase64(&der, kOpenSSLSession)) {
1054 return nullptr;
1055 }
Adam Langley46db7af2017-02-01 15:49:37 -08001056
1057 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
1058 if (!ssl_ctx) {
1059 return nullptr;
1060 }
David Benjaminaaef8332018-06-29 16:45:49 -04001061 // Use a garbage ticket.
1062 std::vector<uint8_t> ticket(ticket_len, 'a');
Steven Valdeza833c352016-11-01 13:39:36 -04001063 bssl::UniquePtr<SSL_SESSION> session(
Adam Langley46db7af2017-02-01 15:49:37 -08001064 SSL_SESSION_from_bytes(der.data(), der.size(), ssl_ctx.get()));
David Benjaminaaef8332018-06-29 16:45:49 -04001065 if (!session ||
1066 !SSL_SESSION_set_protocol_version(session.get(), version) ||
1067 !SSL_SESSION_set_ticket(session.get(), ticket.data(), ticket.size())) {
David Benjamin422fe082015-07-21 22:03:43 -04001068 return nullptr;
1069 }
David Benjamin1269ddd2015-10-18 15:18:55 -04001070 // Fix up the timeout.
David Benjamin9b63f292016-11-15 00:44:05 -05001071#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
David Benjaminaaef8332018-06-29 16:45:49 -04001072 SSL_SESSION_set_time(session.get(), 1234);
David Benjamin9b63f292016-11-15 00:44:05 -05001073#else
David Benjaminaaef8332018-06-29 16:45:49 -04001074 SSL_SESSION_set_time(session.get(), time(nullptr));
David Benjamin9b63f292016-11-15 00:44:05 -05001075#endif
David Benjamin422fe082015-07-21 22:03:43 -04001076 return session;
1077}
1078
David Benjaminafc64de2016-07-19 17:12:41 +02001079static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001080 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +02001081 if (!bio) {
1082 return false;
1083 }
1084 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -04001085 BIO_up_ref(bio.get());
1086 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +02001087 int ret = SSL_connect(ssl);
1088 if (ret > 0) {
1089 // SSL_connect should fail without a BIO to write to.
1090 return false;
1091 }
1092 ERR_clear_error();
1093
1094 const uint8_t *client_hello;
1095 size_t client_hello_len;
1096 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
1097 return false;
1098 }
1099 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
1100 return true;
1101}
1102
Steven Valdeza833c352016-11-01 13:39:36 -04001103// GetClientHelloLen creates a client SSL connection with the specified version
1104// and ticket length. It returns the length of the ClientHello, not including
1105// the record header, on success and zero on error.
1106static size_t GetClientHelloLen(uint16_t max_version, uint16_t session_version,
1107 size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001108 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Steven Valdeza833c352016-11-01 13:39:36 -04001109 bssl::UniquePtr<SSL_SESSION> session =
1110 CreateSessionWithTicket(session_version, ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -04001111 if (!ctx || !session) {
1112 return 0;
1113 }
Steven Valdeza833c352016-11-01 13:39:36 -04001114
1115 // Set a one-element cipher list so the baseline ClientHello is unpadded.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001116 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
Steven Valdez2c62fe92016-10-14 12:08:12 -04001117 if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -08001118 !SSL_set_strict_cipher_list(ssl.get(), "ECDHE-RSA-AES128-GCM-SHA256") ||
Steven Valdeza833c352016-11-01 13:39:36 -04001119 !SSL_set_max_proto_version(ssl.get(), max_version)) {
David Benjamin422fe082015-07-21 22:03:43 -04001120 return 0;
1121 }
Steven Valdeza833c352016-11-01 13:39:36 -04001122
David Benjaminafc64de2016-07-19 17:12:41 +02001123 std::vector<uint8_t> client_hello;
1124 if (!GetClientHello(ssl.get(), &client_hello) ||
1125 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -04001126 return 0;
1127 }
Steven Valdeza833c352016-11-01 13:39:36 -04001128
David Benjaminafc64de2016-07-19 17:12:41 +02001129 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -04001130}
1131
David Benjamina486c6c2019-03-28 18:32:38 -05001132TEST(SSLTest, Padding) {
1133 struct PaddingVersions {
1134 uint16_t max_version, session_version;
1135 };
1136 static const PaddingVersions kPaddingVersions[] = {
1137 // Test the padding extension at TLS 1.2.
1138 {TLS1_2_VERSION, TLS1_2_VERSION},
1139 // Test the padding extension at TLS 1.3 with a TLS 1.2 session, so there
1140 // will be no PSK binder after the padding extension.
1141 {TLS1_3_VERSION, TLS1_2_VERSION},
1142 // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
1143 // will be a PSK binder after the padding extension.
1144 {TLS1_3_VERSION, TLS1_3_VERSION},
David Benjamin422fe082015-07-21 22:03:43 -04001145
David Benjamina486c6c2019-03-28 18:32:38 -05001146 };
David Benjamin422fe082015-07-21 22:03:43 -04001147
David Benjamina486c6c2019-03-28 18:32:38 -05001148 struct PaddingTest {
1149 size_t input_len, padded_len;
1150 };
1151 static const PaddingTest kPaddingTests[] = {
1152 // ClientHellos of length below 0x100 do not require padding.
1153 {0xfe, 0xfe},
1154 {0xff, 0xff},
1155 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
1156 {0x100, 0x200},
1157 {0x123, 0x200},
1158 {0x1fb, 0x200},
1159 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
1160 // padding extension takes a minimum of four bytes plus one required
1161 // content
1162 // byte. (To work around yet more server bugs, we avoid empty final
1163 // extensions.)
1164 {0x1fc, 0x201},
1165 {0x1fd, 0x202},
1166 {0x1fe, 0x203},
1167 {0x1ff, 0x204},
1168 // Finally, larger ClientHellos need no padding.
1169 {0x200, 0x200},
1170 {0x201, 0x201},
1171 };
David Benjamin422fe082015-07-21 22:03:43 -04001172
David Benjamina486c6c2019-03-28 18:32:38 -05001173 for (const PaddingVersions &versions : kPaddingVersions) {
1174 SCOPED_TRACE(versions.max_version);
1175 SCOPED_TRACE(versions.session_version);
David Benjamin422fe082015-07-21 22:03:43 -04001176
David Benjamina486c6c2019-03-28 18:32:38 -05001177 // Sample a baseline length.
1178 size_t base_len =
1179 GetClientHelloLen(versions.max_version, versions.session_version, 1);
1180 ASSERT_NE(base_len, 0u) << "Baseline length could not be sampled";
1181
1182 for (const PaddingTest &test : kPaddingTests) {
1183 SCOPED_TRACE(test.input_len);
1184 ASSERT_LE(base_len, test.input_len) << "Baseline ClientHello too long";
1185
1186 size_t padded_len =
1187 GetClientHelloLen(versions.max_version, versions.session_version,
1188 1 + test.input_len - base_len);
1189 EXPECT_EQ(padded_len, test.padded_len)
1190 << "ClientHello was not padded to expected length";
David Benjamin422fe082015-07-21 22:03:43 -04001191 }
1192 }
David Benjamin422fe082015-07-21 22:03:43 -04001193}
1194
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001195static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001196 static const char kCertPEM[] =
1197 "-----BEGIN CERTIFICATE-----\n"
1198 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1199 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1200 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1201 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1202 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1203 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1204 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1205 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1206 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1207 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1208 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1209 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1210 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1211 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001212 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
David Benjamin1444c3a2016-12-20 17:23:11 -05001213 return bssl::UniquePtr<X509>(
1214 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjaminde942382016-02-11 12:02:01 -05001215}
1216
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001217static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001218 static const char kKeyPEM[] =
1219 "-----BEGIN RSA PRIVATE KEY-----\n"
1220 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1221 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1222 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1223 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1224 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1225 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1226 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1227 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1228 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1229 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1230 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1231 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1232 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1233 "-----END RSA PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001234 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1235 return bssl::UniquePtr<EVP_PKEY>(
David Benjaminde942382016-02-11 12:02:01 -05001236 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1237}
1238
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001239static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001240 static const char kCertPEM[] =
1241 "-----BEGIN CERTIFICATE-----\n"
1242 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1243 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1244 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1245 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1246 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1247 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1248 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1249 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1250 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1251 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1252 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001253 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1254 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjamin0fc37ef2016-08-17 15:29:46 -04001255}
1256
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001257static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001258 static const char kKeyPEM[] =
1259 "-----BEGIN PRIVATE KEY-----\n"
1260 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1261 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1262 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1263 "-----END PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001264 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1265 return bssl::UniquePtr<EVP_PKEY>(
David Benjamin0fc37ef2016-08-17 15:29:46 -04001266 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1267}
1268
Adam Langleyd04ca952017-02-28 11:26:51 -08001269static bssl::UniquePtr<CRYPTO_BUFFER> BufferFromPEM(const char *pem) {
1270 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1271 char *name, *header;
1272 uint8_t *data;
1273 long data_len;
1274 if (!PEM_read_bio(bio.get(), &name, &header, &data,
1275 &data_len)) {
1276 return nullptr;
1277 }
1278 OPENSSL_free(name);
1279 OPENSSL_free(header);
1280
1281 auto ret = bssl::UniquePtr<CRYPTO_BUFFER>(
1282 CRYPTO_BUFFER_new(data, data_len, nullptr));
1283 OPENSSL_free(data);
1284 return ret;
1285}
1286
1287static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestCertificateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001288 static const char kCertPEM[] =
1289 "-----BEGIN CERTIFICATE-----\n"
1290 "MIIC0jCCAbqgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQiBD\n"
1291 "QTAeFw0xNjAyMjgyMDI3MDNaFw0yNjAyMjUyMDI3MDNaMBgxFjAUBgNVBAMMDUNs\n"
1292 "aWVudCBDZXJ0IEEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRvaz8\n"
1293 "CC/cshpCafJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/\n"
1294 "kLRcH89M/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3\n"
1295 "tHb+xs2PSs8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+c\n"
1296 "IDs2rQ+lP7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1\n"
1297 "z7C8jU50Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9V\n"
1298 "iLeXANgZi+Xx9KgfAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI\n"
1299 "KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBFEVbmYl+2RtNw\n"
1300 "rDftRDF1v2QUbcN2ouSnQDHxeDQdSgasLzT3ui8iYu0Rw2WWcZ0DV5e0ztGPhWq7\n"
1301 "AO0B120aFRMOY+4+bzu9Q2FFkQqc7/fKTvTDzIJI5wrMnFvUfzzvxh3OHWMYSs/w\n"
1302 "giq33hTKeHEq6Jyk3btCny0Ycecyc3yGXH10sizUfiHlhviCkDuESk8mFDwDDzqW\n"
1303 "ZF0IipzFbEDHoIxLlm3GQxpiLoEV4k8KYJp3R5KBLFyxM6UGPz8h72mIPCJp2RuK\n"
1304 "MYgF91UDvVzvnYm6TfseM2+ewKirC00GOrZ7rEcFvtxnKSqYf4ckqfNdSU1Y+RRC\n"
1305 "1ngWZ7Ih\n"
1306 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001307 return BufferFromPEM(kCertPEM);
David Benjamin1444c3a2016-12-20 17:23:11 -05001308}
1309
Adam Langleyd04ca952017-02-28 11:26:51 -08001310static bssl::UniquePtr<X509> X509FromBuffer(
1311 bssl::UniquePtr<CRYPTO_BUFFER> buffer) {
1312 if (!buffer) {
1313 return nullptr;
1314 }
1315 const uint8_t *derp = CRYPTO_BUFFER_data(buffer.get());
1316 return bssl::UniquePtr<X509>(
1317 d2i_X509(NULL, &derp, CRYPTO_BUFFER_len(buffer.get())));
1318}
1319
1320static bssl::UniquePtr<X509> GetChainTestCertificate() {
1321 return X509FromBuffer(GetChainTestCertificateBuffer());
1322}
1323
1324static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestIntermediateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001325 static const char kCertPEM[] =
1326 "-----BEGIN CERTIFICATE-----\n"
1327 "MIICwjCCAaqgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS\n"
1328 "b290IENBMB4XDTE2MDIyODIwMjcwM1oXDTI2MDIyNTIwMjcwM1owDzENMAsGA1UE\n"
1329 "AwwEQiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALsSCYmDip2D\n"
1330 "GkjFxw7ykz26JSjELkl6ArlYjFJ3aT/SCh8qbS4gln7RH8CPBd78oFdfhIKQrwtZ\n"
1331 "3/q21ykD9BAS3qHe2YdcJfm8/kWAy5DvXk6NXU4qX334KofBAEpgdA/igEFq1P1l\n"
1332 "HAuIfZCpMRfT+i5WohVsGi8f/NgpRvVaMONLNfgw57mz1lbtFeBEISmX0kbsuJxF\n"
1333 "Qj/Bwhi5/0HAEXG8e7zN4cEx0yPRvmOATRdVb/8dW2pwOHRJq9R5M0NUkIsTSnL7\n"
1334 "6N/z8hRAHMsV3IudC5Yd7GXW1AGu9a+iKU+Q4xcZCoj0DC99tL4VKujrV1kAeqsM\n"
1335 "cz5/dKzi6+cCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
1336 "AQYwDQYJKoZIhvcNAQELBQADggEBAIIeZiEeNhWWQ8Y4D+AGDwqUUeG8NjCbKrXQ\n"
1337 "BlHg5wZ8xftFaiP1Dp/UAezmx2LNazdmuwrYB8lm3FVTyaPDTKEGIPS4wJKHgqH1\n"
1338 "QPDhqNm85ey7TEtI9oYjsNim/Rb+iGkIAMXaxt58SzxbjvP0kMr1JfJIZbic9vye\n"
1339 "NwIspMFIpP3FB8ywyu0T0hWtCQgL4J47nigCHpOu58deP88fS/Nyz/fyGVWOZ76b\n"
1340 "WhWwgM3P3X95fQ3d7oFPR/bVh0YV+Cf861INwplokXgXQ3/TCQ+HNXeAMWn3JLWv\n"
1341 "XFwk8owk9dq/kQGdndGgy3KTEW4ctPX5GNhf3LJ9Q7dLji4ReQ4=\n"
1342 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001343 return BufferFromPEM(kCertPEM);
1344}
1345
1346static bssl::UniquePtr<X509> GetChainTestIntermediate() {
1347 return X509FromBuffer(GetChainTestIntermediateBuffer());
David Benjamin1444c3a2016-12-20 17:23:11 -05001348}
1349
1350static bssl::UniquePtr<EVP_PKEY> GetChainTestKey() {
1351 static const char kKeyPEM[] =
1352 "-----BEGIN PRIVATE KEY-----\n"
1353 "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRvaz8CC/cshpC\n"
1354 "afJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/kLRcH89M\n"
1355 "/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3tHb+xs2P\n"
1356 "Ss8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+cIDs2rQ+l\n"
1357 "P7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1z7C8jU50\n"
1358 "Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9ViLeXANgZ\n"
1359 "i+Xx9KgfAgMBAAECggEBAK0VjSJzkyPaamcyTVSWjo7GdaBGcK60lk657RjR+lK0\n"
1360 "YJ7pkej4oM2hdsVZFsP8Cs4E33nXLa/0pDsRov/qrp0WQm2skwqGMC1I/bZ0WRPk\n"
1361 "wHaDrBBfESWnJDX/AGpVtlyOjPmgmK6J2usMPihQUDkKdAYrVWJePrMIxt1q6BMe\n"
1362 "iczs3qriMmtY3bUc4UyUwJ5fhDLjshHvfuIpYQyI6EXZM6dZksn9LylXJnigY6QJ\n"
1363 "HxOYO0BDwOsZ8yQ8J8afLk88i0GizEkgE1z3REtQUwgWfxr1WV/ud+T6/ZhSAgH9\n"
1364 "042mQvSFZnIUSEsmCvjhWuAunfxHKCTcAoYISWfzWpkCgYEA7gpf3HHU5Tn+CgUn\n"
1365 "1X5uGpG3DmcMgfeGgs2r2f/IIg/5Ac1dfYILiybL1tN9zbyLCJfcbFpWBc9hJL6f\n"
1366 "CPc5hUiwWFJqBJewxQkC1Ae/HakHbip+IZ+Jr0842O4BAArvixk4Lb7/N2Ct9sTE\n"
1367 "NJO6RtK9lbEZ5uK61DglHy8CS2UCgYEA4ZC1o36kPAMQBggajgnucb2yuUEelk0f\n"
1368 "AEr+GI32MGE+93xMr7rAhBoqLg4AITyIfEnOSQ5HwagnIHonBbv1LV/Gf9ursx8Z\n"
1369 "YOGbvT8zzzC+SU1bkDzdjAYnFQVGIjMtKOBJ3K07++ypwX1fr4QsQ8uKL8WSOWwt\n"
1370 "Z3Bym6XiZzMCgYADnhy+2OwHX85AkLt+PyGlPbmuelpyTzS4IDAQbBa6jcuW/2wA\n"
1371 "UE2km75VUXmD+u2R/9zVuLm99NzhFhSMqlUxdV1YukfqMfP5yp1EY6m/5aW7QuIP\n"
1372 "2MDa7TVL9rIFMiVZ09RKvbBbQxjhuzPQKL6X/PPspnhiTefQ+dl2k9xREQKBgHDS\n"
1373 "fMfGNEeAEKezrfSVqxphE9/tXms3L+ZpnCaT+yu/uEr5dTIAawKoQ6i9f/sf1/Sy\n"
1374 "xedsqR+IB+oKrzIDDWMgoJybN4pkZ8E5lzhVQIjFjKgFdWLzzqyW9z1gYfABQPlN\n"
1375 "FiS20WX0vgP1vcKAjdNrHzc9zyHBpgQzDmAj3NZZAoGBAI8vKCKdH7w3aL5CNkZQ\n"
1376 "2buIeWNA2HZazVwAGG5F2TU/LmXfRKnG6dX5bkU+AkBZh56jNZy//hfFSewJB4Kk\n"
1377 "buB7ERSdaNbO21zXt9FEA3+z0RfMd/Zv2vlIWOSB5nzl/7UKti3sribK6s9ZVLfi\n"
1378 "SxpiPQ8d/hmSGwn4ksrWUsJD\n"
1379 "-----END PRIVATE KEY-----\n";
1380 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1381 return bssl::UniquePtr<EVP_PKEY>(
1382 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1383}
1384
David Benjaminc79ae7a2017-08-29 16:09:44 -04001385// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
1386// before configuring as a server.
1387TEST(SSLTest, ClientCAList) {
1388 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1389 ASSERT_TRUE(ctx);
1390 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1391 ASSERT_TRUE(ssl);
1392
1393 bssl::UniquePtr<X509_NAME> name(X509_NAME_new());
1394 ASSERT_TRUE(name);
1395
1396 bssl::UniquePtr<X509_NAME> name_dup(X509_NAME_dup(name.get()));
1397 ASSERT_TRUE(name_dup);
1398
1399 bssl::UniquePtr<STACK_OF(X509_NAME)> stack(sk_X509_NAME_new_null());
1400 ASSERT_TRUE(stack);
David Benjamin2908dd12018-06-29 17:46:42 -04001401 ASSERT_TRUE(PushToStack(stack.get(), std::move(name_dup)));
David Benjaminc79ae7a2017-08-29 16:09:44 -04001402
1403 // |SSL_set_client_CA_list| takes ownership.
1404 SSL_set_client_CA_list(ssl.get(), stack.release());
1405
1406 STACK_OF(X509_NAME) *result = SSL_get_client_CA_list(ssl.get());
1407 ASSERT_TRUE(result);
1408 ASSERT_EQ(1u, sk_X509_NAME_num(result));
1409 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(result, 0), name.get()));
1410}
1411
1412TEST(SSLTest, AddClientCA) {
1413 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1414 ASSERT_TRUE(ctx);
1415 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1416 ASSERT_TRUE(ssl);
1417
1418 bssl::UniquePtr<X509> cert1 = GetTestCertificate();
1419 bssl::UniquePtr<X509> cert2 = GetChainTestCertificate();
1420 ASSERT_TRUE(cert1 && cert2);
1421 X509_NAME *name1 = X509_get_subject_name(cert1.get());
1422 X509_NAME *name2 = X509_get_subject_name(cert2.get());
1423
1424 EXPECT_EQ(0u, sk_X509_NAME_num(SSL_get_client_CA_list(ssl.get())));
1425
1426 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1427 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert2.get()));
1428
1429 STACK_OF(X509_NAME) *list = SSL_get_client_CA_list(ssl.get());
1430 ASSERT_EQ(2u, sk_X509_NAME_num(list));
1431 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1432 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1433
1434 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1435
1436 list = SSL_get_client_CA_list(ssl.get());
1437 ASSERT_EQ(3u, sk_X509_NAME_num(list));
1438 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1439 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1440 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 2), name1));
1441}
1442
1443static void AppendSession(SSL_SESSION *session, void *arg) {
1444 std::vector<SSL_SESSION*> *out =
1445 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
1446 out->push_back(session);
1447}
1448
1449// CacheEquals returns true if |ctx|'s session cache consists of |expected|, in
1450// order.
1451static bool CacheEquals(SSL_CTX *ctx,
1452 const std::vector<SSL_SESSION*> &expected) {
1453 // Check the linked list.
1454 SSL_SESSION *ptr = ctx->session_cache_head;
1455 for (SSL_SESSION *session : expected) {
1456 if (ptr != session) {
1457 return false;
1458 }
1459 // TODO(davidben): This is an absurd way to denote the end of the list.
1460 if (ptr->next ==
1461 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
1462 ptr = nullptr;
1463 } else {
1464 ptr = ptr->next;
1465 }
1466 }
1467 if (ptr != nullptr) {
1468 return false;
1469 }
1470
1471 // Check the hash table.
1472 std::vector<SSL_SESSION*> actual, expected_copy;
David Benjamin9eaa3bd2017-09-27 17:03:54 -04001473 lh_SSL_SESSION_doall_arg(ctx->sessions, AppendSession, &actual);
David Benjaminc79ae7a2017-08-29 16:09:44 -04001474 expected_copy = expected;
1475
1476 std::sort(actual.begin(), actual.end());
1477 std::sort(expected_copy.begin(), expected_copy.end());
1478
1479 return actual == expected_copy;
1480}
1481
1482static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
1483 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
1484 if (!ssl_ctx) {
1485 return nullptr;
1486 }
1487 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new(ssl_ctx.get()));
1488 if (!ret) {
1489 return nullptr;
1490 }
1491
David Benjaminaaef8332018-06-29 16:45:49 -04001492 uint8_t id[SSL3_SSL_SESSION_ID_LENGTH] = {0};
1493 OPENSSL_memcpy(id, &number, sizeof(number));
1494 if (!SSL_SESSION_set1_id(ret.get(), id, sizeof(id))) {
1495 return nullptr;
1496 }
David Benjaminc79ae7a2017-08-29 16:09:44 -04001497 return ret;
1498}
1499
1500// Test that the internal session cache behaves as expected.
1501TEST(SSLTest, InternalSessionCache) {
1502 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1503 ASSERT_TRUE(ctx);
1504
1505 // Prepare 10 test sessions.
1506 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
1507 for (int i = 0; i < 10; i++) {
1508 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
1509 ASSERT_TRUE(session);
1510 sessions.push_back(std::move(session));
1511 }
1512
1513 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1514
1515 // Insert all the test sessions.
1516 for (const auto &session : sessions) {
1517 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), session.get()));
1518 }
1519
1520 // Only the last five should be in the list.
1521 ASSERT_TRUE(CacheEquals(
1522 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
1523 sessions[6].get(), sessions[5].get()}));
1524
1525 // Inserting an element already in the cache should fail and leave the cache
1526 // unchanged.
1527 ASSERT_FALSE(SSL_CTX_add_session(ctx.get(), sessions[7].get()));
1528 ASSERT_TRUE(CacheEquals(
1529 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
1530 sessions[6].get(), sessions[5].get()}));
1531
1532 // Although collisions should be impossible (256-bit session IDs), the cache
1533 // must handle them gracefully.
1534 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
1535 ASSERT_TRUE(collision);
1536 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), collision.get()));
1537 ASSERT_TRUE(CacheEquals(
1538 ctx.get(), {collision.get(), sessions[9].get(), sessions[8].get(),
1539 sessions[6].get(), sessions[5].get()}));
1540
1541 // Removing sessions behaves correctly.
1542 ASSERT_TRUE(SSL_CTX_remove_session(ctx.get(), sessions[6].get()));
1543 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
1544 sessions[8].get(), sessions[5].get()}));
1545
1546 // Removing sessions requires an exact match.
1547 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[0].get()));
1548 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[7].get()));
1549
1550 // The cache remains unchanged.
1551 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
1552 sessions[8].get(), sessions[5].get()}));
1553}
1554
1555static uint16_t EpochFromSequence(uint64_t seq) {
1556 return static_cast<uint16_t>(seq >> 48);
1557}
1558
David Benjamin71dfad42017-07-16 17:27:39 -04001559static const uint8_t kTestName[] = {
1560 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
1561 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
1562 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
1563 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
1564 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
1565 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64,
1566};
1567
David Benjaminb79cc842016-12-07 15:57:14 -05001568static bool CompleteHandshakes(SSL *client, SSL *server) {
1569 // Drive both their handshakes to completion.
1570 for (;;) {
1571 int client_ret = SSL_do_handshake(client);
1572 int client_err = SSL_get_error(client, client_ret);
1573 if (client_err != SSL_ERROR_NONE &&
1574 client_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001575 client_err != SSL_ERROR_WANT_WRITE &&
1576 client_err != SSL_ERROR_PENDING_TICKET) {
David Benjaminb79cc842016-12-07 15:57:14 -05001577 fprintf(stderr, "Client error: %d\n", client_err);
1578 return false;
1579 }
1580
1581 int server_ret = SSL_do_handshake(server);
1582 int server_err = SSL_get_error(server, server_ret);
1583 if (server_err != SSL_ERROR_NONE &&
1584 server_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001585 server_err != SSL_ERROR_WANT_WRITE &&
1586 server_err != SSL_ERROR_PENDING_TICKET) {
David Benjaminb79cc842016-12-07 15:57:14 -05001587 fprintf(stderr, "Server error: %d\n", server_err);
1588 return false;
1589 }
1590
1591 if (client_ret == 1 && server_ret == 1) {
1592 break;
1593 }
1594 }
1595
1596 return true;
1597}
1598
Steven Valdez777a2392019-02-21 11:30:47 -05001599static bool FlushNewSessionTickets(SSL *client, SSL *server) {
1600 // NewSessionTickets are deferred on the server to |SSL_write|, and clients do
1601 // not pick them up until |SSL_read|.
1602 for (;;) {
1603 int server_ret = SSL_write(server, nullptr, 0);
1604 int server_err = SSL_get_error(server, server_ret);
1605 // The server may either succeed (|server_ret| is zero) or block on write
1606 // (|server_ret| is -1 and |server_err| is |SSL_ERROR_WANT_WRITE|).
1607 if (server_ret > 0 ||
1608 (server_ret < 0 && server_err != SSL_ERROR_WANT_WRITE)) {
1609 fprintf(stderr, "Unexpected server result: %d %d\n", server_ret,
1610 server_err);
1611 return false;
1612 }
1613
1614 int client_ret = SSL_read(client, nullptr, 0);
1615 int client_err = SSL_get_error(client, client_ret);
1616 // The client must always block on read.
1617 if (client_ret != -1 || client_err != SSL_ERROR_WANT_READ) {
1618 fprintf(stderr, "Unexpected client result: %d %d\n", client_ret,
1619 client_err);
1620 return false;
1621 }
1622
1623 // The server flushed everything it had to write.
1624 if (server_ret == 0) {
1625 return true;
1626 }
1627 }
1628}
1629
David Benjamina8614602017-09-06 15:40:19 -04001630struct ClientConfig {
1631 SSL_SESSION *session = nullptr;
1632 std::string servername;
1633};
1634
David Benjaminb79cc842016-12-07 15:57:14 -05001635static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client,
1636 bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001637 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
Adam Langleyddb57cf2018-01-26 09:17:53 -08001638 const ClientConfig &config = ClientConfig(),
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001639 bool do_handshake = true,
1640 bool shed_handshake_config = true) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001641 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001642 if (!client || !server) {
1643 return false;
1644 }
1645 SSL_set_connect_state(client.get());
1646 SSL_set_accept_state(server.get());
1647
David Benjamina8614602017-09-06 15:40:19 -04001648 if (config.session) {
1649 SSL_set_session(client.get(), config.session);
1650 }
1651 if (!config.servername.empty() &&
1652 !SSL_set_tlsext_host_name(client.get(), config.servername.c_str())) {
1653 return false;
1654 }
David Benjamina20e5352016-08-02 19:09:41 -04001655
David Benjaminde942382016-02-11 12:02:01 -05001656 BIO *bio1, *bio2;
1657 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1658 return false;
1659 }
1660 // SSL_set_bio takes ownership.
1661 SSL_set_bio(client.get(), bio1, bio1);
1662 SSL_set_bio(server.get(), bio2, bio2);
1663
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001664 SSL_set_shed_handshake_config(client.get(), shed_handshake_config);
1665 SSL_set_shed_handshake_config(server.get(), shed_handshake_config);
1666
Adam Langleyddb57cf2018-01-26 09:17:53 -08001667 if (do_handshake && !CompleteHandshakes(client.get(), server.get())) {
David Benjaminb79cc842016-12-07 15:57:14 -05001668 return false;
David Benjaminde942382016-02-11 12:02:01 -05001669 }
1670
David Benjamin686bb192016-05-10 15:15:41 -04001671 *out_client = std::move(client);
1672 *out_server = std::move(server);
1673 return true;
1674}
1675
David Benjaminc11ea9422017-08-29 16:33:21 -04001676// SSLVersionTest executes its test cases under all available protocol versions.
1677// Test cases call |Connect| to create a connection using context objects with
1678// the protocol version fixed to the current version under test.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001679class SSLVersionTest : public ::testing::TestWithParam<VersionParam> {
1680 protected:
1681 SSLVersionTest() : cert_(GetTestCertificate()), key_(GetTestKey()) {}
1682
1683 void SetUp() { ResetContexts(); }
1684
1685 bssl::UniquePtr<SSL_CTX> CreateContext() const {
1686 const SSL_METHOD *method = is_dtls() ? DTLS_method() : TLS_method();
1687 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
1688 if (!ctx || !SSL_CTX_set_min_proto_version(ctx.get(), version()) ||
1689 !SSL_CTX_set_max_proto_version(ctx.get(), version())) {
1690 return nullptr;
1691 }
1692 return ctx;
David Benjamin0fef3052016-11-18 15:11:10 +09001693 }
David Benjamin686bb192016-05-10 15:15:41 -04001694
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001695 void ResetContexts() {
1696 ASSERT_TRUE(cert_);
1697 ASSERT_TRUE(key_);
1698 client_ctx_ = CreateContext();
1699 ASSERT_TRUE(client_ctx_);
1700 server_ctx_ = CreateContext();
1701 ASSERT_TRUE(server_ctx_);
1702 // Set up a server cert. Client certs can be set up explicitly.
1703 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09001704 }
David Benjamin686bb192016-05-10 15:15:41 -04001705
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001706 bool UseCertAndKey(SSL_CTX *ctx) const {
1707 return SSL_CTX_use_certificate(ctx, cert_.get()) &&
1708 SSL_CTX_use_PrivateKey(ctx, key_.get());
David Benjamin0fef3052016-11-18 15:11:10 +09001709 }
David Benjamin686bb192016-05-10 15:15:41 -04001710
David Benjamina8614602017-09-06 15:40:19 -04001711 bool Connect(const ClientConfig &config = ClientConfig()) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001712 return ConnectClientAndServer(&client_, &server_, client_ctx_.get(),
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001713 server_ctx_.get(), config, true,
1714 shed_handshake_config_);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001715 }
1716
1717 uint16_t version() const { return GetParam().version; }
1718
1719 bool is_dtls() const {
1720 return GetParam().ssl_method == VersionParam::is_dtls;
1721 }
1722
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001723 bool shed_handshake_config_ = true;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001724 bssl::UniquePtr<SSL> client_, server_;
1725 bssl::UniquePtr<SSL_CTX> server_ctx_, client_ctx_;
1726 bssl::UniquePtr<X509> cert_;
1727 bssl::UniquePtr<EVP_PKEY> key_;
1728};
1729
David Benjaminbe7006a2019-04-09 18:05:02 -05001730INSTANTIATE_TEST_SUITE_P(WithVersion, SSLVersionTest,
1731 testing::ValuesIn(kAllVersions),
1732 [](const testing::TestParamInfo<VersionParam> &i) {
1733 return i.param.name;
1734 });
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001735
1736TEST_P(SSLVersionTest, SequenceNumber) {
1737 ASSERT_TRUE(Connect());
1738
David Benjamin0fef3052016-11-18 15:11:10 +09001739 // Drain any post-handshake messages to ensure there are no unread records
1740 // on either end.
Steven Valdez777a2392019-02-21 11:30:47 -05001741 ASSERT_TRUE(FlushNewSessionTickets(client_.get(), server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05001742
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001743 uint64_t client_read_seq = SSL_get_read_sequence(client_.get());
1744 uint64_t client_write_seq = SSL_get_write_sequence(client_.get());
1745 uint64_t server_read_seq = SSL_get_read_sequence(server_.get());
1746 uint64_t server_write_seq = SSL_get_write_sequence(server_.get());
Steven Valdez2c62fe92016-10-14 12:08:12 -04001747
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001748 if (is_dtls()) {
David Benjamin0fef3052016-11-18 15:11:10 +09001749 // Both client and server must be at epoch 1.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001750 EXPECT_EQ(EpochFromSequence(client_read_seq), 1);
1751 EXPECT_EQ(EpochFromSequence(client_write_seq), 1);
1752 EXPECT_EQ(EpochFromSequence(server_read_seq), 1);
1753 EXPECT_EQ(EpochFromSequence(server_write_seq), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09001754
1755 // The next record to be written should exceed the largest received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001756 EXPECT_GT(client_write_seq, server_read_seq);
1757 EXPECT_GT(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09001758 } else {
1759 // The next record to be written should equal the next to be received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001760 EXPECT_EQ(client_write_seq, server_read_seq);
1761 EXPECT_EQ(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09001762 }
1763
1764 // Send a record from client to server.
Steven Valdez777a2392019-02-21 11:30:47 -05001765 uint8_t byte = 0;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001766 EXPECT_EQ(SSL_write(client_.get(), &byte, 1), 1);
1767 EXPECT_EQ(SSL_read(server_.get(), &byte, 1), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09001768
1769 // The client write and server read sequence numbers should have
1770 // incremented.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001771 EXPECT_EQ(client_write_seq + 1, SSL_get_write_sequence(client_.get()));
1772 EXPECT_EQ(server_read_seq + 1, SSL_get_read_sequence(server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05001773}
1774
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001775TEST_P(SSLVersionTest, OneSidedShutdown) {
David Benjamin68f37b72016-11-18 15:14:42 +09001776 // SSL_shutdown is a no-op in DTLS.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001777 if (is_dtls()) {
1778 return;
David Benjamin686bb192016-05-10 15:15:41 -04001779 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001780 ASSERT_TRUE(Connect());
David Benjamin686bb192016-05-10 15:15:41 -04001781
1782 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1783 // one side has shut down.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001784 ASSERT_EQ(SSL_shutdown(client_.get()), 0);
David Benjamin686bb192016-05-10 15:15:41 -04001785
1786 // Reading from the server should consume the EOF.
1787 uint8_t byte;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001788 ASSERT_EQ(SSL_read(server_.get(), &byte, 1), 0);
1789 ASSERT_EQ(SSL_get_error(server_.get(), 0), SSL_ERROR_ZERO_RETURN);
David Benjamin686bb192016-05-10 15:15:41 -04001790
1791 // However, the server may continue to write data and then shut down the
1792 // connection.
1793 byte = 42;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001794 ASSERT_EQ(SSL_write(server_.get(), &byte, 1), 1);
1795 ASSERT_EQ(SSL_read(client_.get(), &byte, 1), 1);
1796 ASSERT_EQ(byte, 42);
David Benjamin686bb192016-05-10 15:15:41 -04001797
1798 // The server may then shutdown the connection.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001799 EXPECT_EQ(SSL_shutdown(server_.get()), 1);
1800 EXPECT_EQ(SSL_shutdown(client_.get()), 1);
David Benjamin686bb192016-05-10 15:15:41 -04001801}
David Benjamin68f37b72016-11-18 15:14:42 +09001802
David Benjaminf0d8e222017-02-04 10:58:26 -05001803TEST(SSLTest, SessionDuplication) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001804 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1805 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001806 ASSERT_TRUE(client_ctx);
1807 ASSERT_TRUE(server_ctx);
Steven Valdez87eab492016-06-27 16:34:59 -04001808
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001809 bssl::UniquePtr<X509> cert = GetTestCertificate();
1810 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminf0d8e222017-02-04 10:58:26 -05001811 ASSERT_TRUE(cert);
1812 ASSERT_TRUE(key);
1813 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
1814 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04001815
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001816 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05001817 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04001818 server_ctx.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04001819
1820 SSL_SESSION *session0 = SSL_get_session(client.get());
David Benjamin31b0c9b2017-07-20 14:49:15 -04001821 bssl::UniquePtr<SSL_SESSION> session1 =
1822 bssl::SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL);
David Benjaminf0d8e222017-02-04 10:58:26 -05001823 ASSERT_TRUE(session1);
David Benjamin4501bd52016-08-01 13:39:41 -04001824
David Benjamina3a71e92018-06-29 13:24:45 -04001825 session1->not_resumable = false;
Steven Valdez84b5c002016-08-25 16:30:58 -04001826
Steven Valdez87eab492016-06-27 16:34:59 -04001827 uint8_t *s0_bytes, *s1_bytes;
1828 size_t s0_len, s1_len;
1829
David Benjaminf0d8e222017-02-04 10:58:26 -05001830 ASSERT_TRUE(SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001831 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001832
David Benjaminf0d8e222017-02-04 10:58:26 -05001833 ASSERT_TRUE(SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001834 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001835
David Benjamin7d7554b2017-02-04 11:48:59 -05001836 EXPECT_EQ(Bytes(s0_bytes, s0_len), Bytes(s1_bytes, s1_len));
Steven Valdez87eab492016-06-27 16:34:59 -04001837}
David Benjamin686bb192016-05-10 15:15:41 -04001838
David Benjaminf0d8e222017-02-04 10:58:26 -05001839static void ExpectFDs(const SSL *ssl, int rfd, int wfd) {
David Benjaminca743582017-06-15 17:51:35 -04001840 EXPECT_EQ(rfd, SSL_get_fd(ssl));
David Benjaminf0d8e222017-02-04 10:58:26 -05001841 EXPECT_EQ(rfd, SSL_get_rfd(ssl));
1842 EXPECT_EQ(wfd, SSL_get_wfd(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04001843
1844 // The wrapper BIOs are always equal when fds are equal, even if set
1845 // individually.
David Benjaminf0d8e222017-02-04 10:58:26 -05001846 if (rfd == wfd) {
1847 EXPECT_EQ(SSL_get_rbio(ssl), SSL_get_wbio(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04001848 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001849}
1850
David Benjaminf0d8e222017-02-04 10:58:26 -05001851TEST(SSLTest, SetFD) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001852 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001853 ASSERT_TRUE(ctx);
David Benjamin5c0fb882016-06-14 14:03:51 -04001854
1855 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001856 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001857 ASSERT_TRUE(ssl);
1858 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1859 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
1860 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04001861
1862 // Test setting the same FD.
1863 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001864 ASSERT_TRUE(ssl);
1865 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1866 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001867
1868 // Test setting the same FD one side at a time.
1869 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001870 ASSERT_TRUE(ssl);
1871 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1872 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1873 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001874
1875 // Test setting the same FD in the other order.
1876 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001877 ASSERT_TRUE(ssl);
1878 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1879 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1880 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001881
David Benjamin5c0fb882016-06-14 14:03:51 -04001882 // Test changing the read FD partway through.
1883 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001884 ASSERT_TRUE(ssl);
1885 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1886 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 2));
1887 ExpectFDs(ssl.get(), 2, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001888
1889 // Test changing the write FD partway through.
1890 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001891 ASSERT_TRUE(ssl);
1892 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1893 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
1894 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04001895
1896 // Test a no-op change to the read FD partway through.
1897 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001898 ASSERT_TRUE(ssl);
1899 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1900 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1901 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001902
1903 // Test a no-op change to the write FD partway through.
1904 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001905 ASSERT_TRUE(ssl);
1906 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1907 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1908 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001909
1910 // ASan builds will implicitly test that the internal |BIO| reference-counting
1911 // is correct.
David Benjamin5c0fb882016-06-14 14:03:51 -04001912}
1913
David Benjaminf0d8e222017-02-04 10:58:26 -05001914TEST(SSLTest, SetBIO) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001915 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001916 ASSERT_TRUE(ctx);
David Benjamin4501bd52016-08-01 13:39:41 -04001917
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001918 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1919 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04001920 bio3(BIO_new(BIO_s_mem()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001921 ASSERT_TRUE(ssl);
1922 ASSERT_TRUE(bio1);
1923 ASSERT_TRUE(bio2);
1924 ASSERT_TRUE(bio3);
David Benjamin4501bd52016-08-01 13:39:41 -04001925
1926 // SSL_set_bio takes one reference when the parameters are the same.
1927 BIO_up_ref(bio1.get());
1928 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1929
1930 // Repeating the call does nothing.
1931 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1932
1933 // It takes one reference each when the parameters are different.
1934 BIO_up_ref(bio2.get());
1935 BIO_up_ref(bio3.get());
1936 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1937
1938 // Repeating the call does nothing.
1939 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1940
1941 // It takes one reference when changing only wbio.
1942 BIO_up_ref(bio1.get());
1943 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1944
1945 // It takes one reference when changing only rbio and the two are different.
1946 BIO_up_ref(bio3.get());
1947 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1948
1949 // If setting wbio to rbio, it takes no additional references.
1950 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1951
1952 // From there, wbio may be switched to something else.
1953 BIO_up_ref(bio1.get());
1954 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1955
1956 // If setting rbio to wbio, it takes no additional references.
1957 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1958
1959 // From there, rbio may be switched to something else, but, for historical
1960 // reasons, it takes a reference to both parameters.
1961 BIO_up_ref(bio1.get());
1962 BIO_up_ref(bio2.get());
1963 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1964
1965 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1966 // is correct.
David Benjamin4501bd52016-08-01 13:39:41 -04001967}
1968
David Benjamin25490f22016-07-14 00:22:54 -04001969static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1970
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001971TEST_P(SSLVersionTest, GetPeerCertificate) {
1972 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04001973
David Benjamin0fef3052016-11-18 15:11:10 +09001974 // Configure both client and server to accept any certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001975 SSL_CTX_set_verify(client_ctx_.get(),
1976 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1977 nullptr);
1978 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
1979 SSL_CTX_set_verify(server_ctx_.get(),
1980 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1981 nullptr);
1982 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjaminadd5e522016-07-14 00:33:24 -04001983
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001984 ASSERT_TRUE(Connect());
David Benjaminadd5e522016-07-14 00:33:24 -04001985
David Benjamin0fef3052016-11-18 15:11:10 +09001986 // Client and server should both see the leaf certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001987 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1988 ASSERT_TRUE(peer);
1989 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04001990
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001991 peer.reset(SSL_get_peer_certificate(client_.get()));
1992 ASSERT_TRUE(peer);
1993 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04001994
David Benjamine664a532017-07-20 20:19:36 -04001995 // However, for historical reasons, the X509 chain includes the leaf on the
David Benjamin0fef3052016-11-18 15:11:10 +09001996 // client, but does not on the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001997 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(client_.get())), 1u);
1998 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(client_.get())),
1999 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04002000
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002001 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(server_.get())), 0u);
2002 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(server_.get())),
2003 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04002004}
2005
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002006TEST_P(SSLVersionTest, NoPeerCertificate) {
2007 SSL_CTX_set_verify(server_ctx_.get(), SSL_VERIFY_PEER, nullptr);
2008 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
2009 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
David Benjamine664a532017-07-20 20:19:36 -04002010
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002011 ASSERT_TRUE(Connect());
David Benjamine664a532017-07-20 20:19:36 -04002012
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002013 // Server should not see a peer certificate.
2014 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
2015 ASSERT_FALSE(peer);
2016 ASSERT_FALSE(SSL_get0_peer_certificates(server_.get()));
David Benjamine664a532017-07-20 20:19:36 -04002017}
2018
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002019TEST_P(SSLVersionTest, RetainOnlySHA256OfCerts) {
David Benjamin25490f22016-07-14 00:22:54 -04002020 uint8_t *cert_der = NULL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002021 int cert_der_len = i2d_X509(cert_.get(), &cert_der);
2022 ASSERT_GE(cert_der_len, 0);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002023 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04002024
2025 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
2026 SHA256(cert_der, cert_der_len, cert_sha256);
2027
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002028 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2029
David Benjamin0fef3052016-11-18 15:11:10 +09002030 // Configure both client and server to accept any certificate, but the
2031 // server must retain only the SHA-256 of the peer.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002032 SSL_CTX_set_verify(client_ctx_.get(),
2033 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2034 nullptr);
2035 SSL_CTX_set_verify(server_ctx_.get(),
2036 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2037 nullptr);
2038 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
2039 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
2040 SSL_CTX_set_retain_only_sha256_of_client_certs(server_ctx_.get(), 1);
David Benjamin25490f22016-07-14 00:22:54 -04002041
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002042 ASSERT_TRUE(Connect());
David Benjamin25490f22016-07-14 00:22:54 -04002043
David Benjamin0fef3052016-11-18 15:11:10 +09002044 // The peer certificate has been dropped.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002045 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
2046 EXPECT_FALSE(peer);
David Benjamin25490f22016-07-14 00:22:54 -04002047
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002048 SSL_SESSION *session = SSL_get_session(server_.get());
David Benjamin02de7bd2018-05-08 18:13:54 -04002049 EXPECT_TRUE(SSL_SESSION_has_peer_sha256(session));
David Benjamin25490f22016-07-14 00:22:54 -04002050
David Benjamin02de7bd2018-05-08 18:13:54 -04002051 const uint8_t *peer_sha256;
2052 size_t peer_sha256_len;
2053 SSL_SESSION_get0_peer_sha256(session, &peer_sha256, &peer_sha256_len);
2054 EXPECT_EQ(Bytes(cert_sha256), Bytes(peer_sha256, peer_sha256_len));
David Benjamin25490f22016-07-14 00:22:54 -04002055}
2056
David Benjamin737d2df2017-09-25 15:05:19 -04002057// Tests that our ClientHellos do not change unexpectedly. These are purely
2058// change detection tests. If they fail as part of an intentional ClientHello
2059// change, update the test vector.
2060TEST(SSLTest, ClientHello) {
2061 struct {
2062 uint16_t max_version;
2063 std::vector<uint8_t> expected;
2064 } kTests[] = {
David Benjamin737d2df2017-09-25 15:05:19 -04002065 {TLS1_VERSION,
2066 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x01, 0x00,
2067 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2068 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2069 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
2070 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
Adam Langleyd6680952018-08-23 08:01:23 -07002071 0x01, 0x00, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01,
2072 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
2073 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
David Benjamin737d2df2017-09-25 15:05:19 -04002074 {TLS1_1_VERSION,
2075 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x02, 0x00,
2076 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2077 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2078 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
2079 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
Adam Langleyd6680952018-08-23 08:01:23 -07002080 0x01, 0x00, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01,
2081 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
2082 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
David Benjamin737d2df2017-09-25 15:05:19 -04002083 {TLS1_2_VERSION,
David Benjamin6e678ee2018-04-16 19:54:42 -04002084 {0x16, 0x03, 0x01, 0x00, 0x82, 0x01, 0x00, 0x00, 0x7e, 0x03, 0x03, 0x00,
David Benjamin737d2df2017-09-25 15:05:19 -04002085 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2086 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
David Benjamin6e678ee2018-04-16 19:54:42 -04002087 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xcc, 0xa9,
David Benjamin737d2df2017-09-25 15:05:19 -04002088 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xc0, 0x09,
David Benjamin6e678ee2018-04-16 19:54:42 -04002089 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
Adam Langleyd6680952018-08-23 08:01:23 -07002090 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37, 0x00, 0x17, 0x00, 0x00,
2091 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00,
2092 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
2093 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04, 0x03, 0x08,
2094 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06,
2095 0x01, 0x02, 0x01}},
David Benjamin737d2df2017-09-25 15:05:19 -04002096 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
2097 // implementation has settled enough that it won't change.
David Benjaminafc64de2016-07-19 17:12:41 +02002098 };
David Benjamin737d2df2017-09-25 15:05:19 -04002099
2100 for (const auto &t : kTests) {
2101 SCOPED_TRACE(t.max_version);
2102
2103 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2104 ASSERT_TRUE(ctx);
2105 // Our default cipher list varies by CPU capabilities, so manually place the
2106 // ChaCha20 ciphers in front.
2107 const char *cipher_list = "CHACHA20:ALL";
David Benjamin737d2df2017-09-25 15:05:19 -04002108 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), t.max_version));
2109 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list));
2110
2111 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
2112 ASSERT_TRUE(ssl);
2113 std::vector<uint8_t> client_hello;
2114 ASSERT_TRUE(GetClientHello(ssl.get(), &client_hello));
2115
2116 // Zero the client_random.
2117 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
2118 1 + 3 + // handshake message header
2119 2; // client_version
2120 ASSERT_GE(client_hello.size(), kRandomOffset + SSL3_RANDOM_SIZE);
2121 OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
2122
2123 if (client_hello != t.expected) {
2124 ADD_FAILURE() << "ClientHellos did not match.";
2125 // Print the value manually so it is easier to update the test vector.
2126 for (size_t i = 0; i < client_hello.size(); i += 12) {
2127 printf(" %c", i == 0 ? '{' : ' ');
2128 for (size_t j = i; j < client_hello.size() && j < i + 12; j++) {
2129 if (j > i) {
2130 printf(" ");
2131 }
2132 printf("0x%02x", client_hello[j]);
2133 if (j < client_hello.size() - 1) {
2134 printf(",");
2135 }
2136 }
2137 if (i + 12 >= client_hello.size()) {
Adam Langleyd6680952018-08-23 08:01:23 -07002138 printf("}},");
David Benjamin737d2df2017-09-25 15:05:19 -04002139 }
2140 printf("\n");
2141 }
2142 }
David Benjaminafc64de2016-07-19 17:12:41 +02002143 }
David Benjaminafc64de2016-07-19 17:12:41 +02002144}
2145
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002146static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04002147
2148static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
2149 // Save the most recent session.
2150 g_last_session.reset(session);
2151 return 1;
2152}
2153
David Benjamina8614602017-09-06 15:40:19 -04002154static bssl::UniquePtr<SSL_SESSION> CreateClientSession(
2155 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2156 const ClientConfig &config = ClientConfig()) {
David Benjamina20e5352016-08-02 19:09:41 -04002157 g_last_session = nullptr;
2158 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2159
2160 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002161 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04002162 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
Steven Valdez777a2392019-02-21 11:30:47 -05002163 config) ||
2164 !FlushNewSessionTickets(client.get(), server.get())) {
David Benjamina20e5352016-08-02 19:09:41 -04002165 fprintf(stderr, "Failed to connect client and server.\n");
2166 return nullptr;
2167 }
2168
David Benjamina20e5352016-08-02 19:09:41 -04002169 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2170
2171 if (!g_last_session) {
2172 fprintf(stderr, "Client did not receive a session.\n");
2173 return nullptr;
2174 }
2175 return std::move(g_last_session);
2176}
2177
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002178static void ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2179 SSL_SESSION *session, bool want_reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002180 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002181 ClientConfig config;
2182 config.session = session;
2183 EXPECT_TRUE(
2184 ConnectClientAndServer(&client, &server, client_ctx, server_ctx, config));
David Benjamina20e5352016-08-02 19:09:41 -04002185
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002186 EXPECT_EQ(SSL_session_reused(client.get()), SSL_session_reused(server.get()));
David Benjamina20e5352016-08-02 19:09:41 -04002187
2188 bool was_reused = !!SSL_session_reused(client.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002189 EXPECT_EQ(was_reused, want_reused);
David Benjamina20e5352016-08-02 19:09:41 -04002190}
2191
David Benjamin3c51d9b2016-11-01 17:50:42 -04002192static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
2193 SSL_CTX *server_ctx,
2194 SSL_SESSION *session) {
2195 g_last_session = nullptr;
2196 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2197
2198 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002199 ClientConfig config;
2200 config.session = session;
2201 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
Steven Valdez777a2392019-02-21 11:30:47 -05002202 config) ||
2203 !FlushNewSessionTickets(client.get(), server.get())) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002204 fprintf(stderr, "Failed to connect client and server.\n");
2205 return nullptr;
2206 }
2207
2208 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2209 fprintf(stderr, "Client and server were inconsistent.\n");
2210 return nullptr;
2211 }
2212
2213 if (!SSL_session_reused(client.get())) {
2214 fprintf(stderr, "Session was not reused.\n");
2215 return nullptr;
2216 }
2217
David Benjamin3c51d9b2016-11-01 17:50:42 -04002218 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2219
2220 if (!g_last_session) {
2221 fprintf(stderr, "Client did not receive a renewed session.\n");
2222 return nullptr;
2223 }
2224 return std::move(g_last_session);
2225}
2226
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002227static void ExpectTicketKeyChanged(SSL_CTX *ctx, uint8_t *inout_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002228 bool changed) {
2229 uint8_t new_key[kTicketKeyLen];
David Benjaminc11ea9422017-08-29 16:33:21 -04002230 // May return 0, 1 or 48.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002231 ASSERT_EQ(SSL_CTX_get_tlsext_ticket_keys(ctx, new_key, kTicketKeyLen), 1);
2232 if (changed) {
2233 ASSERT_NE(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
2234 } else {
2235 ASSERT_EQ(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002236 }
2237 OPENSSL_memcpy(inout_key, new_key, kTicketKeyLen);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002238}
2239
David Benjamina933c382016-10-28 00:10:03 -04002240static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
2241 static const uint8_t kContext[] = {3};
2242
2243 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
2244 return SSL_TLSEXT_ERR_ALERT_FATAL;
2245 }
2246
2247 return SSL_TLSEXT_ERR_OK;
2248}
2249
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002250TEST_P(SSLVersionTest, SessionIDContext) {
David Benjamina20e5352016-08-02 19:09:41 -04002251 static const uint8_t kContext1[] = {1};
2252 static const uint8_t kContext2[] = {2};
2253
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002254 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2255 sizeof(kContext1)));
David Benjamina20e5352016-08-02 19:09:41 -04002256
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002257 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2258 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002259
David Benjamin0fef3052016-11-18 15:11:10 +09002260 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002261 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2262 ASSERT_TRUE(session);
David Benjamina20e5352016-08-02 19:09:41 -04002263
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002264 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2265 session.get(),
2266 true /* expect session reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002267
David Benjamin0fef3052016-11-18 15:11:10 +09002268 // Change the session ID context.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002269 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext2,
2270 sizeof(kContext2)));
David Benjamina20e5352016-08-02 19:09:41 -04002271
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002272 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2273 session.get(),
2274 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002275
David Benjamin0fef3052016-11-18 15:11:10 +09002276 // Change the session ID context back and install an SNI callback to switch
2277 // it.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002278 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2279 sizeof(kContext1)));
David Benjamina933c382016-10-28 00:10:03 -04002280
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002281 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09002282 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04002283
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002284 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2285 session.get(),
2286 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002287
David Benjamin0fef3052016-11-18 15:11:10 +09002288 // Switch the session ID context with the early callback instead.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002289 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), nullptr);
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002290 SSL_CTX_set_select_certificate_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002291 server_ctx_.get(),
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002292 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
2293 static const uint8_t kContext[] = {3};
2294
2295 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
2296 sizeof(kContext))) {
2297 return ssl_select_cert_error;
2298 }
2299
2300 return ssl_select_cert_success;
2301 });
David Benjamina933c382016-10-28 00:10:03 -04002302
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002303 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2304 session.get(),
2305 false /* expect session not reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002306}
2307
David Benjamin721e8b72016-08-03 13:13:17 -04002308static timeval g_current_time;
2309
2310static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2311 *out_clock = g_current_time;
2312}
2313
David Benjamin17b30832017-01-28 14:00:32 -05002314static void FrozenTimeCallback(const SSL *ssl, timeval *out_clock) {
2315 out_clock->tv_sec = 1000;
2316 out_clock->tv_usec = 0;
2317}
2318
David Benjamin3c51d9b2016-11-01 17:50:42 -04002319static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
2320 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
2321 int encrypt) {
2322 static const uint8_t kZeros[16] = {0};
2323
2324 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -05002325 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamin3c51d9b2016-11-01 17:50:42 -04002326 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -05002327 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002328 return 0;
2329 }
2330
2331 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
2332 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
2333 return -1;
2334 }
2335
2336 // Returning two from the callback in decrypt mode renews the
2337 // session in TLS 1.2 and below.
2338 return encrypt ? 1 : 2;
2339}
2340
David Benjamin123db572016-11-03 16:59:25 -04002341static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjaminaaef8332018-06-29 16:45:49 -04002342 const uint8_t *ticket;
2343 size_t ticket_len;
2344 SSL_SESSION_get0_ticket(session, &ticket, &ticket_len);
2345 if (ticket_len < 16 + 16 + SHA256_DIGEST_LENGTH) {
David Benjamin123db572016-11-03 16:59:25 -04002346 return false;
2347 }
2348
David Benjaminaaef8332018-06-29 16:45:49 -04002349 const uint8_t *ciphertext = ticket + 16 + 16;
2350 size_t len = ticket_len - 16 - 16 - SHA256_DIGEST_LENGTH;
David Benjamin123db572016-11-03 16:59:25 -04002351 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
2352
David Benjamin9b63f292016-11-15 00:44:05 -05002353#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
2354 // Fuzzer-mode tickets are unencrypted.
David Benjamin17cf2cb2016-12-13 01:07:13 -05002355 OPENSSL_memcpy(plaintext.get(), ciphertext, len);
David Benjamin9b63f292016-11-15 00:44:05 -05002356#else
2357 static const uint8_t kZeros[16] = {0};
David Benjaminaaef8332018-06-29 16:45:49 -04002358 const uint8_t *iv = ticket + 16;
David Benjamin123db572016-11-03 16:59:25 -04002359 bssl::ScopedEVP_CIPHER_CTX ctx;
2360 int len1, len2;
2361 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
2362 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
2363 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
2364 return false;
2365 }
2366
2367 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05002368#endif
David Benjamin123db572016-11-03 16:59:25 -04002369
Adam Langley46db7af2017-02-01 15:49:37 -08002370 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
2371 if (!ssl_ctx) {
2372 return false;
2373 }
David Benjamin123db572016-11-03 16:59:25 -04002374 bssl::UniquePtr<SSL_SESSION> server_session(
Adam Langley46db7af2017-02-01 15:49:37 -08002375 SSL_SESSION_from_bytes(plaintext.get(), len, ssl_ctx.get()));
David Benjamin123db572016-11-03 16:59:25 -04002376 if (!server_session) {
2377 return false;
2378 }
2379
David Benjaminaaef8332018-06-29 16:45:49 -04002380 *out = SSL_SESSION_get_time(server_session.get());
David Benjamin123db572016-11-03 16:59:25 -04002381 return true;
2382}
2383
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002384TEST_P(SSLVersionTest, SessionTimeout) {
2385 for (bool server_test : {false, true}) {
2386 SCOPED_TRACE(server_test);
David Benjamin721e8b72016-08-03 13:13:17 -04002387
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002388 ResetContexts();
2389 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2390 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
2391
David Benjamin17b30832017-01-28 14:00:32 -05002392 static const time_t kStartTime = 1000;
David Benjamin0fef3052016-11-18 15:11:10 +09002393 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002394
David Benjamin17b30832017-01-28 14:00:32 -05002395 // We are willing to use a longer lifetime for TLS 1.3 sessions as
2396 // resumptions still perform ECDHE.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002397 const time_t timeout = version() == TLS1_3_VERSION
David Benjamin17b30832017-01-28 14:00:32 -05002398 ? SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT
2399 : SSL_DEFAULT_SESSION_TIMEOUT;
2400
David Benjamin17b30832017-01-28 14:00:32 -05002401 // Both client and server must enforce session timeouts. We configure the
2402 // other side with a frozen clock so it never expires tickets.
David Benjamin0fef3052016-11-18 15:11:10 +09002403 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002404 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2405 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002406 } else {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002407 SSL_CTX_set_current_time_cb(client_ctx_.get(), CurrentTimeCallback);
2408 SSL_CTX_set_current_time_cb(server_ctx_.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002409 }
2410
2411 // Configure a ticket callback which renews tickets.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002412 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002413
2414 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002415 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2416 ASSERT_TRUE(session);
David Benjamin0fef3052016-11-18 15:11:10 +09002417
2418 // Advance the clock just behind the timeout.
David Benjamin17b30832017-01-28 14:00:32 -05002419 g_current_time.tv_sec += timeout - 1;
David Benjamin0fef3052016-11-18 15:11:10 +09002420
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002421 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2422 session.get(),
2423 true /* expect session reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002424
2425 // Advance the clock one more second.
2426 g_current_time.tv_sec++;
2427
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002428 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2429 session.get(),
2430 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002431
2432 // Rewind the clock to before the session was minted.
2433 g_current_time.tv_sec = kStartTime - 1;
2434
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002435 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2436 session.get(),
2437 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002438
David Benjamin0fef3052016-11-18 15:11:10 +09002439 // Renew the session 10 seconds before expiration.
David Benjamin17b30832017-01-28 14:00:32 -05002440 time_t new_start_time = kStartTime + timeout - 10;
2441 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002442 bssl::UniquePtr<SSL_SESSION> new_session = ExpectSessionRenewed(
2443 client_ctx_.get(), server_ctx_.get(), session.get());
2444 ASSERT_TRUE(new_session);
David Benjamin0fef3052016-11-18 15:11:10 +09002445
2446 // This new session is not the same object as before.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002447 EXPECT_NE(session.get(), new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002448
2449 // Check the sessions have timestamps measured from issuance.
2450 long session_time = 0;
2451 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002452 ASSERT_TRUE(GetServerTicketTime(&session_time, new_session.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09002453 } else {
David Benjaminaaef8332018-06-29 16:45:49 -04002454 session_time = SSL_SESSION_get_time(new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002455 }
David Benjamin721e8b72016-08-03 13:13:17 -04002456
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002457 ASSERT_EQ(session_time, g_current_time.tv_sec);
David Benjamin721e8b72016-08-03 13:13:17 -04002458
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002459 if (version() == TLS1_3_VERSION) {
David Benjamin17b30832017-01-28 14:00:32 -05002460 // Renewal incorporates fresh key material in TLS 1.3, so we extend the
2461 // lifetime TLS 1.3.
2462 g_current_time.tv_sec = new_start_time + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002463 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2464 new_session.get(),
2465 true /* expect session reused */));
David Benjamin721e8b72016-08-03 13:13:17 -04002466
David Benjamin17b30832017-01-28 14:00:32 -05002467 // The new session expires after the new timeout.
2468 g_current_time.tv_sec = new_start_time + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002469 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2470 new_session.get(),
2471 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002472
2473 // Renew the session until it begins just past the auth timeout.
2474 time_t auth_end_time = kStartTime + SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
2475 while (new_start_time < auth_end_time - 1000) {
2476 // Get as close as possible to target start time.
2477 new_start_time =
2478 std::min(auth_end_time - 1000, new_start_time + timeout - 1);
2479 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002480 new_session = ExpectSessionRenewed(client_ctx_.get(), server_ctx_.get(),
David Benjamin17b30832017-01-28 14:00:32 -05002481 new_session.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002482 ASSERT_TRUE(new_session);
David Benjamin17b30832017-01-28 14:00:32 -05002483 }
2484
2485 // Now the session's lifetime is bound by the auth timeout.
2486 g_current_time.tv_sec = auth_end_time - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002487 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2488 new_session.get(),
2489 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002490
2491 g_current_time.tv_sec = auth_end_time + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002492 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2493 new_session.get(),
2494 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002495 } else {
2496 // The new session is usable just before the old expiration.
2497 g_current_time.tv_sec = kStartTime + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002498 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2499 new_session.get(),
2500 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002501
2502 // Renewal does not extend the lifetime, so it is not usable beyond the
2503 // old expiration.
2504 g_current_time.tv_sec = kStartTime + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002505 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2506 new_session.get(),
2507 false /* expect session not reused */));
David Benjamin1b22f852016-10-27 16:36:32 -04002508 }
David Benjamin721e8b72016-08-03 13:13:17 -04002509 }
David Benjamin721e8b72016-08-03 13:13:17 -04002510}
2511
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002512TEST_P(SSLVersionTest, DefaultTicketKeyInitialization) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002513 static const uint8_t kZeroKey[kTicketKeyLen] = {};
2514 uint8_t ticket_key[kTicketKeyLen];
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002515 ASSERT_EQ(1, SSL_CTX_get_tlsext_ticket_keys(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002516 kTicketKeyLen));
2517 ASSERT_NE(0, OPENSSL_memcmp(ticket_key, kZeroKey, kTicketKeyLen));
2518}
2519
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002520TEST_P(SSLVersionTest, DefaultTicketKeyRotation) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002521 static const time_t kStartTime = 1001;
2522 g_current_time.tv_sec = kStartTime;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002523
David Benjaminc11ea9422017-08-29 16:33:21 -04002524 // We use session reuse as a proxy for ticket decryption success, hence
2525 // disable session timeouts.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002526 SSL_CTX_set_timeout(server_ctx_.get(), std::numeric_limits<uint32_t>::max());
2527 SSL_CTX_set_session_psk_dhe_timeout(server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002528 std::numeric_limits<uint32_t>::max());
2529
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002530 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2531 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002532
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002533 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2534 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_OFF);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002535
David Benjamin1f0d54b2018-08-09 16:19:13 -05002536 // Initialize ticket_key with the current key and check that it was
2537 // initialized to something, not all zeros.
2538 uint8_t ticket_key[kTicketKeyLen] = {0};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002539 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2540 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002541
David Benjaminc11ea9422017-08-29 16:33:21 -04002542 // Verify ticket resumption actually works.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002543 bssl::UniquePtr<SSL> client, server;
2544 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002545 CreateClientSession(client_ctx_.get(), server_ctx_.get());
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002546 ASSERT_TRUE(session);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002547 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002548 session.get(), true /* reused */));
2549
David Benjaminc11ea9422017-08-29 16:33:21 -04002550 // Advance time to just before key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002551 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002552 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002553 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002554 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002555 false /* NOT changed */));
2556
David Benjaminc11ea9422017-08-29 16:33:21 -04002557 // Force key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002558 g_current_time.tv_sec += 1;
2559 bssl::UniquePtr<SSL_SESSION> new_session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002560 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2561 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2562 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002563
David Benjaminc11ea9422017-08-29 16:33:21 -04002564 // Resumption with both old and new ticket should work.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002565 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002566 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002567 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002568 new_session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002569 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002570 false /* NOT changed */));
2571
David Benjaminc11ea9422017-08-29 16:33:21 -04002572 // Force key rotation again. Resumption with the old ticket now fails.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002573 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002574 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002575 session.get(), false /* NOT reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002576 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2577 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002578
David Benjaminc11ea9422017-08-29 16:33:21 -04002579 // But resumption with the newer session still works.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002580 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002581 new_session.get(), true /* reused */));
2582}
2583
David Benjamin0fc37ef2016-08-17 15:29:46 -04002584static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002585 SSL_CTX *ctx = reinterpret_cast<SSL_CTX *>(arg);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002586 SSL_set_SSL_CTX(ssl, ctx);
2587 return SSL_TLSEXT_ERR_OK;
2588}
2589
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002590TEST_P(SSLVersionTest, SNICallback) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002591 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002592 ASSERT_TRUE(cert2);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002593 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002594 ASSERT_TRUE(key2);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002595
David Benjamin0fef3052016-11-18 15:11:10 +09002596 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
2597 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002598
David Benjamin83a32122017-02-14 18:34:54 -05002599 static const uint8_t kSCTList[] = {0, 6, 0, 4, 5, 6, 7, 8};
2600 static const uint8_t kOCSPResponse[] = {1, 2, 3, 4};
2601
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002602 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
2603 ASSERT_TRUE(server_ctx2);
2604 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()));
2605 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()));
2606 ASSERT_TRUE(SSL_CTX_set_signed_cert_timestamp_list(
2607 server_ctx2.get(), kSCTList, sizeof(kSCTList)));
2608 ASSERT_TRUE(SSL_CTX_set_ocsp_response(server_ctx2.get(), kOCSPResponse,
2609 sizeof(kOCSPResponse)));
2610 // Historically signing preferences would be lost in some cases with the
2611 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2612 // this doesn't happen when |version| is TLS 1.2, configure the private
2613 // key to only sign SHA-256.
2614 ASSERT_TRUE(SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
2615 &kECDSAWithSHA256, 1));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002616
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002617 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), SwitchContext);
2618 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002619
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002620 SSL_CTX_enable_signed_cert_timestamps(client_ctx_.get());
2621 SSL_CTX_enable_ocsp_stapling(client_ctx_.get());
David Benjamin83a32122017-02-14 18:34:54 -05002622
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002623 ASSERT_TRUE(Connect());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002624
David Benjamin0fef3052016-11-18 15:11:10 +09002625 // The client should have received |cert2|.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002626 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client_.get()));
2627 ASSERT_TRUE(peer);
2628 EXPECT_EQ(X509_cmp(peer.get(), cert2.get()), 0);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002629
David Benjamin83a32122017-02-14 18:34:54 -05002630 // The client should have received |server_ctx2|'s SCT list.
2631 const uint8_t *data;
2632 size_t len;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002633 SSL_get0_signed_cert_timestamp_list(client_.get(), &data, &len);
2634 EXPECT_EQ(Bytes(kSCTList), Bytes(data, len));
David Benjamin83a32122017-02-14 18:34:54 -05002635
2636 // The client should have received |server_ctx2|'s OCSP response.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002637 SSL_get0_ocsp_response(client_.get(), &data, &len);
2638 EXPECT_EQ(Bytes(kOCSPResponse), Bytes(data, len));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002639}
2640
David Benjaminf0d8e222017-02-04 10:58:26 -05002641// Test that the early callback can swap the maximum version.
2642TEST(SSLTest, EarlyCallbackVersionSwitch) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002643 bssl::UniquePtr<X509> cert = GetTestCertificate();
2644 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2645 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2646 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002647 ASSERT_TRUE(cert);
2648 ASSERT_TRUE(key);
2649 ASSERT_TRUE(server_ctx);
2650 ASSERT_TRUE(client_ctx);
2651 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
2652 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
2653 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
2654 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
David Benjamin99620572016-08-30 00:35:36 -04002655
David Benjaminf0d8e222017-02-04 10:58:26 -05002656 SSL_CTX_set_select_certificate_cb(
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002657 server_ctx.get(),
2658 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
David Benjaminf0d8e222017-02-04 10:58:26 -05002659 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002660 return ssl_select_cert_error;
David Benjaminf0d8e222017-02-04 10:58:26 -05002661 }
2662
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002663 return ssl_select_cert_success;
David Benjaminf0d8e222017-02-04 10:58:26 -05002664 });
David Benjamin99620572016-08-30 00:35:36 -04002665
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002666 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05002667 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04002668 server_ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002669 EXPECT_EQ(TLS1_2_VERSION, SSL_version(client.get()));
David Benjamin99620572016-08-30 00:35:36 -04002670}
2671
David Benjaminf0d8e222017-02-04 10:58:26 -05002672TEST(SSLTest, SetVersion) {
David Benjamin2dc02042016-09-19 19:57:37 -04002673 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002674 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002675
David Benjaminf0d8e222017-02-04 10:58:26 -05002676 // Set valid TLS versions.
2677 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2678 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
2679 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2680 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002681
David Benjaminf0d8e222017-02-04 10:58:26 -05002682 // Invalid TLS versions are rejected.
2683 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2684 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x0200));
2685 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2686 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2687 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x0200));
2688 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002689
David Benjaminf0d8e222017-02-04 10:58:26 -05002690 // Zero is the default version.
2691 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08002692 EXPECT_EQ(TLS1_3_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002693 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07002694 EXPECT_EQ(TLS1_VERSION, SSL_CTX_get_min_proto_version(ctx.get()));
David Benjamin3cfeb952017-03-01 16:48:38 -05002695
David Benjamin9bb15f52018-06-26 00:07:40 -04002696 // TLS 1.3 is available, but not by default.
David Benjamin3cfeb952017-03-01 16:48:38 -05002697 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07002698 EXPECT_EQ(TLS1_3_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjamine34bcc92016-09-21 16:53:09 -04002699
David Benjamin9bb15f52018-06-26 00:07:40 -04002700 // SSL 3.0 is not available.
2701 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION));
2702
David Benjamin2dc02042016-09-19 19:57:37 -04002703 ctx.reset(SSL_CTX_new(DTLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002704 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002705
David Benjaminf0d8e222017-02-04 10:58:26 -05002706 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2707 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION));
2708 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2709 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002710
David Benjaminf0d8e222017-02-04 10:58:26 -05002711 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2712 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2713 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2714 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2715 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2716 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2717 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2718 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002719
David Benjaminf0d8e222017-02-04 10:58:26 -05002720 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07002721 EXPECT_EQ(DTLS1_2_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002722 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07002723 EXPECT_EQ(DTLS1_VERSION, SSL_CTX_get_min_proto_version(ctx.get()));
David Benjamin2dc02042016-09-19 19:57:37 -04002724}
2725
David Benjamin458334a2016-12-15 13:53:25 -05002726static const char *GetVersionName(uint16_t version) {
2727 switch (version) {
David Benjamin458334a2016-12-15 13:53:25 -05002728 case TLS1_VERSION:
2729 return "TLSv1";
2730 case TLS1_1_VERSION:
2731 return "TLSv1.1";
2732 case TLS1_2_VERSION:
2733 return "TLSv1.2";
2734 case TLS1_3_VERSION:
2735 return "TLSv1.3";
2736 case DTLS1_VERSION:
2737 return "DTLSv1";
2738 case DTLS1_2_VERSION:
2739 return "DTLSv1.2";
2740 default:
2741 return "???";
2742 }
2743}
2744
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002745TEST_P(SSLVersionTest, Version) {
2746 ASSERT_TRUE(Connect());
David Benjamincb18ac22016-09-27 14:09:15 -04002747
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002748 EXPECT_EQ(SSL_version(client_.get()), version());
2749 EXPECT_EQ(SSL_version(server_.get()), version());
David Benjamincb18ac22016-09-27 14:09:15 -04002750
David Benjamin458334a2016-12-15 13:53:25 -05002751 // Test the version name is reported as expected.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002752 const char *version_name = GetVersionName(version());
2753 EXPECT_EQ(strcmp(version_name, SSL_get_version(client_.get())), 0);
2754 EXPECT_EQ(strcmp(version_name, SSL_get_version(server_.get())), 0);
David Benjamin458334a2016-12-15 13:53:25 -05002755
2756 // Test SSL_SESSION reports the same name.
2757 const char *client_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002758 SSL_SESSION_get_version(SSL_get_session(client_.get()));
David Benjamin458334a2016-12-15 13:53:25 -05002759 const char *server_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002760 SSL_SESSION_get_version(SSL_get_session(server_.get()));
2761 EXPECT_EQ(strcmp(version_name, client_name), 0);
2762 EXPECT_EQ(strcmp(version_name, server_name), 0);
David Benjamincb18ac22016-09-27 14:09:15 -04002763}
2764
David Benjamin9ef31f02016-10-31 18:01:13 -04002765// Tests that that |SSL_get_pending_cipher| is available during the ALPN
2766// selection callback.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002767TEST_P(SSLVersionTest, ALPNCipherAvailable) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002768 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2769
David Benjamin9ef31f02016-10-31 18:01:13 -04002770 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002771 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
2772 sizeof(kALPNProtos)),
2773 0);
David Benjamin0fef3052016-11-18 15:11:10 +09002774
2775 // The ALPN callback does not fail the handshake on error, so have the
2776 // callback write a boolean.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002777 std::pair<uint16_t, bool> callback_state(version(), false);
David Benjamin0fef3052016-11-18 15:11:10 +09002778 SSL_CTX_set_alpn_select_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002779 server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09002780 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
2781 unsigned in_len, void *arg) -> int {
2782 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
2783 if (SSL_get_pending_cipher(ssl) != nullptr &&
2784 SSL_version(ssl) == state->first) {
2785 state->second = true;
2786 }
2787 return SSL_TLSEXT_ERR_NOACK;
2788 },
2789 &callback_state);
2790
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002791 ASSERT_TRUE(Connect());
David Benjamin0fef3052016-11-18 15:11:10 +09002792
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002793 ASSERT_TRUE(callback_state.second);
David Benjamin0fef3052016-11-18 15:11:10 +09002794}
2795
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002796TEST_P(SSLVersionTest, SSLClearSessionResumption) {
David Benjaminb79cc842016-12-07 15:57:14 -05002797 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
2798 // API pattern.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002799 if (version() == TLS1_3_VERSION) {
2800 return;
David Benjaminb79cc842016-12-07 15:57:14 -05002801 }
2802
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07002803 shed_handshake_config_ = false;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002804 ASSERT_TRUE(Connect());
David Benjaminb79cc842016-12-07 15:57:14 -05002805
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002806 EXPECT_FALSE(SSL_session_reused(client_.get()));
2807 EXPECT_FALSE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002808
2809 // Reset everything.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002810 ASSERT_TRUE(SSL_clear(client_.get()));
2811 ASSERT_TRUE(SSL_clear(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002812
2813 // Attempt to connect a second time.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002814 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002815
2816 // |SSL_clear| should implicitly offer the previous session to the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002817 EXPECT_TRUE(SSL_session_reused(client_.get()));
2818 EXPECT_TRUE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002819}
2820
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07002821TEST_P(SSLVersionTest, SSLClearFailsWithShedding) {
2822 shed_handshake_config_ = false;
2823 ASSERT_TRUE(Connect());
2824 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
2825
2826 // Reset everything.
2827 ASSERT_TRUE(SSL_clear(client_.get()));
2828 ASSERT_TRUE(SSL_clear(server_.get()));
2829
2830 // Now enable shedding, and connect a second time.
2831 shed_handshake_config_ = true;
2832 ASSERT_TRUE(Connect());
2833 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
2834
2835 // |SSL_clear| should now fail.
2836 ASSERT_FALSE(SSL_clear(client_.get()));
2837 ASSERT_FALSE(SSL_clear(server_.get()));
2838}
2839
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002840static bool ChainsEqual(STACK_OF(X509) * chain,
2841 const std::vector<X509 *> &expected) {
David Benjamin1444c3a2016-12-20 17:23:11 -05002842 if (sk_X509_num(chain) != expected.size()) {
2843 return false;
2844 }
2845
2846 for (size_t i = 0; i < expected.size(); i++) {
2847 if (X509_cmp(sk_X509_value(chain, i), expected[i]) != 0) {
2848 return false;
2849 }
2850 }
2851
2852 return true;
2853}
2854
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002855TEST_P(SSLVersionTest, AutoChain) {
2856 cert_ = GetChainTestCertificate();
2857 ASSERT_TRUE(cert_);
2858 key_ = GetChainTestKey();
2859 ASSERT_TRUE(key_);
David Benjamin1444c3a2016-12-20 17:23:11 -05002860 bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002861 ASSERT_TRUE(intermediate);
2862
2863 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2864 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin1444c3a2016-12-20 17:23:11 -05002865
2866 // Configure both client and server to accept any certificate. Add
2867 // |intermediate| to the cert store.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002868 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx_.get()),
2869 intermediate.get()));
2870 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(server_ctx_.get()),
2871 intermediate.get()));
2872 SSL_CTX_set_verify(client_ctx_.get(),
2873 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2874 nullptr);
2875 SSL_CTX_set_verify(server_ctx_.get(),
2876 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2877 nullptr);
2878 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
2879 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjamin1444c3a2016-12-20 17:23:11 -05002880
2881 // By default, the client and server should each only send the leaf.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002882 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002883
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002884 EXPECT_TRUE(
2885 ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()), {cert_.get()}));
2886 EXPECT_TRUE(
2887 ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()), {cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002888
2889 // If auto-chaining is enabled, then the intermediate is sent.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002890 SSL_CTX_clear_mode(client_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
2891 SSL_CTX_clear_mode(server_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
2892 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002893
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002894 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
2895 {cert_.get(), intermediate.get()}));
2896 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
2897 {cert_.get(), intermediate.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002898
2899 // Auto-chaining does not override explicitly-configured intermediates.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002900 ASSERT_TRUE(SSL_CTX_add1_chain_cert(client_ctx_.get(), cert_.get()));
2901 ASSERT_TRUE(SSL_CTX_add1_chain_cert(server_ctx_.get(), cert_.get()));
2902 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002903
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002904 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
2905 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002906
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002907 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
2908 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002909}
2910
David Benjamin48063c22017-01-01 23:56:36 -05002911static bool ExpectBadWriteRetry() {
2912 int err = ERR_get_error();
2913 if (ERR_GET_LIB(err) != ERR_LIB_SSL ||
2914 ERR_GET_REASON(err) != SSL_R_BAD_WRITE_RETRY) {
2915 char buf[ERR_ERROR_STRING_BUF_LEN];
2916 ERR_error_string_n(err, buf, sizeof(buf));
2917 fprintf(stderr, "Wanted SSL_R_BAD_WRITE_RETRY, got: %s.\n", buf);
2918 return false;
2919 }
2920
2921 if (ERR_peek_error() != 0) {
2922 fprintf(stderr, "Unexpected error following SSL_R_BAD_WRITE_RETRY.\n");
2923 return false;
2924 }
2925
2926 return true;
2927}
2928
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002929TEST_P(SSLVersionTest, SSLWriteRetry) {
2930 if (is_dtls()) {
2931 return;
David Benjamin48063c22017-01-01 23:56:36 -05002932 }
2933
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002934 for (bool enable_partial_write : {false, true}) {
2935 SCOPED_TRACE(enable_partial_write);
2936
David Benjamin48063c22017-01-01 23:56:36 -05002937 // Connect a client and server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002938 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2939
2940 ASSERT_TRUE(Connect());
David Benjamin48063c22017-01-01 23:56:36 -05002941
2942 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002943 SSL_set_mode(client_.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002944 }
2945
2946 // Write without reading until the buffer is full and we have an unfinished
2947 // write. Keep a count so we may reread it again later. "hello!" will be
2948 // written in two chunks, "hello" and "!".
2949 char data[] = "hello!";
2950 static const int kChunkLen = 5; // The length of "hello".
2951 unsigned count = 0;
2952 for (;;) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002953 int ret = SSL_write(client_.get(), data, kChunkLen);
David Benjamin48063c22017-01-01 23:56:36 -05002954 if (ret <= 0) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002955 ASSERT_EQ(SSL_get_error(client_.get(), ret), SSL_ERROR_WANT_WRITE);
2956 break;
David Benjamin48063c22017-01-01 23:56:36 -05002957 }
2958
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002959 ASSERT_EQ(ret, 5);
David Benjamin48063c22017-01-01 23:56:36 -05002960
2961 count++;
2962 }
2963
2964 // Retrying with the same parameters is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002965 ASSERT_EQ(
2966 SSL_get_error(client_.get(), SSL_write(client_.get(), data, kChunkLen)),
2967 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002968
2969 // Retrying with the same buffer but shorter length is not legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002970 ASSERT_EQ(SSL_get_error(client_.get(),
2971 SSL_write(client_.get(), data, kChunkLen - 1)),
2972 SSL_ERROR_SSL);
2973 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002974
2975 // Retrying with a different buffer pointer is not legal.
2976 char data2[] = "hello";
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002977 ASSERT_EQ(SSL_get_error(client_.get(),
2978 SSL_write(client_.get(), data2, kChunkLen)),
2979 SSL_ERROR_SSL);
2980 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002981
2982 // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002983 SSL_set_mode(client_.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
2984 ASSERT_EQ(SSL_get_error(client_.get(),
2985 SSL_write(client_.get(), data2, kChunkLen)),
2986 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002987
2988 // |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| does not disable length checks.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002989 ASSERT_EQ(SSL_get_error(client_.get(),
2990 SSL_write(client_.get(), data2, kChunkLen - 1)),
2991 SSL_ERROR_SSL);
2992 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002993
2994 // Retrying with a larger buffer is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002995 ASSERT_EQ(SSL_get_error(client_.get(),
2996 SSL_write(client_.get(), data, kChunkLen + 1)),
2997 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002998
2999 // Drain the buffer.
3000 char buf[20];
3001 for (unsigned i = 0; i < count; i++) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003002 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
3003 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
David Benjamin48063c22017-01-01 23:56:36 -05003004 }
3005
3006 // Now that there is space, a retry with a larger buffer should flush the
3007 // pending record, skip over that many bytes of input (on assumption they
3008 // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE
3009 // is set, this will complete in two steps.
3010 char data3[] = "_____!";
3011 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003012 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen);
3013 ASSERT_EQ(SSL_write(client_.get(), data3 + kChunkLen, 1), 1);
3014 } else {
3015 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen + 1);
David Benjamin48063c22017-01-01 23:56:36 -05003016 }
3017
3018 // Check the last write was correct. The data will be spread over two
3019 // records, so SSL_read returns twice.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003020 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
3021 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
3022 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), 1);
3023 ASSERT_EQ(buf[0], '!');
David Benjamin48063c22017-01-01 23:56:36 -05003024 }
David Benjamin48063c22017-01-01 23:56:36 -05003025}
3026
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003027TEST_P(SSLVersionTest, RecordCallback) {
3028 for (bool test_server : {true, false}) {
3029 SCOPED_TRACE(test_server);
3030 ResetContexts();
David Benjamin5df5be12017-06-22 19:43:11 -04003031
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003032 bool read_seen = false;
3033 bool write_seen = false;
3034 auto cb = [&](int is_write, int cb_version, int cb_type, const void *buf,
3035 size_t len, SSL *ssl) {
3036 if (cb_type != SSL3_RT_HEADER) {
3037 return;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003038 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003039
3040 // The callback does not report a version for records.
3041 EXPECT_EQ(0, cb_version);
3042
3043 if (is_write) {
3044 write_seen = true;
3045 } else {
3046 read_seen = true;
3047 }
3048
3049 // Sanity-check that the record header is plausible.
3050 CBS cbs;
3051 CBS_init(&cbs, reinterpret_cast<const uint8_t *>(buf), len);
3052 uint8_t type;
3053 uint16_t record_version, length;
3054 ASSERT_TRUE(CBS_get_u8(&cbs, &type));
3055 ASSERT_TRUE(CBS_get_u16(&cbs, &record_version));
Steven Valdez64cc1212017-12-04 11:15:37 -05003056 EXPECT_EQ(record_version & 0xff00, version() & 0xff00);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003057 if (is_dtls()) {
3058 uint16_t epoch;
3059 ASSERT_TRUE(CBS_get_u16(&cbs, &epoch));
3060 EXPECT_TRUE(epoch == 0 || epoch == 1) << "Invalid epoch: " << epoch;
3061 ASSERT_TRUE(CBS_skip(&cbs, 6));
3062 }
3063 ASSERT_TRUE(CBS_get_u16(&cbs, &length));
3064 EXPECT_EQ(0u, CBS_len(&cbs));
3065 };
3066 using CallbackType = decltype(cb);
3067 SSL_CTX *ctx = test_server ? server_ctx_.get() : client_ctx_.get();
3068 SSL_CTX_set_msg_callback(
3069 ctx, [](int is_write, int cb_version, int cb_type, const void *buf,
3070 size_t len, SSL *ssl, void *arg) {
3071 CallbackType *cb_ptr = reinterpret_cast<CallbackType *>(arg);
3072 (*cb_ptr)(is_write, cb_version, cb_type, buf, len, ssl);
3073 });
3074 SSL_CTX_set_msg_callback_arg(ctx, &cb);
3075
3076 ASSERT_TRUE(Connect());
3077
3078 EXPECT_TRUE(read_seen);
3079 EXPECT_TRUE(write_seen);
David Benjamin0fef3052016-11-18 15:11:10 +09003080 }
David Benjamin9ef31f02016-10-31 18:01:13 -04003081}
3082
David Benjamina8614602017-09-06 15:40:19 -04003083TEST_P(SSLVersionTest, GetServerName) {
David Benjamina8614602017-09-06 15:40:19 -04003084 ClientConfig config;
3085 config.servername = "host1";
3086
3087 SSL_CTX_set_tlsext_servername_callback(
3088 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
3089 // During the handshake, |SSL_get_servername| must match |config|.
3090 ClientConfig *config_p = reinterpret_cast<ClientConfig *>(arg);
3091 EXPECT_STREQ(config_p->servername.c_str(),
3092 SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name));
3093 return SSL_TLSEXT_ERR_OK;
3094 });
3095 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), &config);
3096
3097 ASSERT_TRUE(Connect(config));
3098 // After the handshake, it must also be available.
3099 EXPECT_STREQ(config.servername.c_str(),
3100 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3101
3102 // Establish a session under host1.
3103 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3104 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3105 bssl::UniquePtr<SSL_SESSION> session =
3106 CreateClientSession(client_ctx_.get(), server_ctx_.get(), config);
3107
3108 // If the client resumes a session with a different name, |SSL_get_servername|
3109 // must return the new name.
3110 ASSERT_TRUE(session);
3111 config.session = session.get();
3112 config.servername = "host2";
3113 ASSERT_TRUE(Connect(config));
3114 EXPECT_STREQ(config.servername.c_str(),
3115 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3116}
3117
David Benjamin3d8f0802017-09-06 16:12:52 -04003118// Test that session cache mode bits are honored in the client session callback.
3119TEST_P(SSLVersionTest, ClientSessionCacheMode) {
3120 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_OFF);
3121 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3122
3123 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_CLIENT);
3124 EXPECT_TRUE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3125
3126 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_SERVER);
3127 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3128}
3129
Steven Valdez777a2392019-02-21 11:30:47 -05003130// Test that all versions survive tiny write buffers. In particular, TLS 1.3
3131// NewSessionTickets are written post-handshake. Servers that block
3132// |SSL_do_handshake| on writing them will deadlock if clients are not draining
3133// the buffer. Test that we do not do this.
3134TEST_P(SSLVersionTest, SmallBuffer) {
3135 // DTLS is a datagram protocol and requires packet-sized buffers.
3136 if (is_dtls()) {
3137 return;
3138 }
3139
3140 // Test both flushing NewSessionTickets with a zero-sized write and
3141 // non-zero-sized write.
3142 for (bool use_zero_write : {false, true}) {
3143 SCOPED_TRACE(use_zero_write);
3144
3145 g_last_session = nullptr;
3146 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3147 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
3148
3149 bssl::UniquePtr<SSL> client(SSL_new(client_ctx_.get())),
3150 server(SSL_new(server_ctx_.get()));
3151 ASSERT_TRUE(client);
3152 ASSERT_TRUE(server);
3153 SSL_set_connect_state(client.get());
3154 SSL_set_accept_state(server.get());
3155
3156 // Use a tiny buffer.
3157 BIO *bio1, *bio2;
3158 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 1, &bio2, 1));
3159
3160 // SSL_set_bio takes ownership.
3161 SSL_set_bio(client.get(), bio1, bio1);
3162 SSL_set_bio(server.get(), bio2, bio2);
3163
3164 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
3165 if (version() >= TLS1_3_VERSION) {
3166 // The post-handshake ticket should not have been processed yet.
3167 EXPECT_FALSE(g_last_session);
3168 }
3169
3170 if (use_zero_write) {
3171 ASSERT_TRUE(FlushNewSessionTickets(client.get(), server.get()));
3172 EXPECT_TRUE(g_last_session);
3173 }
3174
3175 // Send some data from server to client. If |use_zero_write| is false, this
3176 // will also flush the NewSessionTickets.
3177 static const char kMessage[] = "hello world";
3178 char buf[sizeof(kMessage)];
3179 for (;;) {
3180 int server_ret = SSL_write(server.get(), kMessage, sizeof(kMessage));
3181 int server_err = SSL_get_error(server.get(), server_ret);
3182 int client_ret = SSL_read(client.get(), buf, sizeof(buf));
3183 int client_err = SSL_get_error(client.get(), client_ret);
3184
3185 // The server will write a single record, so every iteration should see
3186 // |SSL_ERROR_WANT_WRITE| and |SSL_ERROR_WANT_READ|, until the final
3187 // iteration, where both will complete.
3188 if (server_ret > 0) {
3189 EXPECT_EQ(server_ret, static_cast<int>(sizeof(kMessage)));
3190 EXPECT_EQ(client_ret, static_cast<int>(sizeof(kMessage)));
3191 EXPECT_EQ(Bytes(buf), Bytes(kMessage));
3192 break;
3193 }
3194
3195 ASSERT_EQ(server_ret, -1);
3196 ASSERT_EQ(server_err, SSL_ERROR_WANT_WRITE);
3197 ASSERT_EQ(client_ret, -1);
3198 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
3199 }
3200
3201 // The NewSessionTickets should have been flushed and processed.
3202 EXPECT_TRUE(g_last_session);
3203 }
3204}
3205
Adam Langleye1e78132017-01-31 15:24:31 -08003206TEST(SSLTest, AddChainCertHack) {
3207 // Ensure that we don't accidently break the hack that we have in place to
3208 // keep curl and serf happy when they use an |X509| even after transfering
3209 // ownership.
3210
3211 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3212 ASSERT_TRUE(ctx);
3213 X509 *cert = GetTestCertificate().release();
3214 ASSERT_TRUE(cert);
3215 SSL_CTX_add0_chain_cert(ctx.get(), cert);
3216
3217 // This should not trigger a use-after-free.
3218 X509_cmp(cert, cert);
3219}
3220
David Benjaminb2ff2622017-02-03 17:06:18 -05003221TEST(SSLTest, GetCertificate) {
3222 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3223 ASSERT_TRUE(ctx);
3224 bssl::UniquePtr<X509> cert = GetTestCertificate();
3225 ASSERT_TRUE(cert);
3226 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
3227 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3228 ASSERT_TRUE(ssl);
3229
3230 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
3231 ASSERT_TRUE(cert2);
3232 X509 *cert3 = SSL_get_certificate(ssl.get());
3233 ASSERT_TRUE(cert3);
3234
3235 // The old and new certificates must be identical.
3236 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
3237 EXPECT_EQ(0, X509_cmp(cert.get(), cert3));
3238
3239 uint8_t *der = nullptr;
3240 long der_len = i2d_X509(cert.get(), &der);
3241 ASSERT_LT(0, der_len);
3242 bssl::UniquePtr<uint8_t> free_der(der);
3243
3244 uint8_t *der2 = nullptr;
3245 long der2_len = i2d_X509(cert2, &der2);
3246 ASSERT_LT(0, der2_len);
3247 bssl::UniquePtr<uint8_t> free_der2(der2);
3248
3249 uint8_t *der3 = nullptr;
3250 long der3_len = i2d_X509(cert3, &der3);
3251 ASSERT_LT(0, der3_len);
3252 bssl::UniquePtr<uint8_t> free_der3(der3);
3253
3254 // They must also encode identically.
David Benjamin7d7554b2017-02-04 11:48:59 -05003255 EXPECT_EQ(Bytes(der, der_len), Bytes(der2, der2_len));
3256 EXPECT_EQ(Bytes(der, der_len), Bytes(der3, der3_len));
David Benjaminb2ff2622017-02-03 17:06:18 -05003257}
3258
Adam Langleyd04ca952017-02-28 11:26:51 -08003259TEST(SSLTest, SetChainAndKeyMismatch) {
3260 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_with_buffers_method()));
3261 ASSERT_TRUE(ctx);
3262
3263 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3264 ASSERT_TRUE(key);
3265 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3266 ASSERT_TRUE(leaf);
3267 std::vector<CRYPTO_BUFFER*> chain = {
3268 leaf.get(),
3269 };
3270
3271 // Should fail because |GetTestKey| doesn't match the chain-test certificate.
3272 ASSERT_FALSE(SSL_CTX_set_chain_and_key(ctx.get(), &chain[0], chain.size(),
3273 key.get(), nullptr));
3274 ERR_clear_error();
3275}
3276
3277TEST(SSLTest, SetChainAndKey) {
3278 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3279 ASSERT_TRUE(client_ctx);
3280 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3281 ASSERT_TRUE(server_ctx);
3282
3283 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3284 ASSERT_TRUE(key);
3285 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3286 ASSERT_TRUE(leaf);
3287 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3288 GetChainTestIntermediateBuffer();
3289 ASSERT_TRUE(intermediate);
3290 std::vector<CRYPTO_BUFFER*> chain = {
3291 leaf.get(), intermediate.get(),
3292 };
3293 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3294 chain.size(), key.get(), nullptr));
3295
David Benjamin3a1dd462017-07-11 16:13:10 -04003296 SSL_CTX_set_custom_verify(
3297 client_ctx.get(), SSL_VERIFY_PEER,
3298 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3299 return ssl_verify_ok;
3300 });
Adam Langleyd04ca952017-02-28 11:26:51 -08003301
3302 bssl::UniquePtr<SSL> client, server;
3303 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003304 server_ctx.get()));
Adam Langleyd04ca952017-02-28 11:26:51 -08003305}
3306
Matthew Braithwaite5301c102018-01-23 12:08:55 -08003307TEST(SSLTest, BuffersFailWithoutCustomVerify) {
3308 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3309 ASSERT_TRUE(client_ctx);
3310 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3311 ASSERT_TRUE(server_ctx);
3312
3313 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3314 ASSERT_TRUE(key);
3315 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3316 ASSERT_TRUE(leaf);
3317 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
3318 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3319 chain.size(), key.get(), nullptr));
3320
3321 // Without SSL_CTX_set_custom_verify(), i.e. with everything in the default
3322 // configuration, certificate verification should fail.
3323 bssl::UniquePtr<SSL> client, server;
3324 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3325 server_ctx.get()));
3326
3327 // Whereas with a verifier, the connection should succeed.
3328 SSL_CTX_set_custom_verify(
3329 client_ctx.get(), SSL_VERIFY_PEER,
3330 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3331 return ssl_verify_ok;
3332 });
3333 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3334 server_ctx.get()));
3335}
3336
3337TEST(SSLTest, CustomVerify) {
3338 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3339 ASSERT_TRUE(client_ctx);
3340 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3341 ASSERT_TRUE(server_ctx);
3342
3343 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3344 ASSERT_TRUE(key);
3345 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3346 ASSERT_TRUE(leaf);
3347 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
3348 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3349 chain.size(), key.get(), nullptr));
3350
3351 SSL_CTX_set_custom_verify(
3352 client_ctx.get(), SSL_VERIFY_PEER,
3353 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3354 return ssl_verify_ok;
3355 });
3356
3357 bssl::UniquePtr<SSL> client, server;
3358 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3359 server_ctx.get()));
3360
3361 // With SSL_VERIFY_PEER, ssl_verify_invalid should result in a dropped
3362 // connection.
3363 SSL_CTX_set_custom_verify(
3364 client_ctx.get(), SSL_VERIFY_PEER,
3365 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3366 return ssl_verify_invalid;
3367 });
3368
3369 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3370 server_ctx.get()));
3371
3372 // But with SSL_VERIFY_NONE, ssl_verify_invalid should not cause a dropped
3373 // connection.
3374 SSL_CTX_set_custom_verify(
3375 client_ctx.get(), SSL_VERIFY_NONE,
3376 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3377 return ssl_verify_invalid;
3378 });
3379
3380 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3381 server_ctx.get()));
3382}
3383
David Benjamin71dfad42017-07-16 17:27:39 -04003384TEST(SSLTest, ClientCABuffers) {
3385 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3386 ASSERT_TRUE(client_ctx);
3387 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3388 ASSERT_TRUE(server_ctx);
3389
3390 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3391 ASSERT_TRUE(key);
3392 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3393 ASSERT_TRUE(leaf);
3394 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3395 GetChainTestIntermediateBuffer();
3396 ASSERT_TRUE(intermediate);
3397 std::vector<CRYPTO_BUFFER *> chain = {
3398 leaf.get(),
3399 intermediate.get(),
3400 };
3401 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3402 chain.size(), key.get(), nullptr));
3403
3404 bssl::UniquePtr<CRYPTO_BUFFER> ca_name(
3405 CRYPTO_BUFFER_new(kTestName, sizeof(kTestName), nullptr));
3406 ASSERT_TRUE(ca_name);
3407 bssl::UniquePtr<STACK_OF(CRYPTO_BUFFER)> ca_names(
3408 sk_CRYPTO_BUFFER_new_null());
3409 ASSERT_TRUE(ca_names);
David Benjamin2908dd12018-06-29 17:46:42 -04003410 ASSERT_TRUE(PushToStack(ca_names.get(), std::move(ca_name)));
David Benjamin71dfad42017-07-16 17:27:39 -04003411 SSL_CTX_set0_client_CAs(server_ctx.get(), ca_names.release());
3412
3413 // Configure client and server to accept all certificates.
3414 SSL_CTX_set_custom_verify(
3415 client_ctx.get(), SSL_VERIFY_PEER,
3416 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3417 return ssl_verify_ok;
3418 });
3419 SSL_CTX_set_custom_verify(
3420 server_ctx.get(), SSL_VERIFY_PEER,
3421 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3422 return ssl_verify_ok;
3423 });
3424
3425 bool cert_cb_called = false;
3426 SSL_CTX_set_cert_cb(
3427 client_ctx.get(),
3428 [](SSL *ssl, void *arg) -> int {
David Benjamin5f001d12018-05-08 16:46:48 -04003429 const STACK_OF(CRYPTO_BUFFER) *peer_names =
David Benjamin71dfad42017-07-16 17:27:39 -04003430 SSL_get0_server_requested_CAs(ssl);
3431 EXPECT_EQ(1u, sk_CRYPTO_BUFFER_num(peer_names));
3432 CRYPTO_BUFFER *peer_name = sk_CRYPTO_BUFFER_value(peer_names, 0);
3433 EXPECT_EQ(Bytes(kTestName), Bytes(CRYPTO_BUFFER_data(peer_name),
3434 CRYPTO_BUFFER_len(peer_name)));
3435 *reinterpret_cast<bool *>(arg) = true;
3436 return 1;
3437 },
3438 &cert_cb_called);
3439
3440 bssl::UniquePtr<SSL> client, server;
3441 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003442 server_ctx.get()));
David Benjamin71dfad42017-07-16 17:27:39 -04003443 EXPECT_TRUE(cert_cb_called);
3444}
3445
David Benjamin91222b82017-03-09 20:10:56 -05003446// Configuring the empty cipher list, though an error, should still modify the
3447// configuration.
3448TEST(SSLTest, EmptyCipherList) {
3449 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3450 ASSERT_TRUE(ctx);
3451
3452 // Initially, the cipher list is not empty.
3453 EXPECT_NE(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3454
3455 // Configuring the empty cipher list fails.
3456 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), ""));
3457 ERR_clear_error();
3458
3459 // But the cipher list is still updated to empty.
3460 EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3461}
3462
Adam Langley4c341d02017-03-08 19:33:21 -08003463// ssl_test_ticket_aead_failure_mode enumerates the possible ways in which the
3464// test |SSL_TICKET_AEAD_METHOD| can fail.
3465enum ssl_test_ticket_aead_failure_mode {
3466 ssl_test_ticket_aead_ok = 0,
3467 ssl_test_ticket_aead_seal_fail,
3468 ssl_test_ticket_aead_open_soft_fail,
3469 ssl_test_ticket_aead_open_hard_fail,
3470};
3471
3472struct ssl_test_ticket_aead_state {
3473 unsigned retry_count;
3474 ssl_test_ticket_aead_failure_mode failure_mode;
3475};
3476
3477static int ssl_test_ticket_aead_ex_index_dup(CRYPTO_EX_DATA *to,
3478 const CRYPTO_EX_DATA *from,
3479 void **from_d, int index,
3480 long argl, void *argp) {
3481 abort();
3482}
3483
3484static void ssl_test_ticket_aead_ex_index_free(void *parent, void *ptr,
3485 CRYPTO_EX_DATA *ad, int index,
3486 long argl, void *argp) {
3487 auto state = reinterpret_cast<ssl_test_ticket_aead_state*>(ptr);
3488 if (state == nullptr) {
3489 return;
3490 }
3491
3492 OPENSSL_free(state);
3493}
3494
3495static CRYPTO_once_t g_ssl_test_ticket_aead_ex_index_once = CRYPTO_ONCE_INIT;
3496static int g_ssl_test_ticket_aead_ex_index;
3497
3498static int ssl_test_ticket_aead_get_ex_index() {
3499 CRYPTO_once(&g_ssl_test_ticket_aead_ex_index_once, [] {
3500 g_ssl_test_ticket_aead_ex_index = SSL_get_ex_new_index(
3501 0, nullptr, nullptr, ssl_test_ticket_aead_ex_index_dup,
3502 ssl_test_ticket_aead_ex_index_free);
3503 });
3504 return g_ssl_test_ticket_aead_ex_index;
3505}
3506
3507static size_t ssl_test_ticket_aead_max_overhead(SSL *ssl) {
3508 return 1;
3509}
3510
3511static int ssl_test_ticket_aead_seal(SSL *ssl, uint8_t *out, size_t *out_len,
3512 size_t max_out_len, const uint8_t *in,
3513 size_t in_len) {
3514 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3515 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3516
3517 if (state->failure_mode == ssl_test_ticket_aead_seal_fail ||
3518 max_out_len < in_len + 1) {
3519 return 0;
3520 }
3521
3522 OPENSSL_memmove(out, in, in_len);
3523 out[in_len] = 0xff;
3524 *out_len = in_len + 1;
3525
3526 return 1;
3527}
3528
3529static ssl_ticket_aead_result_t ssl_test_ticket_aead_open(
3530 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len,
3531 const uint8_t *in, size_t in_len) {
3532 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3533 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3534
3535 if (state->retry_count > 0) {
3536 state->retry_count--;
3537 return ssl_ticket_aead_retry;
3538 }
3539
3540 switch (state->failure_mode) {
3541 case ssl_test_ticket_aead_ok:
3542 break;
3543 case ssl_test_ticket_aead_seal_fail:
3544 // If |seal| failed then there shouldn't be any ticket to try and
3545 // decrypt.
3546 abort();
3547 break;
3548 case ssl_test_ticket_aead_open_soft_fail:
3549 return ssl_ticket_aead_ignore_ticket;
3550 case ssl_test_ticket_aead_open_hard_fail:
3551 return ssl_ticket_aead_error;
3552 }
3553
3554 if (in_len == 0 || in[in_len - 1] != 0xff) {
3555 return ssl_ticket_aead_ignore_ticket;
3556 }
3557
3558 if (max_out_len < in_len - 1) {
3559 return ssl_ticket_aead_error;
3560 }
3561
3562 OPENSSL_memmove(out, in, in_len - 1);
3563 *out_len = in_len - 1;
3564 return ssl_ticket_aead_success;
3565}
3566
3567static const SSL_TICKET_AEAD_METHOD kSSLTestTicketMethod = {
3568 ssl_test_ticket_aead_max_overhead,
3569 ssl_test_ticket_aead_seal,
3570 ssl_test_ticket_aead_open,
3571};
3572
3573static void ConnectClientAndServerWithTicketMethod(
3574 bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
3575 SSL_CTX *client_ctx, SSL_CTX *server_ctx, unsigned retry_count,
3576 ssl_test_ticket_aead_failure_mode failure_mode, SSL_SESSION *session) {
3577 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
3578 ASSERT_TRUE(client);
3579 ASSERT_TRUE(server);
3580 SSL_set_connect_state(client.get());
3581 SSL_set_accept_state(server.get());
3582
3583 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3584 OPENSSL_malloc(sizeof(ssl_test_ticket_aead_state)));
3585 ASSERT_TRUE(state);
3586 OPENSSL_memset(state, 0, sizeof(ssl_test_ticket_aead_state));
3587 state->retry_count = retry_count;
3588 state->failure_mode = failure_mode;
3589
3590 ASSERT_TRUE(SSL_set_ex_data(server.get(), ssl_test_ticket_aead_get_ex_index(),
3591 state));
3592
3593 SSL_set_session(client.get(), session);
3594
3595 BIO *bio1, *bio2;
3596 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
3597
3598 // SSL_set_bio takes ownership.
3599 SSL_set_bio(client.get(), bio1, bio1);
3600 SSL_set_bio(server.get(), bio2, bio2);
3601
3602 if (CompleteHandshakes(client.get(), server.get())) {
3603 *out_client = std::move(client);
3604 *out_server = std::move(server);
3605 } else {
3606 out_client->reset();
3607 out_server->reset();
3608 }
3609}
3610
David Benjaminc9775322018-04-13 16:39:12 -04003611using TicketAEADMethodParam =
3612 testing::tuple<uint16_t, unsigned, ssl_test_ticket_aead_failure_mode>;
3613
Adam Langley4c341d02017-03-08 19:33:21 -08003614class TicketAEADMethodTest
David Benjaminc9775322018-04-13 16:39:12 -04003615 : public ::testing::TestWithParam<TicketAEADMethodParam> {};
Adam Langley4c341d02017-03-08 19:33:21 -08003616
3617TEST_P(TicketAEADMethodTest, Resume) {
3618 bssl::UniquePtr<X509> cert = GetTestCertificate();
3619 ASSERT_TRUE(cert);
3620 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3621 ASSERT_TRUE(key);
3622
3623 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
3624 ASSERT_TRUE(server_ctx);
3625 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
3626 ASSERT_TRUE(client_ctx);
3627
3628 const uint16_t version = testing::get<0>(GetParam());
3629 const unsigned retry_count = testing::get<1>(GetParam());
3630 const ssl_test_ticket_aead_failure_mode failure_mode =
3631 testing::get<2>(GetParam());
3632
3633 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3634 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3635 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), version));
3636 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), version));
3637 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), version));
3638 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), version));
3639
3640 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
3641 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
3642 SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
3643 SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
David Benjamin707af292017-03-10 17:47:18 -05003644 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langley4c341d02017-03-08 19:33:21 -08003645
3646 SSL_CTX_set_ticket_aead_method(server_ctx.get(), &kSSLTestTicketMethod);
3647
3648 bssl::UniquePtr<SSL> client, server;
3649 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3650 server_ctx.get(), retry_count,
3651 failure_mode, nullptr);
3652 switch (failure_mode) {
3653 case ssl_test_ticket_aead_ok:
3654 case ssl_test_ticket_aead_open_hard_fail:
3655 case ssl_test_ticket_aead_open_soft_fail:
3656 ASSERT_TRUE(client);
3657 break;
3658 case ssl_test_ticket_aead_seal_fail:
3659 EXPECT_FALSE(client);
3660 return;
3661 }
3662 EXPECT_FALSE(SSL_session_reused(client.get()));
3663 EXPECT_FALSE(SSL_session_reused(server.get()));
3664
Steven Valdez777a2392019-02-21 11:30:47 -05003665 ASSERT_TRUE(FlushNewSessionTickets(client.get(), server.get()));
David Benjamin707af292017-03-10 17:47:18 -05003666 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
Adam Langley4c341d02017-03-08 19:33:21 -08003667 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3668 server_ctx.get(), retry_count,
David Benjamin707af292017-03-10 17:47:18 -05003669 failure_mode, session.get());
Adam Langley4c341d02017-03-08 19:33:21 -08003670 switch (failure_mode) {
3671 case ssl_test_ticket_aead_ok:
3672 ASSERT_TRUE(client);
3673 EXPECT_TRUE(SSL_session_reused(client.get()));
3674 EXPECT_TRUE(SSL_session_reused(server.get()));
3675 break;
3676 case ssl_test_ticket_aead_seal_fail:
3677 abort();
3678 break;
3679 case ssl_test_ticket_aead_open_hard_fail:
3680 EXPECT_FALSE(client);
3681 break;
3682 case ssl_test_ticket_aead_open_soft_fail:
3683 ASSERT_TRUE(client);
3684 EXPECT_FALSE(SSL_session_reused(client.get()));
3685 EXPECT_FALSE(SSL_session_reused(server.get()));
3686 }
3687}
3688
David Benjaminc9775322018-04-13 16:39:12 -04003689std::string TicketAEADMethodParamToString(
3690 const testing::TestParamInfo<TicketAEADMethodParam> &params) {
3691 std::string ret = GetVersionName(std::get<0>(params.param));
3692 // GTest only allows alphanumeric characters and '_' in the parameter
3693 // string. Additionally filter out the 'v' to get "TLS13" over "TLSv13".
3694 for (auto it = ret.begin(); it != ret.end();) {
3695 if (*it == '.' || *it == 'v') {
3696 it = ret.erase(it);
3697 } else {
3698 ++it;
3699 }
3700 }
3701 char retry_count[256];
3702 snprintf(retry_count, sizeof(retry_count), "%d", std::get<1>(params.param));
3703 ret += "_";
3704 ret += retry_count;
3705 ret += "Retries_";
3706 switch (std::get<2>(params.param)) {
3707 case ssl_test_ticket_aead_ok:
3708 ret += "OK";
3709 break;
3710 case ssl_test_ticket_aead_seal_fail:
3711 ret += "SealFail";
3712 break;
3713 case ssl_test_ticket_aead_open_soft_fail:
3714 ret += "OpenSoftFail";
3715 break;
3716 case ssl_test_ticket_aead_open_hard_fail:
3717 ret += "OpenHardFail";
3718 break;
3719 }
3720 return ret;
3721}
3722
David Benjaminbe7006a2019-04-09 18:05:02 -05003723INSTANTIATE_TEST_SUITE_P(
Adam Langley4c341d02017-03-08 19:33:21 -08003724 TicketAEADMethodTests, TicketAEADMethodTest,
David Benjaminc9775322018-04-13 16:39:12 -04003725 testing::Combine(testing::Values(TLS1_2_VERSION, TLS1_3_VERSION),
3726 testing::Values(0, 1, 2),
3727 testing::Values(ssl_test_ticket_aead_ok,
3728 ssl_test_ticket_aead_seal_fail,
3729 ssl_test_ticket_aead_open_soft_fail,
3730 ssl_test_ticket_aead_open_hard_fail)),
3731 TicketAEADMethodParamToString);
Adam Langley4c341d02017-03-08 19:33:21 -08003732
David Benjaminca743582017-06-15 17:51:35 -04003733TEST(SSLTest, SelectNextProto) {
3734 uint8_t *result;
3735 uint8_t result_len;
3736
3737 // If there is an overlap, it should be returned.
3738 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3739 SSL_select_next_proto(&result, &result_len,
3740 (const uint8_t *)"\1a\2bb\3ccc", 9,
3741 (const uint8_t *)"\1x\1y\1a\1z", 8));
3742 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
3743
3744 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3745 SSL_select_next_proto(&result, &result_len,
3746 (const uint8_t *)"\1a\2bb\3ccc", 9,
3747 (const uint8_t *)"\1x\1y\2bb\1z", 9));
3748 EXPECT_EQ(Bytes("bb"), Bytes(result, result_len));
3749
3750 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3751 SSL_select_next_proto(&result, &result_len,
3752 (const uint8_t *)"\1a\2bb\3ccc", 9,
3753 (const uint8_t *)"\1x\1y\3ccc\1z", 10));
3754 EXPECT_EQ(Bytes("ccc"), Bytes(result, result_len));
3755
3756 // Peer preference order takes precedence over local.
3757 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3758 SSL_select_next_proto(&result, &result_len,
3759 (const uint8_t *)"\1a\2bb\3ccc", 9,
3760 (const uint8_t *)"\3ccc\2bb\1a", 9));
3761 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
3762
3763 // If there is no overlap, return the first local protocol.
3764 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
3765 SSL_select_next_proto(&result, &result_len,
3766 (const uint8_t *)"\1a\2bb\3ccc", 9,
3767 (const uint8_t *)"\1x\2yy\3zzz", 9));
3768 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
3769
3770 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
3771 SSL_select_next_proto(&result, &result_len, nullptr, 0,
3772 (const uint8_t *)"\1x\2yy\3zzz", 9));
3773 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
3774}
3775
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003776TEST(SSLTest, SealRecord) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08003777 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
3778 server_ctx(SSL_CTX_new(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003779 ASSERT_TRUE(client_ctx);
3780 ASSERT_TRUE(server_ctx);
3781
3782 bssl::UniquePtr<X509> cert = GetTestCertificate();
3783 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3784 ASSERT_TRUE(cert);
3785 ASSERT_TRUE(key);
3786 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3787 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3788
3789 bssl::UniquePtr<SSL> client, server;
3790 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003791 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003792
3793 const std::vector<uint8_t> record = {1, 2, 3, 4, 5};
3794 std::vector<uint8_t> prefix(
3795 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003796 body(record.size()),
3797 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003798 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3799 bssl::MakeSpan(body), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003800 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003801
3802 std::vector<uint8_t> sealed;
3803 sealed.insert(sealed.end(), prefix.begin(), prefix.end());
3804 sealed.insert(sealed.end(), body.begin(), body.end());
3805 sealed.insert(sealed.end(), suffix.begin(), suffix.end());
3806 std::vector<uint8_t> sealed_copy = sealed;
3807
3808 bssl::Span<uint8_t> plaintext;
3809 size_t record_len;
3810 uint8_t alert = 255;
3811 EXPECT_EQ(bssl::OpenRecord(server.get(), &plaintext, &record_len, &alert,
3812 bssl::MakeSpan(sealed)),
3813 bssl::OpenRecordResult::kOK);
3814 EXPECT_EQ(record_len, sealed.size());
3815 EXPECT_EQ(plaintext, record);
3816 EXPECT_EQ(255, alert);
3817}
3818
3819TEST(SSLTest, SealRecordInPlace) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08003820 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
3821 server_ctx(SSL_CTX_new(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003822 ASSERT_TRUE(client_ctx);
3823 ASSERT_TRUE(server_ctx);
3824
3825 bssl::UniquePtr<X509> cert = GetTestCertificate();
3826 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3827 ASSERT_TRUE(cert);
3828 ASSERT_TRUE(key);
3829 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3830 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3831
3832 bssl::UniquePtr<SSL> client, server;
3833 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003834 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003835
3836 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
3837 std::vector<uint8_t> record = plaintext;
3838 std::vector<uint8_t> prefix(
3839 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003840 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003841 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3842 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003843 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003844 record.insert(record.begin(), prefix.begin(), prefix.end());
3845 record.insert(record.end(), suffix.begin(), suffix.end());
3846
3847 bssl::Span<uint8_t> result;
3848 size_t record_len;
3849 uint8_t alert;
3850 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
3851 bssl::MakeSpan(record)),
3852 bssl::OpenRecordResult::kOK);
3853 EXPECT_EQ(record_len, record.size());
3854 EXPECT_EQ(plaintext, result);
3855}
3856
3857TEST(SSLTest, SealRecordTrailingData) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08003858 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
3859 server_ctx(SSL_CTX_new(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003860 ASSERT_TRUE(client_ctx);
3861 ASSERT_TRUE(server_ctx);
3862
3863 bssl::UniquePtr<X509> cert = GetTestCertificate();
3864 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3865 ASSERT_TRUE(cert);
3866 ASSERT_TRUE(key);
3867 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3868 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3869
3870 bssl::UniquePtr<SSL> client, server;
3871 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003872 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003873
3874 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
3875 std::vector<uint8_t> record = plaintext;
3876 std::vector<uint8_t> prefix(
3877 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003878 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003879 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3880 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003881 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003882 record.insert(record.begin(), prefix.begin(), prefix.end());
3883 record.insert(record.end(), suffix.begin(), suffix.end());
3884 record.insert(record.end(), {5, 4, 3, 2, 1});
3885
3886 bssl::Span<uint8_t> result;
3887 size_t record_len;
3888 uint8_t alert;
3889 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
3890 bssl::MakeSpan(record)),
3891 bssl::OpenRecordResult::kOK);
3892 EXPECT_EQ(record_len, record.size() - 5);
3893 EXPECT_EQ(plaintext, result);
3894}
3895
3896TEST(SSLTest, SealRecordInvalidSpanSize) {
Matthew Braithwaite58d56f42019-11-04 13:20:01 -08003897 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLSv1_2_method())),
3898 server_ctx(SSL_CTX_new(TLSv1_2_method()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003899 ASSERT_TRUE(client_ctx);
3900 ASSERT_TRUE(server_ctx);
3901
3902 bssl::UniquePtr<X509> cert = GetTestCertificate();
3903 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3904 ASSERT_TRUE(cert);
3905 ASSERT_TRUE(key);
3906 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3907 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3908
3909 bssl::UniquePtr<SSL> client, server;
3910 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003911 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003912
3913 std::vector<uint8_t> record = {1, 2, 3, 4, 5};
3914 std::vector<uint8_t> prefix(
3915 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003916 body(record.size()),
3917 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003918
3919 auto expect_err = []() {
3920 int err = ERR_get_error();
3921 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
3922 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_BUFFER_TOO_SMALL);
3923 ERR_clear_error();
3924 };
3925 EXPECT_FALSE(bssl::SealRecord(
3926 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003927 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003928 expect_err();
3929 EXPECT_FALSE(bssl::SealRecord(
3930 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003931 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003932 expect_err();
3933
3934 EXPECT_FALSE(
3935 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3936 bssl::MakeSpan(record.data(), record.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003937 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003938 expect_err();
3939 EXPECT_FALSE(
3940 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3941 bssl::MakeSpan(record.data(), record.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003942 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003943 expect_err();
3944
3945 EXPECT_FALSE(bssl::SealRecord(
3946 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003947 bssl::MakeSpan(suffix.data(), suffix.size() - 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003948 expect_err();
3949 EXPECT_FALSE(bssl::SealRecord(
3950 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003951 bssl::MakeSpan(suffix.data(), suffix.size() + 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003952 expect_err();
3953}
3954
David Benjamin617b8182017-08-29 15:33:10 -04003955// The client should gracefully handle no suitable ciphers being enabled.
3956TEST(SSLTest, NoCiphersAvailable) {
3957 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3958 ASSERT_TRUE(ctx);
3959
3960 // Configure |client_ctx| with a cipher list that does not intersect with its
3961 // version configuration.
3962 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
3963 ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
3964 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
3965
3966 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3967 ASSERT_TRUE(ssl);
3968 SSL_set_connect_state(ssl.get());
3969
3970 UniquePtr<BIO> rbio(BIO_new(BIO_s_mem())), wbio(BIO_new(BIO_s_mem()));
3971 ASSERT_TRUE(rbio);
3972 ASSERT_TRUE(wbio);
3973 SSL_set0_rbio(ssl.get(), rbio.release());
3974 SSL_set0_wbio(ssl.get(), wbio.release());
3975
3976 int ret = SSL_do_handshake(ssl.get());
3977 EXPECT_EQ(-1, ret);
3978 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), ret));
3979 uint32_t err = ERR_get_error();
3980 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
3981 EXPECT_EQ(SSL_R_NO_CIPHERS_AVAILABLE, ERR_GET_REASON(err));
3982}
3983
David Benjamina4bafd32017-10-03 15:06:29 -04003984TEST_P(SSLVersionTest, SessionVersion) {
3985 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3986 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3987
3988 bssl::UniquePtr<SSL_SESSION> session =
3989 CreateClientSession(client_ctx_.get(), server_ctx_.get());
3990 ASSERT_TRUE(session);
3991 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
3992
3993 // Sessions in TLS 1.3 and later should be single-use.
3994 EXPECT_EQ(version() == TLS1_3_VERSION,
3995 !!SSL_SESSION_should_be_single_use(session.get()));
3996
3997 // Making fake sessions for testing works.
3998 session.reset(SSL_SESSION_new(client_ctx_.get()));
3999 ASSERT_TRUE(session);
4000 ASSERT_TRUE(SSL_SESSION_set_protocol_version(session.get(), version()));
4001 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
4002}
4003
David Benjaminfdb7a352017-10-12 17:34:18 -04004004TEST_P(SSLVersionTest, SSLPending) {
4005 UniquePtr<SSL> ssl(SSL_new(client_ctx_.get()));
4006 ASSERT_TRUE(ssl);
4007 EXPECT_EQ(0, SSL_pending(ssl.get()));
4008
4009 ASSERT_TRUE(Connect());
4010 EXPECT_EQ(0, SSL_pending(client_.get()));
4011
4012 ASSERT_EQ(5, SSL_write(server_.get(), "hello", 5));
4013 ASSERT_EQ(5, SSL_write(server_.get(), "world", 5));
4014 EXPECT_EQ(0, SSL_pending(client_.get()));
4015
4016 char buf[10];
4017 ASSERT_EQ(1, SSL_peek(client_.get(), buf, 1));
4018 EXPECT_EQ(5, SSL_pending(client_.get()));
4019
4020 ASSERT_EQ(1, SSL_read(client_.get(), buf, 1));
4021 EXPECT_EQ(4, SSL_pending(client_.get()));
4022
4023 ASSERT_EQ(4, SSL_read(client_.get(), buf, 10));
4024 EXPECT_EQ(0, SSL_pending(client_.get()));
4025
4026 ASSERT_EQ(2, SSL_read(client_.get(), buf, 2));
4027 EXPECT_EQ(3, SSL_pending(client_.get()));
4028}
4029
David Benjamina031b612017-10-11 20:48:25 -04004030// Test that post-handshake tickets consumed by |SSL_shutdown| are ignored.
4031TEST(SSLTest, ShutdownIgnoresTickets) {
4032 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4033 ASSERT_TRUE(ctx);
4034 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_3_VERSION));
4035 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
4036
4037 bssl::UniquePtr<X509> cert = GetTestCertificate();
4038 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4039 ASSERT_TRUE(cert);
4040 ASSERT_TRUE(key);
4041 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
4042 ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
4043
4044 SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_BOTH);
4045
4046 bssl::UniquePtr<SSL> client, server;
4047 ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
4048
4049 SSL_CTX_sess_set_new_cb(ctx.get(), [](SSL *ssl, SSL_SESSION *session) -> int {
4050 ADD_FAILURE() << "New session callback called during SSL_shutdown";
4051 return 0;
4052 });
4053
4054 // Send close_notify.
4055 EXPECT_EQ(0, SSL_shutdown(server.get()));
4056 EXPECT_EQ(0, SSL_shutdown(client.get()));
4057
4058 // Receive close_notify.
4059 EXPECT_EQ(1, SSL_shutdown(server.get()));
4060 EXPECT_EQ(1, SSL_shutdown(client.get()));
4061}
4062
David Benjamin6cc352e2017-11-02 17:21:39 -04004063TEST(SSLTest, SignatureAlgorithmProperties) {
4064 EXPECT_EQ(EVP_PKEY_NONE, SSL_get_signature_algorithm_key_type(0x1234));
4065 EXPECT_EQ(nullptr, SSL_get_signature_algorithm_digest(0x1234));
4066 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(0x1234));
4067
4068 EXPECT_EQ(EVP_PKEY_RSA,
4069 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4070 EXPECT_EQ(EVP_md5_sha1(),
4071 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4072 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4073
4074 EXPECT_EQ(EVP_PKEY_EC, SSL_get_signature_algorithm_key_type(
4075 SSL_SIGN_ECDSA_SECP256R1_SHA256));
4076 EXPECT_EQ(EVP_sha256(), SSL_get_signature_algorithm_digest(
4077 SSL_SIGN_ECDSA_SECP256R1_SHA256));
4078 EXPECT_FALSE(
4079 SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_ECDSA_SECP256R1_SHA256));
4080
4081 EXPECT_EQ(EVP_PKEY_RSA,
David Benjamin6879e192018-04-13 16:01:02 -04004082 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04004083 EXPECT_EQ(EVP_sha384(),
David Benjamin6879e192018-04-13 16:01:02 -04004084 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PSS_RSAE_SHA384));
4085 EXPECT_TRUE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04004086}
4087
Adam Langley85967952018-07-03 08:04:58 -07004088static int XORCompressFunc(SSL *ssl, CBB *out, const uint8_t *in,
4089 size_t in_len) {
4090 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07004091 if (!CBB_add_u8(out, in[i] ^ 0x55)) {
Adam Langley85967952018-07-03 08:04:58 -07004092 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07004093 }
4094 }
4095
4096 SSL_set_app_data(ssl, XORCompressFunc);
4097
Adam Langley85967952018-07-03 08:04:58 -07004098 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07004099}
4100
Adam Langley85967952018-07-03 08:04:58 -07004101static int XORDecompressFunc(SSL *ssl, CRYPTO_BUFFER **out,
4102 size_t uncompressed_len, const uint8_t *in,
4103 size_t in_len) {
4104 if (in_len != uncompressed_len) {
4105 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07004106 }
4107
4108 uint8_t *data;
Adam Langley85967952018-07-03 08:04:58 -07004109 *out = CRYPTO_BUFFER_alloc(&data, uncompressed_len);
4110 if (*out == nullptr) {
4111 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07004112 }
4113
Adam Langley85967952018-07-03 08:04:58 -07004114 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07004115 data[i] = in[i] ^ 0x55;
4116 }
4117
4118 SSL_set_app_data(ssl, XORDecompressFunc);
4119
Adam Langley85967952018-07-03 08:04:58 -07004120 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07004121}
4122
4123TEST(SSLTest, CertCompression) {
4124 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4125 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4126 ASSERT_TRUE(client_ctx);
4127 ASSERT_TRUE(server_ctx);
4128
4129 bssl::UniquePtr<X509> cert = GetTestCertificate();
4130 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4131 ASSERT_TRUE(cert);
4132 ASSERT_TRUE(key);
4133 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
4134 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
4135
4136 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
4137 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
4138 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
4139 client_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
4140 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
4141 server_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
4142
4143 bssl::UniquePtr<SSL> client, server;
4144 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4145 server_ctx.get()));
4146
4147 EXPECT_TRUE(SSL_get_app_data(client.get()) == XORDecompressFunc);
4148 EXPECT_TRUE(SSL_get_app_data(server.get()) == XORCompressFunc);
4149}
4150
Adam Langleyddb57cf2018-01-26 09:17:53 -08004151void MoveBIOs(SSL *dest, SSL *src) {
4152 BIO *rbio = SSL_get_rbio(src);
4153 BIO_up_ref(rbio);
4154 SSL_set0_rbio(dest, rbio);
4155
4156 BIO *wbio = SSL_get_wbio(src);
4157 BIO_up_ref(wbio);
4158 SSL_set0_wbio(dest, wbio);
4159
4160 SSL_set0_rbio(src, nullptr);
4161 SSL_set0_wbio(src, nullptr);
4162}
4163
4164TEST(SSLTest, Handoff) {
4165 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4166 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4167 bssl::UniquePtr<SSL_CTX> handshaker_ctx(SSL_CTX_new(TLS_method()));
4168 ASSERT_TRUE(client_ctx);
4169 ASSERT_TRUE(server_ctx);
4170 ASSERT_TRUE(handshaker_ctx);
4171
4172 SSL_CTX_set_handoff_mode(server_ctx.get(), 1);
4173 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
4174 ASSERT_TRUE(
4175 SSL_CTX_set_max_proto_version(handshaker_ctx.get(), TLS1_2_VERSION));
4176
4177 bssl::UniquePtr<X509> cert = GetTestCertificate();
4178 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4179 ASSERT_TRUE(cert);
4180 ASSERT_TRUE(key);
4181 ASSERT_TRUE(SSL_CTX_use_certificate(handshaker_ctx.get(), cert.get()));
4182 ASSERT_TRUE(SSL_CTX_use_PrivateKey(handshaker_ctx.get(), key.get()));
4183
4184 bssl::UniquePtr<SSL> client, server;
4185 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4186 server_ctx.get(), ClientConfig(),
4187 false /* don't handshake */));
4188
4189 int client_ret = SSL_do_handshake(client.get());
4190 int client_err = SSL_get_error(client.get(), client_ret);
4191 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4192
4193 int server_ret = SSL_do_handshake(server.get());
4194 int server_err = SSL_get_error(server.get(), server_ret);
4195 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
4196
4197 ScopedCBB cbb;
4198 Array<uint8_t> handoff;
Adam Langleyc9827e02019-04-12 14:46:50 -07004199 SSL_CLIENT_HELLO hello;
Adam Langleyddb57cf2018-01-26 09:17:53 -08004200 ASSERT_TRUE(CBB_init(cbb.get(), 256));
Adam Langleyc9827e02019-04-12 14:46:50 -07004201 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004202 ASSERT_TRUE(CBBFinishArray(cbb.get(), &handoff));
4203
4204 bssl::UniquePtr<SSL> handshaker(SSL_new(handshaker_ctx.get()));
4205 ASSERT_TRUE(SSL_apply_handoff(handshaker.get(), handoff));
4206
4207 MoveBIOs(handshaker.get(), server.get());
4208
4209 int handshake_ret = SSL_do_handshake(handshaker.get());
4210 int handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
Matthew Braithwaite56986f92018-03-22 11:48:33 -07004211 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
Adam Langleyddb57cf2018-01-26 09:17:53 -08004212
Matthew Braithwaite56986f92018-03-22 11:48:33 -07004213 // Double-check that additional calls to |SSL_do_handshake| continue
4214 // to get |SSL_ERRROR_HANDBACK|.
4215 handshake_ret = SSL_do_handshake(handshaker.get());
4216 handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
4217 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
Adam Langleyddb57cf2018-01-26 09:17:53 -08004218
4219 ScopedCBB cbb_handback;
4220 Array<uint8_t> handback;
4221 ASSERT_TRUE(CBB_init(cbb_handback.get(), 1024));
4222 ASSERT_TRUE(SSL_serialize_handback(handshaker.get(), cbb_handback.get()));
4223 ASSERT_TRUE(CBBFinishArray(cbb_handback.get(), &handback));
4224
4225 bssl::UniquePtr<SSL> server2(SSL_new(server_ctx.get()));
4226 ASSERT_TRUE(SSL_apply_handback(server2.get(), handback));
4227
4228 MoveBIOs(server2.get(), handshaker.get());
Matthew Braithwaite56986f92018-03-22 11:48:33 -07004229 ASSERT_TRUE(CompleteHandshakes(client.get(), server2.get()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004230
4231 uint8_t byte = 42;
4232 EXPECT_EQ(SSL_write(client.get(), &byte, 1), 1);
4233 EXPECT_EQ(SSL_read(server2.get(), &byte, 1), 1);
4234 EXPECT_EQ(42, byte);
4235
4236 byte = 43;
4237 EXPECT_EQ(SSL_write(server2.get(), &byte, 1), 1);
4238 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
4239 EXPECT_EQ(43, byte);
4240}
4241
4242TEST(SSLTest, HandoffDeclined) {
4243 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4244 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4245 ASSERT_TRUE(client_ctx);
4246 ASSERT_TRUE(server_ctx);
4247
4248 SSL_CTX_set_handoff_mode(server_ctx.get(), 1);
4249 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
4250
4251 bssl::UniquePtr<X509> cert = GetTestCertificate();
4252 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4253 ASSERT_TRUE(cert);
4254 ASSERT_TRUE(key);
4255 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
4256 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
4257
4258 bssl::UniquePtr<SSL> client, server;
4259 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4260 server_ctx.get(), ClientConfig(),
4261 false /* don't handshake */));
4262
4263 int client_ret = SSL_do_handshake(client.get());
4264 int client_err = SSL_get_error(client.get(), client_ret);
4265 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4266
4267 int server_ret = SSL_do_handshake(server.get());
4268 int server_err = SSL_get_error(server.get(), server_ret);
4269 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
4270
4271 ScopedCBB cbb;
Adam Langleyc9827e02019-04-12 14:46:50 -07004272 SSL_CLIENT_HELLO hello;
Adam Langleyddb57cf2018-01-26 09:17:53 -08004273 ASSERT_TRUE(CBB_init(cbb.get(), 256));
Adam Langleyc9827e02019-04-12 14:46:50 -07004274 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004275
4276 ASSERT_TRUE(SSL_decline_handoff(server.get()));
4277
4278 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
4279
4280 uint8_t byte = 42;
4281 EXPECT_EQ(SSL_write(client.get(), &byte, 1), 1);
4282 EXPECT_EQ(SSL_read(server.get(), &byte, 1), 1);
4283 EXPECT_EQ(42, byte);
4284
4285 byte = 43;
4286 EXPECT_EQ(SSL_write(server.get(), &byte, 1), 1);
4287 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
4288 EXPECT_EQ(43, byte);
4289}
4290
Adam Langley826ce152018-08-03 10:31:21 -07004291static std::string SigAlgsToString(Span<const uint16_t> sigalgs) {
4292 std::string ret = "{";
4293
4294 for (uint16_t v : sigalgs) {
4295 if (ret.size() > 1) {
4296 ret += ", ";
4297 }
4298
4299 char buf[8];
4300 snprintf(buf, sizeof(buf) - 1, "0x%02x", v);
4301 buf[sizeof(buf)-1] = 0;
4302 ret += std::string(buf);
4303 }
4304
4305 ret += "}";
4306 return ret;
4307}
4308
4309void ExpectSigAlgsEqual(Span<const uint16_t> expected,
4310 Span<const uint16_t> actual) {
4311 bool matches = false;
4312 if (expected.size() == actual.size()) {
4313 matches = true;
4314
4315 for (size_t i = 0; i < expected.size(); i++) {
4316 if (expected[i] != actual[i]) {
4317 matches = false;
4318 break;
4319 }
4320 }
4321 }
4322
4323 if (!matches) {
4324 ADD_FAILURE() << "expected: " << SigAlgsToString(expected)
4325 << " got: " << SigAlgsToString(actual);
4326 }
4327}
4328
4329TEST(SSLTest, SigAlgs) {
4330 static const struct {
4331 std::vector<int> input;
4332 bool ok;
4333 std::vector<uint16_t> expected;
4334 } kTests[] = {
4335 {{}, true, {}},
4336 {{1}, false, {}},
4337 {{1, 2, 3}, false, {}},
4338 {{NID_sha256, EVP_PKEY_ED25519}, false, {}},
4339 {{NID_sha256, EVP_PKEY_RSA, NID_sha256, EVP_PKEY_RSA}, false, {}},
4340
4341 {{NID_sha256, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA256}},
4342 {{NID_sha512, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA512}},
4343 {{NID_sha256, EVP_PKEY_RSA_PSS}, true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4344 {{NID_undef, EVP_PKEY_ED25519}, true, {SSL_SIGN_ED25519}},
4345 {{NID_undef, EVP_PKEY_ED25519, NID_sha384, EVP_PKEY_EC},
4346 true,
4347 {SSL_SIGN_ED25519, SSL_SIGN_ECDSA_SECP384R1_SHA384}},
4348 };
4349
4350 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4351
4352 unsigned n = 1;
4353 for (const auto &test : kTests) {
4354 SCOPED_TRACE(n++);
4355
4356 const bool ok =
4357 SSL_CTX_set1_sigalgs(ctx.get(), test.input.data(), test.input.size());
4358 EXPECT_EQ(ok, test.ok);
4359
4360 if (!ok) {
4361 ERR_clear_error();
4362 }
4363
4364 if (!test.ok) {
4365 continue;
4366 }
4367
4368 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
4369 }
4370}
4371
4372TEST(SSLTest, SigAlgsList) {
4373 static const struct {
4374 const char *input;
4375 bool ok;
4376 std::vector<uint16_t> expected;
4377 } kTests[] = {
4378 {"", false, {}},
4379 {":", false, {}},
4380 {"+", false, {}},
4381 {"RSA", false, {}},
4382 {"RSA+", false, {}},
4383 {"RSA+SHA256:", false, {}},
4384 {":RSA+SHA256:", false, {}},
4385 {":RSA+SHA256+:", false, {}},
4386 {"!", false, {}},
4387 {"\x01", false, {}},
4388 {"RSA+SHA256:RSA+SHA384:RSA+SHA256", false, {}},
4389 {"RSA-PSS+SHA256:rsa_pss_rsae_sha256", false, {}},
4390
4391 {"RSA+SHA256", true, {SSL_SIGN_RSA_PKCS1_SHA256}},
4392 {"RSA+SHA256:ed25519",
4393 true,
4394 {SSL_SIGN_RSA_PKCS1_SHA256, SSL_SIGN_ED25519}},
4395 {"ECDSA+SHA256:RSA+SHA512",
4396 true,
4397 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PKCS1_SHA512}},
4398 {"ecdsa_secp256r1_sha256:rsa_pss_rsae_sha256",
4399 true,
4400 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4401 {"RSA-PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4402 {"PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4403 };
4404
4405 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4406
4407 unsigned n = 1;
4408 for (const auto &test : kTests) {
4409 SCOPED_TRACE(n++);
4410
4411 const bool ok = SSL_CTX_set1_sigalgs_list(ctx.get(), test.input);
4412 EXPECT_EQ(ok, test.ok);
4413
4414 if (!ok) {
4415 if (test.ok) {
4416 ERR_print_errors_fp(stderr);
4417 }
4418 ERR_clear_error();
4419 }
4420
4421 if (!test.ok) {
4422 continue;
4423 }
4424
4425 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
4426 }
4427}
4428
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004429TEST(SSLTest, ApplyHandoffRemovesUnsupportedCiphers) {
4430 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4431 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
4432
4433 // handoff is a handoff message that has been artificially modified to pretend
4434 // that only cipher 0x0A is supported. When it is applied to |server|, all
4435 // ciphers but that one should be removed.
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004436 //
4437 // To make a new one of these, try sticking this in the |Handoff| test above:
4438 //
4439 // hexdump(stderr, "", handoff.data(), handoff.size());
4440 // sed -e 's/\(..\)/0x\1, /g'
4441 //
4442 // and modify serialize_features() to emit only cipher 0x0A.
4443
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004444 uint8_t handoff[] = {
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004445 0x30, 0x81, 0x9a, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
4446 0x00, 0x00, 0x7e, 0x03, 0x03, 0x30, 0x8e, 0x8f, 0x79, 0xd2, 0x87, 0x39,
4447 0xc2, 0x23, 0x23, 0x13, 0xca, 0x3c, 0x80, 0x44, 0xfd, 0x80, 0x83, 0x62,
4448 0x3c, 0xcc, 0xf8, 0x76, 0xd3, 0x62, 0xbb, 0x54, 0xe3, 0xc4, 0x39, 0x24,
4449 0xa5, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004450 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
4451 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004452 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
4453 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
4454 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
4455 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
4456 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x02, 0x00,
4457 0x0a, 0x04, 0x0a, 0x00, 0x15, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00,
4458 0x1d,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004459 };
4460
4461 EXPECT_EQ(20u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
4462 ASSERT_TRUE(
4463 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
4464 EXPECT_EQ(1u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
4465}
4466
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004467TEST(SSLTest, ApplyHandoffRemovesUnsupportedCurves) {
4468 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4469 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
4470
4471 // handoff is a handoff message that has been artificially modified to pretend
4472 // that only one curve is supported. When it is applied to |server|, all
4473 // curves but that one should be removed.
4474 //
4475 // See |ApplyHandoffRemovesUnsupportedCiphers| for how to make a new one of
4476 // these.
4477 uint8_t handoff[] = {
4478 0x30, 0x81, 0xc0, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
4479 0x00, 0x00, 0x7e, 0x03, 0x03, 0x98, 0x30, 0xce, 0xd9, 0xb0, 0xdf, 0x5f,
4480 0x82, 0x05, 0x4a, 0x43, 0x67, 0x7e, 0xdb, 0x6a, 0x4f, 0x21, 0x18, 0x4e,
4481 0x0d, 0x94, 0x63, 0x18, 0x8b, 0x54, 0x89, 0xdb, 0x8b, 0x1d, 0x84, 0xbc,
4482 0x09, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
4483 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
4484 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
4485 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
4486 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
4487 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
4488 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
4489 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x30, 0x00,
4490 0x02, 0x00, 0x0a, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x8c, 0x00, 0x8d, 0x00,
4491 0x9c, 0x00, 0x9d, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xc0, 0x09, 0xc0,
4492 0x0a, 0xc0, 0x13, 0xc0, 0x14, 0xc0, 0x2b, 0xc0, 0x2c, 0xc0, 0x2f, 0xc0,
4493 0x30, 0xc0, 0x35, 0xc0, 0x36, 0xcc, 0xa8, 0xcc, 0xa9, 0xcc, 0xac, 0x04,
4494 0x02, 0x00, 0x17,
4495 };
4496
4497 // The zero length means that the default list of groups is used.
4498 EXPECT_EQ(0u, server->config->supported_group_list.size());
4499 ASSERT_TRUE(
4500 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
4501 EXPECT_EQ(1u, server->config->supported_group_list.size());
4502}
4503
Adam Langleyba9ad662018-12-17 13:59:38 -08004504TEST(SSLTest, ZeroSizedWiteFlushesHandshakeMessages) {
4505 // If there are pending handshake mesages, an |SSL_write| of zero bytes should
4506 // flush them.
4507 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4508 EXPECT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
4509 EXPECT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
4510 bssl::UniquePtr<X509> cert = GetTestCertificate();
4511 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4512 ASSERT_TRUE(cert);
4513 ASSERT_TRUE(key);
4514 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
4515 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
4516
4517 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4518 EXPECT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
4519 EXPECT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
4520
4521 bssl::UniquePtr<SSL> client, server;
4522 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4523 server_ctx.get()));
4524
4525 BIO *client_wbio = SSL_get_wbio(client.get());
4526 EXPECT_EQ(0u, BIO_wpending(client_wbio));
4527 EXPECT_TRUE(SSL_key_update(client.get(), SSL_KEY_UPDATE_NOT_REQUESTED));
4528 EXPECT_EQ(0u, BIO_wpending(client_wbio));
4529 EXPECT_EQ(0, SSL_write(client.get(), nullptr, 0));
4530 EXPECT_NE(0u, BIO_wpending(client_wbio));
4531}
4532
David Benjamin5869eb32018-07-17 00:59:45 -04004533TEST_P(SSLVersionTest, VerifyBeforeCertRequest) {
4534 // Configure the server to request client certificates.
4535 SSL_CTX_set_custom_verify(
4536 server_ctx_.get(), SSL_VERIFY_PEER,
4537 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
4538
4539 // Configure the client to reject the server certificate.
4540 SSL_CTX_set_custom_verify(
4541 client_ctx_.get(), SSL_VERIFY_PEER,
4542 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_invalid; });
4543
4544 // cert_cb should not be called. Verification should fail first.
4545 SSL_CTX_set_cert_cb(client_ctx_.get(),
4546 [](SSL *ssl, void *arg) {
4547 ADD_FAILURE() << "cert_cb unexpectedly called";
4548 return 0;
4549 },
4550 nullptr);
4551
4552 bssl::UniquePtr<SSL> client, server;
4553 EXPECT_FALSE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
4554 server_ctx_.get()));
4555}
4556
David Benjamin492c9aa2018-08-31 16:35:22 -05004557// Test that ticket-based sessions on the client get fake session IDs.
4558TEST_P(SSLVersionTest, FakeIDsForTickets) {
4559 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4560 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4561
4562 bssl::UniquePtr<SSL_SESSION> session =
4563 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4564 ASSERT_TRUE(session);
4565
4566 EXPECT_TRUE(SSL_SESSION_has_ticket(session.get()));
4567 unsigned session_id_length;
4568 SSL_SESSION_get_id(session.get(), &session_id_length);
4569 EXPECT_NE(session_id_length, 0u);
4570}
4571
David Benjamin6c04bd12018-07-19 18:13:09 -04004572// These tests test multi-threaded behavior. They are intended to run with
4573// ThreadSanitizer.
David Benjamin5b33eff2018-09-22 16:52:48 -07004574#if defined(OPENSSL_THREADS)
David Benjamin6c04bd12018-07-19 18:13:09 -04004575TEST_P(SSLVersionTest, SessionCacheThreads) {
4576 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
4577 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4578 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4579
4580 if (version() == TLS1_3_VERSION) {
4581 // Our TLS 1.3 implementation does not support stateful resumption.
4582 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
4583 return;
4584 }
4585
4586 // Establish two client sessions to test with.
4587 bssl::UniquePtr<SSL_SESSION> session1 =
4588 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4589 ASSERT_TRUE(session1);
4590 bssl::UniquePtr<SSL_SESSION> session2 =
4591 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4592 ASSERT_TRUE(session2);
4593
4594 auto connect_with_session = [&](SSL_SESSION *session) {
4595 ClientConfig config;
4596 config.session = session;
4597 UniquePtr<SSL> client, server;
4598 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
4599 server_ctx_.get(), config));
4600 };
4601
4602 // Resume sessions in parallel with establishing new ones.
4603 {
4604 std::vector<std::thread> threads;
4605 threads.emplace_back([&] { connect_with_session(nullptr); });
4606 threads.emplace_back([&] { connect_with_session(nullptr); });
4607 threads.emplace_back([&] { connect_with_session(session1.get()); });
4608 threads.emplace_back([&] { connect_with_session(session1.get()); });
4609 threads.emplace_back([&] { connect_with_session(session2.get()); });
4610 threads.emplace_back([&] { connect_with_session(session2.get()); });
4611 for (auto &thread : threads) {
4612 thread.join();
4613 }
4614 }
4615
4616 // Hit the maximum session cache size across multiple threads
4617 size_t limit = SSL_CTX_sess_number(server_ctx_.get()) + 2;
4618 SSL_CTX_sess_set_cache_size(server_ctx_.get(), limit);
4619 {
4620 std::vector<std::thread> threads;
4621 for (int i = 0; i < 4; i++) {
4622 threads.emplace_back([&]() {
4623 connect_with_session(nullptr);
4624 EXPECT_LE(SSL_CTX_sess_number(server_ctx_.get()), limit);
4625 });
4626 }
4627 for (auto &thread : threads) {
4628 thread.join();
4629 }
4630 EXPECT_EQ(SSL_CTX_sess_number(server_ctx_.get()), limit);
4631 }
4632}
4633
4634TEST_P(SSLVersionTest, SessionTicketThreads) {
4635 for (bool renew_ticket : {false, true}) {
4636 SCOPED_TRACE(renew_ticket);
4637 ResetContexts();
4638 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4639 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4640 if (renew_ticket) {
4641 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
4642 }
4643
4644 // Establish two client sessions to test with.
4645 bssl::UniquePtr<SSL_SESSION> session1 =
4646 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4647 ASSERT_TRUE(session1);
4648 bssl::UniquePtr<SSL_SESSION> session2 =
4649 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4650 ASSERT_TRUE(session2);
4651
4652 auto connect_with_session = [&](SSL_SESSION *session) {
4653 ClientConfig config;
4654 config.session = session;
4655 UniquePtr<SSL> client, server;
4656 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
4657 server_ctx_.get(), config));
4658 };
4659
4660 // Resume sessions in parallel with establishing new ones.
4661 {
4662 std::vector<std::thread> threads;
4663 threads.emplace_back([&] { connect_with_session(nullptr); });
4664 threads.emplace_back([&] { connect_with_session(nullptr); });
4665 threads.emplace_back([&] { connect_with_session(session1.get()); });
4666 threads.emplace_back([&] { connect_with_session(session1.get()); });
4667 threads.emplace_back([&] { connect_with_session(session2.get()); });
4668 threads.emplace_back([&] { connect_with_session(session2.get()); });
4669 for (auto &thread : threads) {
4670 thread.join();
4671 }
4672 }
4673 }
4674}
4675
4676// SSL_CTX_get0_certificate needs to lock internally. Test this works.
4677TEST(SSLTest, GetCertificateThreads) {
4678 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4679 ASSERT_TRUE(ctx);
4680 bssl::UniquePtr<X509> cert = GetTestCertificate();
4681 ASSERT_TRUE(cert);
4682 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
4683
4684 // Existing code expects |SSL_CTX_get0_certificate| to be callable from two
4685 // threads concurrently. It originally was an immutable operation. Now we
4686 // implement it with a thread-safe cache, so it is worth testing.
4687 X509 *cert2_thread;
4688 std::thread thread(
4689 [&] { cert2_thread = SSL_CTX_get0_certificate(ctx.get()); });
4690 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
4691 thread.join();
4692
4693 EXPECT_EQ(cert2, cert2_thread);
4694 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
4695}
David Benjamin4cce9552018-12-13 12:20:54 -06004696
4697// Functions which access properties on the negotiated session are thread-safe
4698// where needed. Prior to TLS 1.3, clients resuming sessions and servers
4699// performing stateful resumption will share an underlying SSL_SESSION object,
4700// potentially across threads.
4701TEST_P(SSLVersionTest, SessionPropertiesThreads) {
4702 if (version() == TLS1_3_VERSION) {
4703 // Our TLS 1.3 implementation does not support stateful resumption.
4704 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
4705 return;
4706 }
4707
4708 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
4709 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4710 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4711
4712 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
4713 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
4714
4715 // Configure mutual authentication, so we have more session state.
4716 SSL_CTX_set_custom_verify(
4717 client_ctx_.get(), SSL_VERIFY_PEER,
4718 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
4719 SSL_CTX_set_custom_verify(
4720 server_ctx_.get(), SSL_VERIFY_PEER,
4721 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
4722
4723 // Establish a client session to test with.
4724 bssl::UniquePtr<SSL_SESSION> session =
4725 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4726 ASSERT_TRUE(session);
4727
4728 // Resume with it twice.
4729 UniquePtr<SSL> ssls[4];
4730 ClientConfig config;
4731 config.session = session.get();
4732 ASSERT_TRUE(ConnectClientAndServer(&ssls[0], &ssls[1], client_ctx_.get(),
4733 server_ctx_.get(), config));
4734 ASSERT_TRUE(ConnectClientAndServer(&ssls[2], &ssls[3], client_ctx_.get(),
4735 server_ctx_.get(), config));
4736
4737 // Read properties in parallel.
4738 auto read_properties = [](const SSL *ssl) {
4739 EXPECT_TRUE(SSL_get_peer_cert_chain(ssl));
4740 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(ssl));
4741 EXPECT_TRUE(peer);
4742 EXPECT_TRUE(SSL_get_current_cipher(ssl));
4743 EXPECT_TRUE(SSL_get_curve_id(ssl));
4744 };
4745
4746 std::vector<std::thread> threads;
4747 for (const auto &ssl_ptr : ssls) {
4748 const SSL *ssl = ssl_ptr.get();
4749 threads.emplace_back([=] { read_properties(ssl); });
4750 }
4751 for (auto &thread : threads) {
4752 thread.join();
4753 }
4754}
David Benjamina486c6c2019-03-28 18:32:38 -05004755#endif // OPENSSL_THREADS
David Benjamin6c04bd12018-07-19 18:13:09 -04004756
Steven Valdezc8e0f902018-07-14 11:23:01 -04004757constexpr size_t kNumQUICLevels = 4;
4758static_assert(ssl_encryption_initial < kNumQUICLevels,
4759 "kNumQUICLevels is wrong");
4760static_assert(ssl_encryption_early_data < kNumQUICLevels,
4761 "kNumQUICLevels is wrong");
4762static_assert(ssl_encryption_handshake < kNumQUICLevels,
4763 "kNumQUICLevels is wrong");
4764static_assert(ssl_encryption_application < kNumQUICLevels,
4765 "kNumQUICLevels is wrong");
4766
4767class MockQUICTransport {
4768 public:
David Benjamind6343572019-08-15 17:29:02 -04004769 enum class Role { kClient, kServer };
4770
4771 explicit MockQUICTransport(Role role) : role_(role) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04004772 // The caller is expected to configure initial secrets.
4773 levels_[ssl_encryption_initial].write_secret = {1};
4774 levels_[ssl_encryption_initial].read_secret = {1};
4775 }
4776
4777 void set_peer(MockQUICTransport *peer) { peer_ = peer; }
4778
4779 bool has_alert() const { return has_alert_; }
4780 ssl_encryption_level_t alert_level() const { return alert_level_; }
4781 uint8_t alert() const { return alert_; }
4782
4783 bool PeerSecretsMatch(ssl_encryption_level_t level) const {
4784 return levels_[level].write_secret == peer_->levels_[level].read_secret &&
Steven Valdez384d0ea2018-11-06 10:45:36 -05004785 levels_[level].read_secret == peer_->levels_[level].write_secret &&
4786 levels_[level].cipher == peer_->levels_[level].cipher;
Steven Valdezc8e0f902018-07-14 11:23:01 -04004787 }
4788
4789 bool HasSecrets(ssl_encryption_level_t level) const {
4790 return !levels_[level].write_secret.empty() ||
4791 !levels_[level].read_secret.empty();
4792 }
4793
4794 bool SetEncryptionSecrets(ssl_encryption_level_t level,
4795 const uint8_t *read_secret,
Steven Valdez384d0ea2018-11-06 10:45:36 -05004796 const uint8_t *write_secret, size_t secret_len,
4797 const SSL_CIPHER *cipher) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04004798 if (HasSecrets(level)) {
4799 ADD_FAILURE() << "duplicate keys configured";
4800 return false;
4801 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05004802
4803 if (cipher == nullptr) {
4804 ADD_FAILURE() << "current cipher unavailable";
4805 return false;
4806 }
4807
David Benjamind6343572019-08-15 17:29:02 -04004808 bool expect_read_secret = true, expect_write_secret = true;
4809 if (level == ssl_encryption_early_data) {
4810 if (role_ == Role::kClient) {
4811 expect_read_secret = false;
4812 } else {
4813 expect_write_secret = false;
4814 }
4815 }
4816
4817 if (expect_read_secret) {
4818 if (read_secret == nullptr) {
4819 ADD_FAILURE() << "read secret was unexpectedly null";
4820 return false;
4821 }
4822 levels_[level].read_secret.assign(read_secret, read_secret + secret_len);
4823 } else if (read_secret != nullptr) {
4824 ADD_FAILURE() << "unexpected read secret";
Steven Valdezc8e0f902018-07-14 11:23:01 -04004825 return false;
4826 }
David Benjamind6343572019-08-15 17:29:02 -04004827
4828 if (expect_write_secret) {
4829 if (write_secret == nullptr) {
4830 ADD_FAILURE() << "write secret was unexpectedly null";
4831 return false;
4832 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04004833 levels_[level].write_secret.assign(write_secret,
4834 write_secret + secret_len);
David Benjamind6343572019-08-15 17:29:02 -04004835 } else if (write_secret != nullptr) {
4836 ADD_FAILURE() << "unexpected write secret";
4837 return false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04004838 }
David Benjamind6343572019-08-15 17:29:02 -04004839
Steven Valdez384d0ea2018-11-06 10:45:36 -05004840 levels_[level].cipher = SSL_CIPHER_get_id(cipher);
Steven Valdezc8e0f902018-07-14 11:23:01 -04004841 return true;
4842 }
4843
4844 bool WriteHandshakeData(ssl_encryption_level_t level,
4845 Span<const uint8_t> data) {
4846 if (levels_[level].write_secret.empty()) {
4847 ADD_FAILURE() << "data written before keys configured";
4848 return false;
4849 }
4850 levels_[level].write_data.insert(levels_[level].write_data.end(),
4851 data.begin(), data.end());
4852 return true;
4853 }
4854
4855 bool SendAlert(ssl_encryption_level_t level, uint8_t alert_value) {
4856 if (has_alert_) {
4857 ADD_FAILURE() << "duplicate alert sent";
4858 return false;
4859 }
4860
4861 if (levels_[level].write_secret.empty()) {
4862 ADD_FAILURE() << "alert sent before keys configured";
4863 return false;
4864 }
4865
4866 has_alert_ = true;
4867 alert_level_ = level;
4868 alert_ = alert_value;
4869 return true;
4870 }
4871
4872 bool ReadHandshakeData(std::vector<uint8_t> *out,
4873 ssl_encryption_level_t level,
4874 size_t num = std::numeric_limits<size_t>::max()) {
4875 if (levels_[level].read_secret.empty()) {
David Benjamind6343572019-08-15 17:29:02 -04004876 ADD_FAILURE() << "data read before keys configured in level " << level;
Steven Valdezc8e0f902018-07-14 11:23:01 -04004877 return false;
4878 }
4879 // The peer may not have configured any keys yet.
4880 if (peer_->levels_[level].write_secret.empty()) {
David Benjamind0b97942019-08-21 12:54:20 -04004881 out->clear();
Steven Valdezc8e0f902018-07-14 11:23:01 -04004882 return true;
4883 }
4884 // Check the peer computed the same key.
4885 if (peer_->levels_[level].write_secret != levels_[level].read_secret) {
David Benjamind6343572019-08-15 17:29:02 -04004886 ADD_FAILURE() << "peer write key does not match read key in level "
4887 << level;
Steven Valdezc8e0f902018-07-14 11:23:01 -04004888 return false;
4889 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05004890 if (peer_->levels_[level].cipher != levels_[level].cipher) {
David Benjamind6343572019-08-15 17:29:02 -04004891 ADD_FAILURE() << "peer cipher does not match in level " << level;
Steven Valdez384d0ea2018-11-06 10:45:36 -05004892 return false;
4893 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04004894 std::vector<uint8_t> *peer_data = &peer_->levels_[level].write_data;
4895 num = std::min(num, peer_data->size());
4896 out->assign(peer_data->begin(), peer_data->begin() + num);
4897 peer_data->erase(peer_data->begin(), peer_data->begin() + num);
4898 return true;
4899 }
4900
4901 private:
David Benjamind6343572019-08-15 17:29:02 -04004902 Role role_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04004903 MockQUICTransport *peer_ = nullptr;
4904
4905 bool has_alert_ = false;
4906 ssl_encryption_level_t alert_level_ = ssl_encryption_initial;
4907 uint8_t alert_ = 0;
4908
4909 struct Level {
4910 std::vector<uint8_t> write_data;
4911 std::vector<uint8_t> write_secret;
4912 std::vector<uint8_t> read_secret;
Steven Valdez384d0ea2018-11-06 10:45:36 -05004913 uint32_t cipher = 0;
Steven Valdezc8e0f902018-07-14 11:23:01 -04004914 };
4915 Level levels_[kNumQUICLevels];
4916};
4917
4918class MockQUICTransportPair {
4919 public:
David Benjamind6343572019-08-15 17:29:02 -04004920 MockQUICTransportPair()
4921 : client_(MockQUICTransport::Role::kClient),
4922 server_(MockQUICTransport::Role::kServer) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04004923 client_.set_peer(&server_);
David Benjamind6343572019-08-15 17:29:02 -04004924 server_.set_peer(&client_);
Steven Valdezc8e0f902018-07-14 11:23:01 -04004925 }
4926
4927 ~MockQUICTransportPair() {
Steven Valdezc8e0f902018-07-14 11:23:01 -04004928 client_.set_peer(nullptr);
David Benjamind6343572019-08-15 17:29:02 -04004929 server_.set_peer(nullptr);
Steven Valdezc8e0f902018-07-14 11:23:01 -04004930 }
4931
4932 MockQUICTransport *client() { return &client_; }
4933 MockQUICTransport *server() { return &server_; }
4934
4935 bool SecretsMatch(ssl_encryption_level_t level) const {
David Benjamind6343572019-08-15 17:29:02 -04004936 return client_.HasSecrets(level) && server_.HasSecrets(level) &&
4937 client_.PeerSecretsMatch(level);
Steven Valdezc8e0f902018-07-14 11:23:01 -04004938 }
4939
4940 private:
4941 MockQUICTransport client_;
4942 MockQUICTransport server_;
4943};
4944
4945class QUICMethodTest : public testing::Test {
4946 protected:
4947 void SetUp() override {
4948 client_ctx_.reset(SSL_CTX_new(TLS_method()));
4949 server_ctx_.reset(SSL_CTX_new(TLS_method()));
4950 ASSERT_TRUE(client_ctx_);
4951 ASSERT_TRUE(server_ctx_);
4952
4953 bssl::UniquePtr<X509> cert = GetTestCertificate();
4954 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4955 ASSERT_TRUE(cert);
4956 ASSERT_TRUE(key);
4957 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx_.get(), cert.get()));
4958 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx_.get(), key.get()));
4959
4960 SSL_CTX_set_min_proto_version(server_ctx_.get(), TLS1_3_VERSION);
4961 SSL_CTX_set_max_proto_version(server_ctx_.get(), TLS1_3_VERSION);
4962 SSL_CTX_set_min_proto_version(client_ctx_.get(), TLS1_3_VERSION);
4963 SSL_CTX_set_max_proto_version(client_ctx_.get(), TLS1_3_VERSION);
4964 }
4965
4966 static MockQUICTransport *TransportFromSSL(const SSL *ssl) {
4967 return ex_data_.Get(ssl);
4968 }
4969
4970 static bool ProvideHandshakeData(
4971 SSL *ssl, size_t num = std::numeric_limits<size_t>::max()) {
4972 MockQUICTransport *transport = TransportFromSSL(ssl);
4973 ssl_encryption_level_t level = SSL_quic_read_level(ssl);
4974 std::vector<uint8_t> data;
4975 return transport->ReadHandshakeData(&data, level, num) &&
4976 SSL_provide_quic_data(ssl, level, data.data(), data.size());
4977 }
4978
4979 bool CreateClientAndServer() {
4980 client_.reset(SSL_new(client_ctx_.get()));
4981 server_.reset(SSL_new(server_ctx_.get()));
4982 if (!client_ || !server_) {
4983 return false;
4984 }
4985
4986 SSL_set_connect_state(client_.get());
4987 SSL_set_accept_state(server_.get());
4988
David Benjamind6343572019-08-15 17:29:02 -04004989 transport_.reset(new MockQUICTransportPair);
4990 ex_data_.Set(client_.get(), transport_->client());
4991 ex_data_.Set(server_.get(), transport_->server());
Steven Valdezc8e0f902018-07-14 11:23:01 -04004992 return true;
4993 }
4994
David Benjamind6343572019-08-15 17:29:02 -04004995 // CompleteHandshakesForQUIC runs |SSL_do_handshake| on |client_| and
4996 // |server_| until each completes once. It returns true on success and false
4997 // on failure.
4998 bool CompleteHandshakesForQUIC() {
4999 bool client_done = false, server_done = false;
5000 while (!client_done || !server_done) {
5001 if (!client_done) {
5002 if (!ProvideHandshakeData(client_.get())) {
5003 ADD_FAILURE() << "ProvideHandshakeData(client_) failed";
5004 return false;
5005 }
5006 int client_ret = SSL_do_handshake(client_.get());
5007 if (client_ret == 1) {
5008 client_done = true;
5009 } else {
5010 EXPECT_EQ(client_ret, -1);
5011 EXPECT_EQ(SSL_get_error(client_.get(), client_ret),
5012 SSL_ERROR_WANT_READ);
5013 }
5014 }
5015
5016 if (!server_done) {
5017 if (!ProvideHandshakeData(server_.get())) {
5018 ADD_FAILURE() << "ProvideHandshakeData(server_) failed";
5019 return false;
5020 }
5021 int server_ret = SSL_do_handshake(server_.get());
5022 if (server_ret == 1) {
5023 server_done = true;
5024 } else {
5025 EXPECT_EQ(server_ret, -1);
5026 EXPECT_EQ(SSL_get_error(server_.get(), server_ret),
5027 SSL_ERROR_WANT_READ);
5028 }
5029 }
5030 }
5031 return true;
5032 }
5033
5034 bssl::UniquePtr<SSL_SESSION> CreateClientSessionForQUIC() {
5035 g_last_session = nullptr;
5036 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
5037 if (!CreateClientAndServer() ||
5038 !CompleteHandshakesForQUIC()) {
5039 return nullptr;
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005040 }
5041
David Benjamind6343572019-08-15 17:29:02 -04005042 // The server sent NewSessionTicket messages in the handshake.
5043 if (!ProvideHandshakeData(client_.get()) ||
5044 !SSL_process_quic_post_handshake(client_.get())) {
5045 return nullptr;
5046 }
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005047
David Benjamind6343572019-08-15 17:29:02 -04005048 return std::move(g_last_session);
5049 }
5050
5051 void ExpectHandshakeSuccess() {
5052 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_application));
5053 EXPECT_EQ(ssl_encryption_application, SSL_quic_read_level(client_.get()));
5054 EXPECT_EQ(ssl_encryption_application, SSL_quic_write_level(client_.get()));
5055 EXPECT_EQ(ssl_encryption_application, SSL_quic_read_level(server_.get()));
5056 EXPECT_EQ(ssl_encryption_application, SSL_quic_write_level(server_.get()));
5057 EXPECT_FALSE(transport_->client()->has_alert());
5058 EXPECT_FALSE(transport_->server()->has_alert());
5059
5060 // SSL_do_handshake is now idempotent.
5061 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
5062 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005063 }
5064
Steven Valdezc8e0f902018-07-14 11:23:01 -04005065 // The following functions may be configured on an |SSL_QUIC_METHOD| as
5066 // default implementations.
5067
5068 static int SetEncryptionSecretsCallback(SSL *ssl,
5069 ssl_encryption_level_t level,
5070 const uint8_t *read_key,
5071 const uint8_t *write_key,
5072 size_t key_len) {
Steven Valdez384d0ea2018-11-06 10:45:36 -05005073 return TransportFromSSL(ssl)->SetEncryptionSecrets(
5074 level, read_key, write_key, key_len, SSL_get_current_cipher(ssl));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005075 }
5076
David Benjamincc9d9352018-10-30 19:45:22 -05005077 static int AddHandshakeDataCallback(SSL *ssl,
5078 enum ssl_encryption_level_t level,
5079 const uint8_t *data, size_t len) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005080 EXPECT_EQ(level, SSL_quic_write_level(ssl));
5081 return TransportFromSSL(ssl)->WriteHandshakeData(level,
5082 MakeConstSpan(data, len));
5083 }
5084
5085 static int FlushFlightCallback(SSL *ssl) { return 1; }
5086
5087 static int SendAlertCallback(SSL *ssl, ssl_encryption_level_t level,
5088 uint8_t alert) {
5089 EXPECT_EQ(level, SSL_quic_write_level(ssl));
5090 return TransportFromSSL(ssl)->SendAlert(level, alert);
5091 }
5092
5093 bssl::UniquePtr<SSL_CTX> client_ctx_;
5094 bssl::UniquePtr<SSL_CTX> server_ctx_;
5095
5096 static UnownedSSLExData<MockQUICTransport> ex_data_;
David Benjamind6343572019-08-15 17:29:02 -04005097 std::unique_ptr<MockQUICTransportPair> transport_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005098
5099 bssl::UniquePtr<SSL> client_;
5100 bssl::UniquePtr<SSL> server_;
5101};
5102
5103UnownedSSLExData<MockQUICTransport> QUICMethodTest::ex_data_;
5104
David Benjaminfd863b62019-07-25 13:51:32 -04005105// Test a full handshake and resumption work.
Steven Valdezc8e0f902018-07-14 11:23:01 -04005106TEST_F(QUICMethodTest, Basic) {
5107 const SSL_QUIC_METHOD quic_method = {
5108 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05005109 AddHandshakeDataCallback,
Steven Valdezc8e0f902018-07-14 11:23:01 -04005110 FlushFlightCallback,
5111 SendAlertCallback,
5112 };
5113
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005114 g_last_session = nullptr;
5115
5116 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5117 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005118 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5119 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
David Benjamind6343572019-08-15 17:29:02 -04005120
Steven Valdezc8e0f902018-07-14 11:23:01 -04005121 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04005122 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdezc8e0f902018-07-14 11:23:01 -04005123
David Benjamind6343572019-08-15 17:29:02 -04005124 ExpectHandshakeSuccess();
5125 EXPECT_FALSE(SSL_session_reused(client_.get()));
5126 EXPECT_FALSE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005127
5128 // The server sent NewSessionTicket messages in the handshake.
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005129 EXPECT_FALSE(g_last_session);
5130 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5131 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
5132 EXPECT_TRUE(g_last_session);
5133
5134 // Create a second connection to verify resumption works.
David Benjamind6343572019-08-15 17:29:02 -04005135 ASSERT_TRUE(CreateClientAndServer());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005136 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
5137 SSL_set_session(client_.get(), session.get());
5138
David Benjamind6343572019-08-15 17:29:02 -04005139 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005140
David Benjamind6343572019-08-15 17:29:02 -04005141 ExpectHandshakeSuccess();
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005142 EXPECT_TRUE(SSL_session_reused(client_.get()));
5143 EXPECT_TRUE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005144}
5145
David Benjaminfd863b62019-07-25 13:51:32 -04005146// Test that HelloRetryRequest in QUIC works.
5147TEST_F(QUICMethodTest, HelloRetryRequest) {
5148 const SSL_QUIC_METHOD quic_method = {
5149 SetEncryptionSecretsCallback,
5150 AddHandshakeDataCallback,
5151 FlushFlightCallback,
5152 SendAlertCallback,
5153 };
5154
5155 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5156 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5157
5158 // BoringSSL predicts the most preferred curve, so using different preferences
5159 // will trigger HelloRetryRequest.
5160 static const int kClientPrefs[] = {NID_X25519, NID_X9_62_prime256v1};
5161 ASSERT_TRUE(SSL_CTX_set1_curves(client_ctx_.get(), kClientPrefs,
5162 OPENSSL_ARRAY_SIZE(kClientPrefs)));
5163 static const int kServerPrefs[] = {NID_X9_62_prime256v1, NID_X25519};
5164 ASSERT_TRUE(SSL_CTX_set1_curves(server_ctx_.get(), kServerPrefs,
5165 OPENSSL_ARRAY_SIZE(kServerPrefs)));
5166
5167 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04005168 ASSERT_TRUE(CompleteHandshakesForQUIC());
5169 ExpectHandshakeSuccess();
5170}
David Benjaminfd863b62019-07-25 13:51:32 -04005171
David Benjamind6343572019-08-15 17:29:02 -04005172TEST_F(QUICMethodTest, ZeroRTTAccept) {
5173 const SSL_QUIC_METHOD quic_method = {
5174 SetEncryptionSecretsCallback,
5175 AddHandshakeDataCallback,
5176 FlushFlightCallback,
5177 SendAlertCallback,
5178 };
5179
5180 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5181 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
5182 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
5183 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5184 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5185
5186 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
5187 ASSERT_TRUE(session);
5188
5189 ASSERT_TRUE(CreateClientAndServer());
5190 SSL_set_session(client_.get(), session.get());
5191
5192 // The client handshake should return immediately into the early data state.
5193 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
5194 EXPECT_TRUE(SSL_in_early_data(client_.get()));
5195 // The transport should have keys for sending 0-RTT data.
5196 EXPECT_TRUE(
5197 transport_->client()->HasSecrets(ssl_encryption_early_data));
5198
5199 // The server will consume the ClientHello and also enter the early data
5200 // state.
5201 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5202 ASSERT_EQ(SSL_do_handshake(server_.get()), 1);
5203 EXPECT_TRUE(SSL_in_early_data(server_.get()));
5204 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_early_data));
5205 // The transport should have keys for sending half-RTT data.
5206 EXPECT_TRUE(
5207 transport_->server()->HasSecrets(ssl_encryption_application));
5208
5209 // Finish up the client and server handshakes.
5210 ASSERT_TRUE(CompleteHandshakesForQUIC());
5211
5212 // Both sides can now exchange 1-RTT data.
5213 ExpectHandshakeSuccess();
5214 EXPECT_TRUE(SSL_session_reused(client_.get()));
5215 EXPECT_TRUE(SSL_session_reused(server_.get()));
5216 EXPECT_FALSE(SSL_in_early_data(client_.get()));
5217 EXPECT_FALSE(SSL_in_early_data(server_.get()));
5218 EXPECT_TRUE(SSL_early_data_accepted(client_.get()));
5219 EXPECT_TRUE(SSL_early_data_accepted(server_.get()));
5220}
5221
5222TEST_F(QUICMethodTest, ZeroRTTReject) {
5223 const SSL_QUIC_METHOD quic_method = {
5224 SetEncryptionSecretsCallback,
5225 AddHandshakeDataCallback,
5226 FlushFlightCallback,
5227 SendAlertCallback,
5228 };
5229
5230 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5231 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
5232 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
5233 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5234 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5235
5236 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
5237 ASSERT_TRUE(session);
5238
5239 for (bool reject_hrr : {false, true}) {
5240 SCOPED_TRACE(reject_hrr);
5241
5242 ASSERT_TRUE(CreateClientAndServer());
5243 if (reject_hrr) {
5244 // Configure the server to prefer P-256, which will reject 0-RTT via
5245 // HelloRetryRequest.
5246 int p256 = NID_X9_62_prime256v1;
5247 ASSERT_TRUE(SSL_set1_curves(server_.get(), &p256, 1));
5248 } else {
5249 // Disable 0-RTT on the server, so it will reject it.
5250 SSL_set_early_data_enabled(server_.get(), 0);
David Benjaminfd863b62019-07-25 13:51:32 -04005251 }
David Benjamind6343572019-08-15 17:29:02 -04005252 SSL_set_session(client_.get(), session.get());
David Benjaminfd863b62019-07-25 13:51:32 -04005253
David Benjamind6343572019-08-15 17:29:02 -04005254 // The client handshake should return immediately into the early data state.
5255 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
5256 EXPECT_TRUE(SSL_in_early_data(client_.get()));
5257 // The transport should have keys for sending 0-RTT data.
5258 EXPECT_TRUE(transport_->client()->HasSecrets(ssl_encryption_early_data));
5259
5260 // The server will consume the ClientHello, but it will not accept 0-RTT.
David Benjaminfd863b62019-07-25 13:51:32 -04005261 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
David Benjamind6343572019-08-15 17:29:02 -04005262 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
5263 EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
5264 EXPECT_FALSE(SSL_in_early_data(server_.get()));
5265 EXPECT_FALSE(transport_->server()->HasSecrets(ssl_encryption_early_data));
5266
5267 // The client consumes the server response and signals 0-RTT rejection.
5268 for (;;) {
5269 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5270 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
5271 int err = SSL_get_error(client_.get(), -1);
5272 if (err == SSL_ERROR_EARLY_DATA_REJECTED) {
5273 break;
5274 }
5275 ASSERT_EQ(SSL_ERROR_WANT_READ, err);
David Benjaminfd863b62019-07-25 13:51:32 -04005276 }
5277
David Benjamind6343572019-08-15 17:29:02 -04005278 // As in TLS over TCP, 0-RTT rejection is sticky.
5279 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
5280 ASSERT_EQ(SSL_ERROR_EARLY_DATA_REJECTED, SSL_get_error(client_.get(), -1));
5281
5282 // Finish up the client and server handshakes.
5283 SSL_reset_early_data_reject(client_.get());
5284 ASSERT_TRUE(CompleteHandshakesForQUIC());
5285
5286 // Both sides can now exchange 1-RTT data.
5287 ExpectHandshakeSuccess();
5288 EXPECT_TRUE(SSL_session_reused(client_.get()));
5289 EXPECT_TRUE(SSL_session_reused(server_.get()));
5290 EXPECT_FALSE(SSL_in_early_data(client_.get()));
5291 EXPECT_FALSE(SSL_in_early_data(server_.get()));
5292 EXPECT_FALSE(SSL_early_data_accepted(client_.get()));
5293 EXPECT_FALSE(SSL_early_data_accepted(server_.get()));
David Benjaminfd863b62019-07-25 13:51:32 -04005294 }
David Benjaminfd863b62019-07-25 13:51:32 -04005295}
5296
Steven Valdezc8e0f902018-07-14 11:23:01 -04005297// Test only releasing data to QUIC one byte at a time on request, to maximize
5298// state machine pauses. Additionally, test that existing asynchronous callbacks
5299// still work.
5300TEST_F(QUICMethodTest, Async) {
5301 const SSL_QUIC_METHOD quic_method = {
5302 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05005303 AddHandshakeDataCallback,
Steven Valdezc8e0f902018-07-14 11:23:01 -04005304 FlushFlightCallback,
5305 SendAlertCallback,
5306 };
5307
5308 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5309 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5310 ASSERT_TRUE(CreateClientAndServer());
5311
5312 // Install an asynchronous certificate callback.
5313 bool cert_cb_ok = false;
5314 SSL_set_cert_cb(server_.get(),
5315 [](SSL *, void *arg) -> int {
5316 return *static_cast<bool *>(arg) ? 1 : -1;
5317 },
5318 &cert_cb_ok);
5319
5320 for (;;) {
5321 int client_ret = SSL_do_handshake(client_.get());
5322 if (client_ret != 1) {
5323 ASSERT_EQ(client_ret, -1);
5324 ASSERT_EQ(SSL_get_error(client_.get(), client_ret), SSL_ERROR_WANT_READ);
5325 ASSERT_TRUE(ProvideHandshakeData(client_.get(), 1));
5326 }
5327
5328 int server_ret = SSL_do_handshake(server_.get());
5329 if (server_ret != 1) {
5330 ASSERT_EQ(server_ret, -1);
5331 int ssl_err = SSL_get_error(server_.get(), server_ret);
5332 switch (ssl_err) {
5333 case SSL_ERROR_WANT_READ:
5334 ASSERT_TRUE(ProvideHandshakeData(server_.get(), 1));
5335 break;
5336 case SSL_ERROR_WANT_X509_LOOKUP:
5337 ASSERT_FALSE(cert_cb_ok);
5338 cert_cb_ok = true;
5339 break;
5340 default:
5341 FAIL() << "Unexpected SSL_get_error result: " << ssl_err;
5342 }
5343 }
5344
5345 if (client_ret == 1 && server_ret == 1) {
5346 break;
5347 }
5348 }
5349
David Benjamind6343572019-08-15 17:29:02 -04005350 ExpectHandshakeSuccess();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005351}
5352
5353// Test buffering write data until explicit flushes.
5354TEST_F(QUICMethodTest, Buffered) {
5355 struct BufferedFlight {
5356 std::vector<uint8_t> data[kNumQUICLevels];
5357 };
5358 static UnownedSSLExData<BufferedFlight> buffered_flights;
5359
David Benjamincc9d9352018-10-30 19:45:22 -05005360 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
5361 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005362 BufferedFlight *flight = buffered_flights.Get(ssl);
5363 flight->data[level].insert(flight->data[level].end(), data, data + len);
5364 return 1;
5365 };
5366
5367 auto flush_flight = [](SSL *ssl) -> int {
5368 BufferedFlight *flight = buffered_flights.Get(ssl);
5369 for (size_t level = 0; level < kNumQUICLevels; level++) {
5370 if (!flight->data[level].empty()) {
5371 if (!TransportFromSSL(ssl)->WriteHandshakeData(
5372 static_cast<ssl_encryption_level_t>(level),
5373 flight->data[level])) {
5374 return 0;
5375 }
5376 flight->data[level].clear();
5377 }
5378 }
5379 return 1;
5380 };
5381
5382 const SSL_QUIC_METHOD quic_method = {
5383 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05005384 add_handshake_data,
Steven Valdezc8e0f902018-07-14 11:23:01 -04005385 flush_flight,
5386 SendAlertCallback,
5387 };
5388
5389 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5390 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5391 ASSERT_TRUE(CreateClientAndServer());
5392
5393 BufferedFlight client_flight, server_flight;
5394 buffered_flights.Set(client_.get(), &client_flight);
5395 buffered_flights.Set(server_.get(), &server_flight);
5396
David Benjamind6343572019-08-15 17:29:02 -04005397 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdezc8e0f902018-07-14 11:23:01 -04005398
David Benjamind6343572019-08-15 17:29:02 -04005399 ExpectHandshakeSuccess();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005400}
5401
5402// Test that excess data at one level is rejected. That is, if a single
5403// |SSL_provide_quic_data| call included both ServerHello and
5404// EncryptedExtensions in a single chunk, BoringSSL notices and rejects this on
5405// key change.
5406TEST_F(QUICMethodTest, ExcessProvidedData) {
David Benjamincc9d9352018-10-30 19:45:22 -05005407 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
5408 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005409 // Switch everything to the initial level.
5410 return TransportFromSSL(ssl)->WriteHandshakeData(ssl_encryption_initial,
5411 MakeConstSpan(data, len));
5412 };
5413
5414 const SSL_QUIC_METHOD quic_method = {
5415 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05005416 add_handshake_data,
Steven Valdezc8e0f902018-07-14 11:23:01 -04005417 FlushFlightCallback,
5418 SendAlertCallback,
5419 };
5420
5421 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5422 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5423 ASSERT_TRUE(CreateClientAndServer());
5424
5425 // Send the ClientHello and ServerHello through Finished.
5426 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5427 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
5428 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5429 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
5430 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
5431
5432 // The client is still waiting for the ServerHello at initial
5433 // encryption.
5434 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
5435
David Benjamincc9d9352018-10-30 19:45:22 -05005436 // |add_handshake_data| incorrectly wrote everything at the initial level, so
5437 // this queues up ServerHello through Finished in one chunk.
Steven Valdezc8e0f902018-07-14 11:23:01 -04005438 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5439
5440 // The client reads ServerHello successfully, but then rejects the buffered
5441 // EncryptedExtensions on key change.
5442 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5443 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_SSL);
5444 uint32_t err = ERR_get_error();
5445 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
5446 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_BUFFERED_MESSAGES_ON_CIPHER_CHANGE);
5447
5448 // The client sends an alert in response to this.
David Benjamind6343572019-08-15 17:29:02 -04005449 ASSERT_TRUE(transport_->client()->has_alert());
5450 EXPECT_EQ(transport_->client()->alert_level(), ssl_encryption_initial);
5451 EXPECT_EQ(transport_->client()->alert(), SSL_AD_UNEXPECTED_MESSAGE);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005452
5453 // Sanity-check client did get far enough to process the ServerHello and
5454 // install keys.
David Benjamind6343572019-08-15 17:29:02 -04005455 EXPECT_TRUE(transport_->client()->HasSecrets(ssl_encryption_handshake));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005456}
5457
5458// Test that |SSL_provide_quic_data| will reject data at the wrong level.
5459TEST_F(QUICMethodTest, ProvideWrongLevel) {
5460 const SSL_QUIC_METHOD quic_method = {
5461 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05005462 AddHandshakeDataCallback,
Steven Valdezc8e0f902018-07-14 11:23:01 -04005463 FlushFlightCallback,
5464 SendAlertCallback,
5465 };
5466
5467 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5468 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5469 ASSERT_TRUE(CreateClientAndServer());
5470
5471 // Send the ClientHello and ServerHello through Finished.
5472 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5473 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
5474 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5475 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
5476 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
5477
5478 // The client is still waiting for the ServerHello at initial
5479 // encryption.
5480 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
5481
5482 // Data cannot be provided at the next level.
5483 std::vector<uint8_t> data;
5484 ASSERT_TRUE(
David Benjamind6343572019-08-15 17:29:02 -04005485 transport_->client()->ReadHandshakeData(&data, ssl_encryption_initial));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005486 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_handshake,
5487 data.data(), data.size()));
5488 ERR_clear_error();
5489
5490 // Progress to EncryptedExtensions.
5491 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
5492 data.data(), data.size()));
5493 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5494 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
5495 ASSERT_EQ(ssl_encryption_handshake, SSL_quic_read_level(client_.get()));
5496
5497 // Data cannot be provided at the previous level.
5498 ASSERT_TRUE(
David Benjamind6343572019-08-15 17:29:02 -04005499 transport_->client()->ReadHandshakeData(&data, ssl_encryption_handshake));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005500 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
5501 data.data(), data.size()));
5502}
5503
5504TEST_F(QUICMethodTest, TooMuchData) {
5505 const SSL_QUIC_METHOD quic_method = {
5506 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05005507 AddHandshakeDataCallback,
Steven Valdezc8e0f902018-07-14 11:23:01 -04005508 FlushFlightCallback,
5509 SendAlertCallback,
5510 };
5511
5512 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5513 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5514 ASSERT_TRUE(CreateClientAndServer());
5515
5516 size_t limit =
5517 SSL_quic_max_handshake_flight_len(client_.get(), ssl_encryption_initial);
5518 uint8_t b = 0;
5519 for (size_t i = 0; i < limit; i++) {
5520 ASSERT_TRUE(
5521 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
5522 }
5523
5524 EXPECT_FALSE(
5525 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
5526}
5527
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005528// Provide invalid post-handshake data.
5529TEST_F(QUICMethodTest, BadPostHandshake) {
5530 const SSL_QUIC_METHOD quic_method = {
5531 SetEncryptionSecretsCallback,
5532 AddHandshakeDataCallback,
5533 FlushFlightCallback,
5534 SendAlertCallback,
5535 };
5536
5537 g_last_session = nullptr;
5538
5539 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5540 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
5541 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5542 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5543 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04005544 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005545
5546 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
5547 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
David Benjamind6343572019-08-15 17:29:02 -04005548 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_application));
5549 EXPECT_FALSE(transport_->client()->has_alert());
5550 EXPECT_FALSE(transport_->server()->has_alert());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005551
5552 // Junk sent as part of post-handshake data should cause an error.
5553 uint8_t kJunk[] = {0x17, 0x0, 0x0, 0x4, 0xB, 0xE, 0xE, 0xF};
5554 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_application,
5555 kJunk, sizeof(kJunk)));
5556 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 0);
5557}
5558
Adam Langley7540cc22019-04-18 09:56:13 -07005559extern "C" {
5560int BORINGSSL_enum_c_type_test(void);
5561}
5562
5563TEST(SSLTest, EnumTypes) {
5564 EXPECT_EQ(sizeof(int), sizeof(ssl_private_key_result_t));
5565 EXPECT_EQ(1, BORINGSSL_enum_c_type_test());
5566}
5567
David Benjaminb29e1e12019-05-06 14:44:46 -05005568TEST_P(SSLVersionTest, DoubleSSLError) {
5569 // Connect the inner SSL connections.
5570 ASSERT_TRUE(Connect());
5571
5572 // Make a pair of |BIO|s which wrap |client_| and |server_|.
5573 UniquePtr<BIO_METHOD> bio_method(BIO_meth_new(0, nullptr));
5574 ASSERT_TRUE(bio_method);
5575 ASSERT_TRUE(BIO_meth_set_read(
5576 bio_method.get(), [](BIO *bio, char *out, int len) -> int {
5577 SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
5578 int ret = SSL_read(ssl, out, len);
5579 int ssl_ret = SSL_get_error(ssl, ret);
5580 if (ssl_ret == SSL_ERROR_WANT_READ) {
5581 BIO_set_retry_read(bio);
5582 }
5583 return ret;
5584 }));
5585 ASSERT_TRUE(BIO_meth_set_write(
5586 bio_method.get(), [](BIO *bio, const char *in, int len) -> int {
5587 SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
5588 int ret = SSL_write(ssl, in, len);
5589 int ssl_ret = SSL_get_error(ssl, ret);
5590 if (ssl_ret == SSL_ERROR_WANT_WRITE) {
5591 BIO_set_retry_write(bio);
5592 }
5593 return ret;
5594 }));
5595 ASSERT_TRUE(BIO_meth_set_ctrl(
5596 bio_method.get(), [](BIO *bio, int cmd, long larg, void *parg) -> long {
5597 // |SSL| objects require |BIO_flush| support.
5598 if (cmd == BIO_CTRL_FLUSH) {
5599 return 1;
5600 }
5601 return 0;
5602 }));
5603
5604 UniquePtr<BIO> client_bio(BIO_new(bio_method.get()));
5605 ASSERT_TRUE(client_bio);
5606 BIO_set_data(client_bio.get(), client_.get());
5607 BIO_set_init(client_bio.get(), 1);
5608
5609 UniquePtr<BIO> server_bio(BIO_new(bio_method.get()));
5610 ASSERT_TRUE(server_bio);
5611 BIO_set_data(server_bio.get(), server_.get());
5612 BIO_set_init(server_bio.get(), 1);
5613
5614 // Wrap the inner connections in another layer of SSL.
5615 UniquePtr<SSL> client_outer(SSL_new(client_ctx_.get()));
5616 ASSERT_TRUE(client_outer);
5617 SSL_set_connect_state(client_outer.get());
5618 SSL_set_bio(client_outer.get(), client_bio.get(), client_bio.get());
5619 client_bio.release(); // |SSL_set_bio| takes ownership.
5620
5621 UniquePtr<SSL> server_outer(SSL_new(server_ctx_.get()));
5622 ASSERT_TRUE(server_outer);
5623 SSL_set_accept_state(server_outer.get());
5624 SSL_set_bio(server_outer.get(), server_bio.get(), server_bio.get());
5625 server_bio.release(); // |SSL_set_bio| takes ownership.
5626
5627 // Configure |client_outer| to reject the server certificate.
5628 SSL_set_custom_verify(
5629 client_outer.get(), SSL_VERIFY_PEER,
5630 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
5631 return ssl_verify_invalid;
5632 });
5633
5634 for (;;) {
5635 int client_ret = SSL_do_handshake(client_outer.get());
5636 int client_err = SSL_get_error(client_outer.get(), client_ret);
5637 if (client_err != SSL_ERROR_WANT_READ &&
5638 client_err != SSL_ERROR_WANT_WRITE) {
5639 // The client handshake should terminate on a certificate verification
5640 // error.
5641 EXPECT_EQ(SSL_ERROR_SSL, client_err);
5642 uint32_t err = ERR_peek_error();
5643 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
5644 EXPECT_EQ(SSL_R_CERTIFICATE_VERIFY_FAILED, ERR_GET_REASON(err));
5645 break;
5646 }
5647
5648 // Run the server handshake and continue.
5649 int server_ret = SSL_do_handshake(server_outer.get());
5650 int server_err = SSL_get_error(server_outer.get(), server_ret);
5651 ASSERT_TRUE(server_err == SSL_ERROR_NONE ||
5652 server_err == SSL_ERROR_WANT_READ ||
5653 server_err == SSL_ERROR_WANT_WRITE);
5654 }
5655}
5656
David Benjamin0e7dbd52019-05-15 16:01:18 -04005657TEST(SSLTest, WriteWhileExplicitRenegotiate) {
5658 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
5659 ASSERT_TRUE(ctx);
5660
5661 bssl::UniquePtr<X509> cert = GetTestCertificate();
5662 bssl::UniquePtr<EVP_PKEY> pkey = GetTestKey();
5663 ASSERT_TRUE(cert);
5664 ASSERT_TRUE(pkey);
5665 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
5666 ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), pkey.get()));
5667 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_2_VERSION));
5668 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_2_VERSION));
5669 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
5670 ctx.get(), "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"));
5671
5672 bssl::UniquePtr<SSL> client, server;
5673 ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
5674 ClientConfig(), true /* do_handshake */,
5675 false /* don't shed handshake config */));
5676 SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_explicit);
5677
5678 static const uint8_t kInput[] = {'h', 'e', 'l', 'l', 'o'};
5679
5680 // Write "hello" until the buffer is full, so |client| has a pending write.
5681 size_t num_writes = 0;
5682 for (;;) {
5683 int ret = SSL_write(client.get(), kInput, sizeof(kInput));
5684 if (ret != int(sizeof(kInput))) {
5685 ASSERT_EQ(-1, ret);
5686 ASSERT_EQ(SSL_ERROR_WANT_WRITE, SSL_get_error(client.get(), ret));
5687 break;
5688 }
5689 num_writes++;
5690 }
5691
5692 // Encrypt a HelloRequest.
5693 uint8_t in[] = {SSL3_MT_HELLO_REQUEST, 0, 0, 0};
5694#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
5695 // Fuzzer-mode records are unencrypted.
5696 uint8_t record[5 + sizeof(in)];
5697 record[0] = SSL3_RT_HANDSHAKE;
5698 record[1] = 3;
5699 record[2] = 3; // TLS 1.2
5700 record[3] = 0;
5701 record[4] = sizeof(record) - 5;
5702 memcpy(record + 5, in, sizeof(in));
5703#else
5704 // Extract key material from |server|.
5705 static const size_t kKeyLen = 32;
5706 static const size_t kNonceLen = 12;
5707 ASSERT_EQ(2u * (kKeyLen + kNonceLen), SSL_get_key_block_len(server.get()));
5708 uint8_t key_block[2u * (kKeyLen + kNonceLen)];
5709 ASSERT_TRUE(
5710 SSL_generate_key_block(server.get(), key_block, sizeof(key_block)));
5711 Span<uint8_t> key = MakeSpan(key_block + kKeyLen, kKeyLen);
5712 Span<uint8_t> nonce =
5713 MakeSpan(key_block + kKeyLen + kKeyLen + kNonceLen, kNonceLen);
5714
5715 uint8_t ad[13];
5716 uint64_t seq = SSL_get_write_sequence(server.get());
5717 for (size_t i = 0; i < 8; i++) {
5718 // The nonce is XORed with the sequence number.
5719 nonce[11 - i] ^= uint8_t(seq);
5720 ad[7 - i] = uint8_t(seq);
5721 seq >>= 8;
5722 }
5723
5724 ad[8] = SSL3_RT_HANDSHAKE;
5725 ad[9] = 3;
5726 ad[10] = 3; // TLS 1.2
5727 ad[11] = 0;
5728 ad[12] = sizeof(in);
5729
5730 uint8_t record[5 + sizeof(in) + 16];
5731 record[0] = SSL3_RT_HANDSHAKE;
5732 record[1] = 3;
5733 record[2] = 3; // TLS 1.2
5734 record[3] = 0;
5735 record[4] = sizeof(record) - 5;
5736
5737 ScopedEVP_AEAD_CTX aead;
5738 ASSERT_TRUE(EVP_AEAD_CTX_init(aead.get(), EVP_aead_chacha20_poly1305(),
5739 key.data(), key.size(),
5740 EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr));
5741 size_t len;
5742 ASSERT_TRUE(EVP_AEAD_CTX_seal(aead.get(), record + 5, &len,
5743 sizeof(record) - 5, nonce.data(), nonce.size(),
5744 in, sizeof(in), ad, sizeof(ad)));
5745 ASSERT_EQ(sizeof(record) - 5, len);
5746#endif // BORINGSSL_UNSAFE_FUZZER_MODE
5747
5748 ASSERT_EQ(int(sizeof(record)),
5749 BIO_write(SSL_get_wbio(server.get()), record, sizeof(record)));
5750
5751 // |SSL_read| should pick up the HelloRequest.
5752 uint8_t byte;
5753 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
5754 ASSERT_EQ(SSL_ERROR_WANT_RENEGOTIATE, SSL_get_error(client.get(), -1));
5755
5756 // Drain the data from the |client|.
5757 uint8_t buf[sizeof(kInput)];
5758 for (size_t i = 0; i < num_writes; i++) {
5759 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
5760 EXPECT_EQ(Bytes(buf), Bytes(kInput));
5761 }
5762
5763 // |client| should be able to finish the pending write and continue to write,
5764 // despite the paused HelloRequest.
5765 ASSERT_EQ(int(sizeof(kInput)),
5766 SSL_write(client.get(), kInput, sizeof(kInput)));
5767 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
5768 EXPECT_EQ(Bytes(buf), Bytes(kInput));
5769
5770 ASSERT_EQ(int(sizeof(kInput)),
5771 SSL_write(client.get(), kInput, sizeof(kInput)));
5772 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
5773 EXPECT_EQ(Bytes(buf), Bytes(kInput));
5774
5775 // |SSL_read| is stuck until we acknowledge the HelloRequest.
5776 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
5777 ASSERT_EQ(SSL_ERROR_WANT_RENEGOTIATE, SSL_get_error(client.get(), -1));
5778
5779 ASSERT_TRUE(SSL_renegotiate(client.get()));
5780 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
5781 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
5782
5783 // We never renegotiate as a server.
5784 ASSERT_EQ(-1, SSL_read(server.get(), buf, sizeof(buf)));
5785 ASSERT_EQ(SSL_ERROR_SSL, SSL_get_error(server.get(), -1));
5786 uint32_t err = ERR_get_error();
5787 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
5788 EXPECT_EQ(SSL_R_NO_RENEGOTIATION, ERR_GET_REASON(err));
5789}
5790
Martin Kreichgauer72912d22017-08-04 12:06:43 -07005791} // namespace
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -07005792BSSL_NAMESPACE_END