blob: d8210dff4785c8fc9a6f45f226f1c50930380c7a [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
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004172 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_CLIENT);
4173 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langleyddb57cf2018-01-26 09:17:53 -08004174 SSL_CTX_set_handoff_mode(server_ctx.get(), 1);
4175 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
4176 ASSERT_TRUE(
4177 SSL_CTX_set_max_proto_version(handshaker_ctx.get(), TLS1_2_VERSION));
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004178 uint8_t keys[48];
4179 SSL_CTX_set_tlsext_ticket_keys(server_ctx.get(), &keys, sizeof(keys));
4180 SSL_CTX_set_tlsext_ticket_keys(handshaker_ctx.get(), &keys, sizeof(keys));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004181
4182 bssl::UniquePtr<X509> cert = GetTestCertificate();
4183 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4184 ASSERT_TRUE(cert);
4185 ASSERT_TRUE(key);
4186 ASSERT_TRUE(SSL_CTX_use_certificate(handshaker_ctx.get(), cert.get()));
4187 ASSERT_TRUE(SSL_CTX_use_PrivateKey(handshaker_ctx.get(), key.get()));
4188
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004189 for (int i = 0; i < 2; ++i) {
4190 bssl::UniquePtr<SSL> client, server;
4191 bool is_resume = i > 0;
4192 auto config = ClientConfig();
4193 if (is_resume) {
4194 ASSERT_TRUE(g_last_session);
4195 config.session = g_last_session.get();
4196 }
4197 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4198 server_ctx.get(), config,
4199 false /* don't handshake */));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004200
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004201 int client_ret = SSL_do_handshake(client.get());
4202 int client_err = SSL_get_error(client.get(), client_ret);
4203 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
Adam Langleyddb57cf2018-01-26 09:17:53 -08004204
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004205 int server_ret = SSL_do_handshake(server.get());
4206 int server_err = SSL_get_error(server.get(), server_ret);
4207 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
Adam Langleyddb57cf2018-01-26 09:17:53 -08004208
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004209 ScopedCBB cbb;
4210 Array<uint8_t> handoff;
4211 SSL_CLIENT_HELLO hello;
4212 ASSERT_TRUE(CBB_init(cbb.get(), 256));
4213 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
4214 ASSERT_TRUE(CBBFinishArray(cbb.get(), &handoff));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004215
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004216 bssl::UniquePtr<SSL> handshaker(SSL_new(handshaker_ctx.get()));
4217 ASSERT_TRUE(SSL_apply_handoff(handshaker.get(), handoff));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004218
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004219 MoveBIOs(handshaker.get(), server.get());
Adam Langleyddb57cf2018-01-26 09:17:53 -08004220
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004221 int handshake_ret = SSL_do_handshake(handshaker.get());
4222 int handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
4223 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
Adam Langleyddb57cf2018-01-26 09:17:53 -08004224
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004225 // Double-check that additional calls to |SSL_do_handshake| continue
4226 // to get |SSL_ERRROR_HANDBACK|.
4227 handshake_ret = SSL_do_handshake(handshaker.get());
4228 handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
4229 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
Adam Langleyddb57cf2018-01-26 09:17:53 -08004230
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004231 ScopedCBB cbb_handback;
4232 Array<uint8_t> handback;
4233 ASSERT_TRUE(CBB_init(cbb_handback.get(), 1024));
4234 ASSERT_TRUE(SSL_serialize_handback(handshaker.get(), cbb_handback.get()));
4235 ASSERT_TRUE(CBBFinishArray(cbb_handback.get(), &handback));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004236
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004237 bssl::UniquePtr<SSL> server2(SSL_new(server_ctx.get()));
4238 ASSERT_TRUE(SSL_apply_handback(server2.get(), handback));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004239
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004240 MoveBIOs(server2.get(), handshaker.get());
4241 ASSERT_TRUE(CompleteHandshakes(client.get(), server2.get()));
4242 EXPECT_EQ(is_resume, SSL_session_reused(client.get()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004243
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004244 uint8_t byte = 42;
4245 EXPECT_EQ(SSL_write(client.get(), &byte, 1), 1);
4246 EXPECT_EQ(SSL_read(server2.get(), &byte, 1), 1);
4247 EXPECT_EQ(42, byte);
Adam Langleyddb57cf2018-01-26 09:17:53 -08004248
Matthew Braithwaite134fb892019-11-26 17:56:11 -08004249 byte = 43;
4250 EXPECT_EQ(SSL_write(server2.get(), &byte, 1), 1);
4251 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
4252 EXPECT_EQ(43, byte);
4253 }
Adam Langleyddb57cf2018-01-26 09:17:53 -08004254}
4255
4256TEST(SSLTest, HandoffDeclined) {
4257 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4258 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4259 ASSERT_TRUE(client_ctx);
4260 ASSERT_TRUE(server_ctx);
4261
4262 SSL_CTX_set_handoff_mode(server_ctx.get(), 1);
4263 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
4264
4265 bssl::UniquePtr<X509> cert = GetTestCertificate();
4266 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4267 ASSERT_TRUE(cert);
4268 ASSERT_TRUE(key);
4269 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
4270 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
4271
4272 bssl::UniquePtr<SSL> client, server;
4273 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4274 server_ctx.get(), ClientConfig(),
4275 false /* don't handshake */));
4276
4277 int client_ret = SSL_do_handshake(client.get());
4278 int client_err = SSL_get_error(client.get(), client_ret);
4279 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4280
4281 int server_ret = SSL_do_handshake(server.get());
4282 int server_err = SSL_get_error(server.get(), server_ret);
4283 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
4284
4285 ScopedCBB cbb;
Adam Langleyc9827e02019-04-12 14:46:50 -07004286 SSL_CLIENT_HELLO hello;
Adam Langleyddb57cf2018-01-26 09:17:53 -08004287 ASSERT_TRUE(CBB_init(cbb.get(), 256));
Adam Langleyc9827e02019-04-12 14:46:50 -07004288 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004289
4290 ASSERT_TRUE(SSL_decline_handoff(server.get()));
4291
4292 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
4293
4294 uint8_t byte = 42;
4295 EXPECT_EQ(SSL_write(client.get(), &byte, 1), 1);
4296 EXPECT_EQ(SSL_read(server.get(), &byte, 1), 1);
4297 EXPECT_EQ(42, byte);
4298
4299 byte = 43;
4300 EXPECT_EQ(SSL_write(server.get(), &byte, 1), 1);
4301 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
4302 EXPECT_EQ(43, byte);
4303}
4304
Adam Langley826ce152018-08-03 10:31:21 -07004305static std::string SigAlgsToString(Span<const uint16_t> sigalgs) {
4306 std::string ret = "{";
4307
4308 for (uint16_t v : sigalgs) {
4309 if (ret.size() > 1) {
4310 ret += ", ";
4311 }
4312
4313 char buf[8];
4314 snprintf(buf, sizeof(buf) - 1, "0x%02x", v);
4315 buf[sizeof(buf)-1] = 0;
4316 ret += std::string(buf);
4317 }
4318
4319 ret += "}";
4320 return ret;
4321}
4322
4323void ExpectSigAlgsEqual(Span<const uint16_t> expected,
4324 Span<const uint16_t> actual) {
4325 bool matches = false;
4326 if (expected.size() == actual.size()) {
4327 matches = true;
4328
4329 for (size_t i = 0; i < expected.size(); i++) {
4330 if (expected[i] != actual[i]) {
4331 matches = false;
4332 break;
4333 }
4334 }
4335 }
4336
4337 if (!matches) {
4338 ADD_FAILURE() << "expected: " << SigAlgsToString(expected)
4339 << " got: " << SigAlgsToString(actual);
4340 }
4341}
4342
4343TEST(SSLTest, SigAlgs) {
4344 static const struct {
4345 std::vector<int> input;
4346 bool ok;
4347 std::vector<uint16_t> expected;
4348 } kTests[] = {
4349 {{}, true, {}},
4350 {{1}, false, {}},
4351 {{1, 2, 3}, false, {}},
4352 {{NID_sha256, EVP_PKEY_ED25519}, false, {}},
4353 {{NID_sha256, EVP_PKEY_RSA, NID_sha256, EVP_PKEY_RSA}, false, {}},
4354
4355 {{NID_sha256, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA256}},
4356 {{NID_sha512, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA512}},
4357 {{NID_sha256, EVP_PKEY_RSA_PSS}, true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4358 {{NID_undef, EVP_PKEY_ED25519}, true, {SSL_SIGN_ED25519}},
4359 {{NID_undef, EVP_PKEY_ED25519, NID_sha384, EVP_PKEY_EC},
4360 true,
4361 {SSL_SIGN_ED25519, SSL_SIGN_ECDSA_SECP384R1_SHA384}},
4362 };
4363
4364 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4365
4366 unsigned n = 1;
4367 for (const auto &test : kTests) {
4368 SCOPED_TRACE(n++);
4369
4370 const bool ok =
4371 SSL_CTX_set1_sigalgs(ctx.get(), test.input.data(), test.input.size());
4372 EXPECT_EQ(ok, test.ok);
4373
4374 if (!ok) {
4375 ERR_clear_error();
4376 }
4377
4378 if (!test.ok) {
4379 continue;
4380 }
4381
4382 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
4383 }
4384}
4385
4386TEST(SSLTest, SigAlgsList) {
4387 static const struct {
4388 const char *input;
4389 bool ok;
4390 std::vector<uint16_t> expected;
4391 } kTests[] = {
4392 {"", false, {}},
4393 {":", false, {}},
4394 {"+", false, {}},
4395 {"RSA", false, {}},
4396 {"RSA+", false, {}},
4397 {"RSA+SHA256:", false, {}},
4398 {":RSA+SHA256:", false, {}},
4399 {":RSA+SHA256+:", false, {}},
4400 {"!", false, {}},
4401 {"\x01", false, {}},
4402 {"RSA+SHA256:RSA+SHA384:RSA+SHA256", false, {}},
4403 {"RSA-PSS+SHA256:rsa_pss_rsae_sha256", false, {}},
4404
4405 {"RSA+SHA256", true, {SSL_SIGN_RSA_PKCS1_SHA256}},
4406 {"RSA+SHA256:ed25519",
4407 true,
4408 {SSL_SIGN_RSA_PKCS1_SHA256, SSL_SIGN_ED25519}},
4409 {"ECDSA+SHA256:RSA+SHA512",
4410 true,
4411 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PKCS1_SHA512}},
4412 {"ecdsa_secp256r1_sha256:rsa_pss_rsae_sha256",
4413 true,
4414 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4415 {"RSA-PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4416 {"PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4417 };
4418
4419 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4420
4421 unsigned n = 1;
4422 for (const auto &test : kTests) {
4423 SCOPED_TRACE(n++);
4424
4425 const bool ok = SSL_CTX_set1_sigalgs_list(ctx.get(), test.input);
4426 EXPECT_EQ(ok, test.ok);
4427
4428 if (!ok) {
4429 if (test.ok) {
4430 ERR_print_errors_fp(stderr);
4431 }
4432 ERR_clear_error();
4433 }
4434
4435 if (!test.ok) {
4436 continue;
4437 }
4438
4439 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
4440 }
4441}
4442
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004443TEST(SSLTest, ApplyHandoffRemovesUnsupportedCiphers) {
4444 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4445 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
4446
4447 // handoff is a handoff message that has been artificially modified to pretend
4448 // that only cipher 0x0A is supported. When it is applied to |server|, all
4449 // ciphers but that one should be removed.
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004450 //
4451 // To make a new one of these, try sticking this in the |Handoff| test above:
4452 //
4453 // hexdump(stderr, "", handoff.data(), handoff.size());
4454 // sed -e 's/\(..\)/0x\1, /g'
4455 //
4456 // and modify serialize_features() to emit only cipher 0x0A.
4457
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004458 uint8_t handoff[] = {
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004459 0x30, 0x81, 0x9a, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
4460 0x00, 0x00, 0x7e, 0x03, 0x03, 0x30, 0x8e, 0x8f, 0x79, 0xd2, 0x87, 0x39,
4461 0xc2, 0x23, 0x23, 0x13, 0xca, 0x3c, 0x80, 0x44, 0xfd, 0x80, 0x83, 0x62,
4462 0x3c, 0xcc, 0xf8, 0x76, 0xd3, 0x62, 0xbb, 0x54, 0xe3, 0xc4, 0x39, 0x24,
4463 0xa5, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004464 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
4465 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004466 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
4467 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
4468 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
4469 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
4470 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x02, 0x00,
4471 0x0a, 0x04, 0x0a, 0x00, 0x15, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00,
4472 0x1d,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004473 };
4474
4475 EXPECT_EQ(20u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
4476 ASSERT_TRUE(
4477 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
4478 EXPECT_EQ(1u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
4479}
4480
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004481TEST(SSLTest, ApplyHandoffRemovesUnsupportedCurves) {
4482 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4483 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
4484
4485 // handoff is a handoff message that has been artificially modified to pretend
4486 // that only one curve is supported. When it is applied to |server|, all
4487 // curves but that one should be removed.
4488 //
4489 // See |ApplyHandoffRemovesUnsupportedCiphers| for how to make a new one of
4490 // these.
4491 uint8_t handoff[] = {
4492 0x30, 0x81, 0xc0, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
4493 0x00, 0x00, 0x7e, 0x03, 0x03, 0x98, 0x30, 0xce, 0xd9, 0xb0, 0xdf, 0x5f,
4494 0x82, 0x05, 0x4a, 0x43, 0x67, 0x7e, 0xdb, 0x6a, 0x4f, 0x21, 0x18, 0x4e,
4495 0x0d, 0x94, 0x63, 0x18, 0x8b, 0x54, 0x89, 0xdb, 0x8b, 0x1d, 0x84, 0xbc,
4496 0x09, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
4497 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
4498 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
4499 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
4500 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
4501 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
4502 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
4503 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x30, 0x00,
4504 0x02, 0x00, 0x0a, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x8c, 0x00, 0x8d, 0x00,
4505 0x9c, 0x00, 0x9d, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xc0, 0x09, 0xc0,
4506 0x0a, 0xc0, 0x13, 0xc0, 0x14, 0xc0, 0x2b, 0xc0, 0x2c, 0xc0, 0x2f, 0xc0,
4507 0x30, 0xc0, 0x35, 0xc0, 0x36, 0xcc, 0xa8, 0xcc, 0xa9, 0xcc, 0xac, 0x04,
4508 0x02, 0x00, 0x17,
4509 };
4510
4511 // The zero length means that the default list of groups is used.
4512 EXPECT_EQ(0u, server->config->supported_group_list.size());
4513 ASSERT_TRUE(
4514 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
4515 EXPECT_EQ(1u, server->config->supported_group_list.size());
4516}
4517
Adam Langleyba9ad662018-12-17 13:59:38 -08004518TEST(SSLTest, ZeroSizedWiteFlushesHandshakeMessages) {
4519 // If there are pending handshake mesages, an |SSL_write| of zero bytes should
4520 // flush them.
4521 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4522 EXPECT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
4523 EXPECT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
4524 bssl::UniquePtr<X509> cert = GetTestCertificate();
4525 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4526 ASSERT_TRUE(cert);
4527 ASSERT_TRUE(key);
4528 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
4529 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
4530
4531 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4532 EXPECT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
4533 EXPECT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
4534
4535 bssl::UniquePtr<SSL> client, server;
4536 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4537 server_ctx.get()));
4538
4539 BIO *client_wbio = SSL_get_wbio(client.get());
4540 EXPECT_EQ(0u, BIO_wpending(client_wbio));
4541 EXPECT_TRUE(SSL_key_update(client.get(), SSL_KEY_UPDATE_NOT_REQUESTED));
4542 EXPECT_EQ(0u, BIO_wpending(client_wbio));
4543 EXPECT_EQ(0, SSL_write(client.get(), nullptr, 0));
4544 EXPECT_NE(0u, BIO_wpending(client_wbio));
4545}
4546
David Benjamin5869eb32018-07-17 00:59:45 -04004547TEST_P(SSLVersionTest, VerifyBeforeCertRequest) {
4548 // Configure the server to request client certificates.
4549 SSL_CTX_set_custom_verify(
4550 server_ctx_.get(), SSL_VERIFY_PEER,
4551 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
4552
4553 // Configure the client to reject the server certificate.
4554 SSL_CTX_set_custom_verify(
4555 client_ctx_.get(), SSL_VERIFY_PEER,
4556 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_invalid; });
4557
4558 // cert_cb should not be called. Verification should fail first.
4559 SSL_CTX_set_cert_cb(client_ctx_.get(),
4560 [](SSL *ssl, void *arg) {
4561 ADD_FAILURE() << "cert_cb unexpectedly called";
4562 return 0;
4563 },
4564 nullptr);
4565
4566 bssl::UniquePtr<SSL> client, server;
4567 EXPECT_FALSE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
4568 server_ctx_.get()));
4569}
4570
David Benjamin492c9aa2018-08-31 16:35:22 -05004571// Test that ticket-based sessions on the client get fake session IDs.
4572TEST_P(SSLVersionTest, FakeIDsForTickets) {
4573 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4574 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4575
4576 bssl::UniquePtr<SSL_SESSION> session =
4577 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4578 ASSERT_TRUE(session);
4579
4580 EXPECT_TRUE(SSL_SESSION_has_ticket(session.get()));
4581 unsigned session_id_length;
4582 SSL_SESSION_get_id(session.get(), &session_id_length);
4583 EXPECT_NE(session_id_length, 0u);
4584}
4585
David Benjamin6c04bd12018-07-19 18:13:09 -04004586// These tests test multi-threaded behavior. They are intended to run with
4587// ThreadSanitizer.
David Benjamin5b33eff2018-09-22 16:52:48 -07004588#if defined(OPENSSL_THREADS)
David Benjamin6c04bd12018-07-19 18:13:09 -04004589TEST_P(SSLVersionTest, SessionCacheThreads) {
4590 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
4591 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4592 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4593
4594 if (version() == TLS1_3_VERSION) {
4595 // Our TLS 1.3 implementation does not support stateful resumption.
4596 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
4597 return;
4598 }
4599
4600 // Establish two client sessions to test with.
4601 bssl::UniquePtr<SSL_SESSION> session1 =
4602 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4603 ASSERT_TRUE(session1);
4604 bssl::UniquePtr<SSL_SESSION> session2 =
4605 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4606 ASSERT_TRUE(session2);
4607
4608 auto connect_with_session = [&](SSL_SESSION *session) {
4609 ClientConfig config;
4610 config.session = session;
4611 UniquePtr<SSL> client, server;
4612 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
4613 server_ctx_.get(), config));
4614 };
4615
4616 // Resume sessions in parallel with establishing new ones.
4617 {
4618 std::vector<std::thread> threads;
4619 threads.emplace_back([&] { connect_with_session(nullptr); });
4620 threads.emplace_back([&] { connect_with_session(nullptr); });
4621 threads.emplace_back([&] { connect_with_session(session1.get()); });
4622 threads.emplace_back([&] { connect_with_session(session1.get()); });
4623 threads.emplace_back([&] { connect_with_session(session2.get()); });
4624 threads.emplace_back([&] { connect_with_session(session2.get()); });
4625 for (auto &thread : threads) {
4626 thread.join();
4627 }
4628 }
4629
4630 // Hit the maximum session cache size across multiple threads
4631 size_t limit = SSL_CTX_sess_number(server_ctx_.get()) + 2;
4632 SSL_CTX_sess_set_cache_size(server_ctx_.get(), limit);
4633 {
4634 std::vector<std::thread> threads;
4635 for (int i = 0; i < 4; i++) {
4636 threads.emplace_back([&]() {
4637 connect_with_session(nullptr);
4638 EXPECT_LE(SSL_CTX_sess_number(server_ctx_.get()), limit);
4639 });
4640 }
4641 for (auto &thread : threads) {
4642 thread.join();
4643 }
4644 EXPECT_EQ(SSL_CTX_sess_number(server_ctx_.get()), limit);
4645 }
4646}
4647
4648TEST_P(SSLVersionTest, SessionTicketThreads) {
4649 for (bool renew_ticket : {false, true}) {
4650 SCOPED_TRACE(renew_ticket);
4651 ResetContexts();
4652 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4653 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4654 if (renew_ticket) {
4655 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
4656 }
4657
4658 // Establish two client sessions to test with.
4659 bssl::UniquePtr<SSL_SESSION> session1 =
4660 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4661 ASSERT_TRUE(session1);
4662 bssl::UniquePtr<SSL_SESSION> session2 =
4663 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4664 ASSERT_TRUE(session2);
4665
4666 auto connect_with_session = [&](SSL_SESSION *session) {
4667 ClientConfig config;
4668 config.session = session;
4669 UniquePtr<SSL> client, server;
4670 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
4671 server_ctx_.get(), config));
4672 };
4673
4674 // Resume sessions in parallel with establishing new ones.
4675 {
4676 std::vector<std::thread> threads;
4677 threads.emplace_back([&] { connect_with_session(nullptr); });
4678 threads.emplace_back([&] { connect_with_session(nullptr); });
4679 threads.emplace_back([&] { connect_with_session(session1.get()); });
4680 threads.emplace_back([&] { connect_with_session(session1.get()); });
4681 threads.emplace_back([&] { connect_with_session(session2.get()); });
4682 threads.emplace_back([&] { connect_with_session(session2.get()); });
4683 for (auto &thread : threads) {
4684 thread.join();
4685 }
4686 }
4687 }
4688}
4689
4690// SSL_CTX_get0_certificate needs to lock internally. Test this works.
4691TEST(SSLTest, GetCertificateThreads) {
4692 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4693 ASSERT_TRUE(ctx);
4694 bssl::UniquePtr<X509> cert = GetTestCertificate();
4695 ASSERT_TRUE(cert);
4696 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
4697
4698 // Existing code expects |SSL_CTX_get0_certificate| to be callable from two
4699 // threads concurrently. It originally was an immutable operation. Now we
4700 // implement it with a thread-safe cache, so it is worth testing.
4701 X509 *cert2_thread;
4702 std::thread thread(
4703 [&] { cert2_thread = SSL_CTX_get0_certificate(ctx.get()); });
4704 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
4705 thread.join();
4706
4707 EXPECT_EQ(cert2, cert2_thread);
4708 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
4709}
David Benjamin4cce9552018-12-13 12:20:54 -06004710
4711// Functions which access properties on the negotiated session are thread-safe
4712// where needed. Prior to TLS 1.3, clients resuming sessions and servers
4713// performing stateful resumption will share an underlying SSL_SESSION object,
4714// potentially across threads.
4715TEST_P(SSLVersionTest, SessionPropertiesThreads) {
4716 if (version() == TLS1_3_VERSION) {
4717 // Our TLS 1.3 implementation does not support stateful resumption.
4718 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
4719 return;
4720 }
4721
4722 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
4723 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4724 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4725
4726 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
4727 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
4728
4729 // Configure mutual authentication, so we have more session state.
4730 SSL_CTX_set_custom_verify(
4731 client_ctx_.get(), SSL_VERIFY_PEER,
4732 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
4733 SSL_CTX_set_custom_verify(
4734 server_ctx_.get(), SSL_VERIFY_PEER,
4735 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
4736
4737 // Establish a client session to test with.
4738 bssl::UniquePtr<SSL_SESSION> session =
4739 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4740 ASSERT_TRUE(session);
4741
4742 // Resume with it twice.
4743 UniquePtr<SSL> ssls[4];
4744 ClientConfig config;
4745 config.session = session.get();
4746 ASSERT_TRUE(ConnectClientAndServer(&ssls[0], &ssls[1], client_ctx_.get(),
4747 server_ctx_.get(), config));
4748 ASSERT_TRUE(ConnectClientAndServer(&ssls[2], &ssls[3], client_ctx_.get(),
4749 server_ctx_.get(), config));
4750
4751 // Read properties in parallel.
4752 auto read_properties = [](const SSL *ssl) {
4753 EXPECT_TRUE(SSL_get_peer_cert_chain(ssl));
4754 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(ssl));
4755 EXPECT_TRUE(peer);
4756 EXPECT_TRUE(SSL_get_current_cipher(ssl));
4757 EXPECT_TRUE(SSL_get_curve_id(ssl));
4758 };
4759
4760 std::vector<std::thread> threads;
4761 for (const auto &ssl_ptr : ssls) {
4762 const SSL *ssl = ssl_ptr.get();
4763 threads.emplace_back([=] { read_properties(ssl); });
4764 }
4765 for (auto &thread : threads) {
4766 thread.join();
4767 }
4768}
David Benjamina486c6c2019-03-28 18:32:38 -05004769#endif // OPENSSL_THREADS
David Benjamin6c04bd12018-07-19 18:13:09 -04004770
Steven Valdezc8e0f902018-07-14 11:23:01 -04004771constexpr size_t kNumQUICLevels = 4;
4772static_assert(ssl_encryption_initial < kNumQUICLevels,
4773 "kNumQUICLevels is wrong");
4774static_assert(ssl_encryption_early_data < kNumQUICLevels,
4775 "kNumQUICLevels is wrong");
4776static_assert(ssl_encryption_handshake < kNumQUICLevels,
4777 "kNumQUICLevels is wrong");
4778static_assert(ssl_encryption_application < kNumQUICLevels,
4779 "kNumQUICLevels is wrong");
4780
4781class MockQUICTransport {
4782 public:
David Benjamind6343572019-08-15 17:29:02 -04004783 enum class Role { kClient, kServer };
4784
4785 explicit MockQUICTransport(Role role) : role_(role) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04004786 // The caller is expected to configure initial secrets.
4787 levels_[ssl_encryption_initial].write_secret = {1};
4788 levels_[ssl_encryption_initial].read_secret = {1};
4789 }
4790
4791 void set_peer(MockQUICTransport *peer) { peer_ = peer; }
4792
4793 bool has_alert() const { return has_alert_; }
4794 ssl_encryption_level_t alert_level() const { return alert_level_; }
4795 uint8_t alert() const { return alert_; }
4796
4797 bool PeerSecretsMatch(ssl_encryption_level_t level) const {
4798 return levels_[level].write_secret == peer_->levels_[level].read_secret &&
Steven Valdez384d0ea2018-11-06 10:45:36 -05004799 levels_[level].read_secret == peer_->levels_[level].write_secret &&
4800 levels_[level].cipher == peer_->levels_[level].cipher;
Steven Valdezc8e0f902018-07-14 11:23:01 -04004801 }
4802
4803 bool HasSecrets(ssl_encryption_level_t level) const {
4804 return !levels_[level].write_secret.empty() ||
4805 !levels_[level].read_secret.empty();
4806 }
4807
4808 bool SetEncryptionSecrets(ssl_encryption_level_t level,
4809 const uint8_t *read_secret,
Steven Valdez384d0ea2018-11-06 10:45:36 -05004810 const uint8_t *write_secret, size_t secret_len,
4811 const SSL_CIPHER *cipher) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04004812 if (HasSecrets(level)) {
4813 ADD_FAILURE() << "duplicate keys configured";
4814 return false;
4815 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05004816
4817 if (cipher == nullptr) {
4818 ADD_FAILURE() << "current cipher unavailable";
4819 return false;
4820 }
4821
David Benjamind6343572019-08-15 17:29:02 -04004822 bool expect_read_secret = true, expect_write_secret = true;
4823 if (level == ssl_encryption_early_data) {
4824 if (role_ == Role::kClient) {
4825 expect_read_secret = false;
4826 } else {
4827 expect_write_secret = false;
David Benjaminfd320892019-11-19 14:00:36 +08004828 if (!HasSecrets(ssl_encryption_application)) {
4829 ADD_FAILURE() << "early secrets installed without keys to ACK them";
4830 return false;
4831 }
David Benjamind6343572019-08-15 17:29:02 -04004832 }
4833 }
4834
4835 if (expect_read_secret) {
4836 if (read_secret == nullptr) {
4837 ADD_FAILURE() << "read secret was unexpectedly null";
4838 return false;
4839 }
4840 levels_[level].read_secret.assign(read_secret, read_secret + secret_len);
4841 } else if (read_secret != nullptr) {
4842 ADD_FAILURE() << "unexpected read secret";
Steven Valdezc8e0f902018-07-14 11:23:01 -04004843 return false;
4844 }
David Benjamind6343572019-08-15 17:29:02 -04004845
4846 if (expect_write_secret) {
4847 if (write_secret == nullptr) {
4848 ADD_FAILURE() << "write secret was unexpectedly null";
4849 return false;
4850 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04004851 levels_[level].write_secret.assign(write_secret,
4852 write_secret + secret_len);
David Benjamind6343572019-08-15 17:29:02 -04004853 } else if (write_secret != nullptr) {
4854 ADD_FAILURE() << "unexpected write secret";
4855 return false;
Steven Valdezc8e0f902018-07-14 11:23:01 -04004856 }
David Benjamind6343572019-08-15 17:29:02 -04004857
Steven Valdez384d0ea2018-11-06 10:45:36 -05004858 levels_[level].cipher = SSL_CIPHER_get_id(cipher);
Steven Valdezc8e0f902018-07-14 11:23:01 -04004859 return true;
4860 }
4861
4862 bool WriteHandshakeData(ssl_encryption_level_t level,
4863 Span<const uint8_t> data) {
4864 if (levels_[level].write_secret.empty()) {
4865 ADD_FAILURE() << "data written before keys configured";
4866 return false;
4867 }
4868 levels_[level].write_data.insert(levels_[level].write_data.end(),
4869 data.begin(), data.end());
4870 return true;
4871 }
4872
4873 bool SendAlert(ssl_encryption_level_t level, uint8_t alert_value) {
4874 if (has_alert_) {
4875 ADD_FAILURE() << "duplicate alert sent";
4876 return false;
4877 }
4878
4879 if (levels_[level].write_secret.empty()) {
4880 ADD_FAILURE() << "alert sent before keys configured";
4881 return false;
4882 }
4883
4884 has_alert_ = true;
4885 alert_level_ = level;
4886 alert_ = alert_value;
4887 return true;
4888 }
4889
4890 bool ReadHandshakeData(std::vector<uint8_t> *out,
4891 ssl_encryption_level_t level,
4892 size_t num = std::numeric_limits<size_t>::max()) {
4893 if (levels_[level].read_secret.empty()) {
David Benjamind6343572019-08-15 17:29:02 -04004894 ADD_FAILURE() << "data read before keys configured in level " << level;
Steven Valdezc8e0f902018-07-14 11:23:01 -04004895 return false;
4896 }
4897 // The peer may not have configured any keys yet.
4898 if (peer_->levels_[level].write_secret.empty()) {
David Benjamind0b97942019-08-21 12:54:20 -04004899 out->clear();
Steven Valdezc8e0f902018-07-14 11:23:01 -04004900 return true;
4901 }
4902 // Check the peer computed the same key.
4903 if (peer_->levels_[level].write_secret != levels_[level].read_secret) {
David Benjamind6343572019-08-15 17:29:02 -04004904 ADD_FAILURE() << "peer write key does not match read key in level "
4905 << level;
Steven Valdezc8e0f902018-07-14 11:23:01 -04004906 return false;
4907 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05004908 if (peer_->levels_[level].cipher != levels_[level].cipher) {
David Benjamind6343572019-08-15 17:29:02 -04004909 ADD_FAILURE() << "peer cipher does not match in level " << level;
Steven Valdez384d0ea2018-11-06 10:45:36 -05004910 return false;
4911 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04004912 std::vector<uint8_t> *peer_data = &peer_->levels_[level].write_data;
4913 num = std::min(num, peer_data->size());
4914 out->assign(peer_data->begin(), peer_data->begin() + num);
4915 peer_data->erase(peer_data->begin(), peer_data->begin() + num);
4916 return true;
4917 }
4918
4919 private:
David Benjamind6343572019-08-15 17:29:02 -04004920 Role role_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04004921 MockQUICTransport *peer_ = nullptr;
4922
4923 bool has_alert_ = false;
4924 ssl_encryption_level_t alert_level_ = ssl_encryption_initial;
4925 uint8_t alert_ = 0;
4926
4927 struct Level {
4928 std::vector<uint8_t> write_data;
4929 std::vector<uint8_t> write_secret;
4930 std::vector<uint8_t> read_secret;
Steven Valdez384d0ea2018-11-06 10:45:36 -05004931 uint32_t cipher = 0;
Steven Valdezc8e0f902018-07-14 11:23:01 -04004932 };
4933 Level levels_[kNumQUICLevels];
4934};
4935
4936class MockQUICTransportPair {
4937 public:
David Benjamind6343572019-08-15 17:29:02 -04004938 MockQUICTransportPair()
4939 : client_(MockQUICTransport::Role::kClient),
4940 server_(MockQUICTransport::Role::kServer) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04004941 client_.set_peer(&server_);
David Benjamind6343572019-08-15 17:29:02 -04004942 server_.set_peer(&client_);
Steven Valdezc8e0f902018-07-14 11:23:01 -04004943 }
4944
4945 ~MockQUICTransportPair() {
Steven Valdezc8e0f902018-07-14 11:23:01 -04004946 client_.set_peer(nullptr);
David Benjamind6343572019-08-15 17:29:02 -04004947 server_.set_peer(nullptr);
Steven Valdezc8e0f902018-07-14 11:23:01 -04004948 }
4949
4950 MockQUICTransport *client() { return &client_; }
4951 MockQUICTransport *server() { return &server_; }
4952
4953 bool SecretsMatch(ssl_encryption_level_t level) const {
David Benjamind6343572019-08-15 17:29:02 -04004954 return client_.HasSecrets(level) && server_.HasSecrets(level) &&
4955 client_.PeerSecretsMatch(level);
Steven Valdezc8e0f902018-07-14 11:23:01 -04004956 }
4957
4958 private:
4959 MockQUICTransport client_;
4960 MockQUICTransport server_;
4961};
4962
4963class QUICMethodTest : public testing::Test {
4964 protected:
4965 void SetUp() override {
4966 client_ctx_.reset(SSL_CTX_new(TLS_method()));
4967 server_ctx_.reset(SSL_CTX_new(TLS_method()));
4968 ASSERT_TRUE(client_ctx_);
4969 ASSERT_TRUE(server_ctx_);
4970
4971 bssl::UniquePtr<X509> cert = GetTestCertificate();
4972 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4973 ASSERT_TRUE(cert);
4974 ASSERT_TRUE(key);
4975 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx_.get(), cert.get()));
4976 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx_.get(), key.get()));
4977
4978 SSL_CTX_set_min_proto_version(server_ctx_.get(), TLS1_3_VERSION);
4979 SSL_CTX_set_max_proto_version(server_ctx_.get(), TLS1_3_VERSION);
4980 SSL_CTX_set_min_proto_version(client_ctx_.get(), TLS1_3_VERSION);
4981 SSL_CTX_set_max_proto_version(client_ctx_.get(), TLS1_3_VERSION);
4982 }
4983
4984 static MockQUICTransport *TransportFromSSL(const SSL *ssl) {
4985 return ex_data_.Get(ssl);
4986 }
4987
4988 static bool ProvideHandshakeData(
4989 SSL *ssl, size_t num = std::numeric_limits<size_t>::max()) {
4990 MockQUICTransport *transport = TransportFromSSL(ssl);
4991 ssl_encryption_level_t level = SSL_quic_read_level(ssl);
4992 std::vector<uint8_t> data;
4993 return transport->ReadHandshakeData(&data, level, num) &&
4994 SSL_provide_quic_data(ssl, level, data.data(), data.size());
4995 }
4996
4997 bool CreateClientAndServer() {
4998 client_.reset(SSL_new(client_ctx_.get()));
4999 server_.reset(SSL_new(server_ctx_.get()));
5000 if (!client_ || !server_) {
5001 return false;
5002 }
5003
5004 SSL_set_connect_state(client_.get());
5005 SSL_set_accept_state(server_.get());
5006
David Benjamind6343572019-08-15 17:29:02 -04005007 transport_.reset(new MockQUICTransportPair);
5008 ex_data_.Set(client_.get(), transport_->client());
5009 ex_data_.Set(server_.get(), transport_->server());
Steven Valdezc8e0f902018-07-14 11:23:01 -04005010 return true;
5011 }
5012
David Benjamind6343572019-08-15 17:29:02 -04005013 // CompleteHandshakesForQUIC runs |SSL_do_handshake| on |client_| and
5014 // |server_| until each completes once. It returns true on success and false
5015 // on failure.
5016 bool CompleteHandshakesForQUIC() {
5017 bool client_done = false, server_done = false;
5018 while (!client_done || !server_done) {
5019 if (!client_done) {
5020 if (!ProvideHandshakeData(client_.get())) {
5021 ADD_FAILURE() << "ProvideHandshakeData(client_) failed";
5022 return false;
5023 }
5024 int client_ret = SSL_do_handshake(client_.get());
5025 if (client_ret == 1) {
5026 client_done = true;
5027 } else {
5028 EXPECT_EQ(client_ret, -1);
5029 EXPECT_EQ(SSL_get_error(client_.get(), client_ret),
5030 SSL_ERROR_WANT_READ);
5031 }
5032 }
5033
5034 if (!server_done) {
5035 if (!ProvideHandshakeData(server_.get())) {
5036 ADD_FAILURE() << "ProvideHandshakeData(server_) failed";
5037 return false;
5038 }
5039 int server_ret = SSL_do_handshake(server_.get());
5040 if (server_ret == 1) {
5041 server_done = true;
5042 } else {
5043 EXPECT_EQ(server_ret, -1);
5044 EXPECT_EQ(SSL_get_error(server_.get(), server_ret),
5045 SSL_ERROR_WANT_READ);
5046 }
5047 }
5048 }
5049 return true;
5050 }
5051
5052 bssl::UniquePtr<SSL_SESSION> CreateClientSessionForQUIC() {
5053 g_last_session = nullptr;
5054 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
5055 if (!CreateClientAndServer() ||
5056 !CompleteHandshakesForQUIC()) {
5057 return nullptr;
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005058 }
5059
David Benjamind6343572019-08-15 17:29:02 -04005060 // The server sent NewSessionTicket messages in the handshake.
5061 if (!ProvideHandshakeData(client_.get()) ||
5062 !SSL_process_quic_post_handshake(client_.get())) {
5063 return nullptr;
5064 }
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005065
David Benjamind6343572019-08-15 17:29:02 -04005066 return std::move(g_last_session);
5067 }
5068
5069 void ExpectHandshakeSuccess() {
5070 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_application));
5071 EXPECT_EQ(ssl_encryption_application, SSL_quic_read_level(client_.get()));
5072 EXPECT_EQ(ssl_encryption_application, SSL_quic_write_level(client_.get()));
5073 EXPECT_EQ(ssl_encryption_application, SSL_quic_read_level(server_.get()));
5074 EXPECT_EQ(ssl_encryption_application, SSL_quic_write_level(server_.get()));
5075 EXPECT_FALSE(transport_->client()->has_alert());
5076 EXPECT_FALSE(transport_->server()->has_alert());
5077
5078 // SSL_do_handshake is now idempotent.
5079 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
5080 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005081 }
5082
Steven Valdezc8e0f902018-07-14 11:23:01 -04005083 // The following functions may be configured on an |SSL_QUIC_METHOD| as
5084 // default implementations.
5085
5086 static int SetEncryptionSecretsCallback(SSL *ssl,
5087 ssl_encryption_level_t level,
5088 const uint8_t *read_key,
5089 const uint8_t *write_key,
5090 size_t key_len) {
Steven Valdez384d0ea2018-11-06 10:45:36 -05005091 return TransportFromSSL(ssl)->SetEncryptionSecrets(
5092 level, read_key, write_key, key_len, SSL_get_current_cipher(ssl));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005093 }
5094
David Benjamincc9d9352018-10-30 19:45:22 -05005095 static int AddHandshakeDataCallback(SSL *ssl,
5096 enum ssl_encryption_level_t level,
5097 const uint8_t *data, size_t len) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005098 EXPECT_EQ(level, SSL_quic_write_level(ssl));
5099 return TransportFromSSL(ssl)->WriteHandshakeData(level,
5100 MakeConstSpan(data, len));
5101 }
5102
5103 static int FlushFlightCallback(SSL *ssl) { return 1; }
5104
5105 static int SendAlertCallback(SSL *ssl, ssl_encryption_level_t level,
5106 uint8_t alert) {
5107 EXPECT_EQ(level, SSL_quic_write_level(ssl));
5108 return TransportFromSSL(ssl)->SendAlert(level, alert);
5109 }
5110
5111 bssl::UniquePtr<SSL_CTX> client_ctx_;
5112 bssl::UniquePtr<SSL_CTX> server_ctx_;
5113
5114 static UnownedSSLExData<MockQUICTransport> ex_data_;
David Benjamind6343572019-08-15 17:29:02 -04005115 std::unique_ptr<MockQUICTransportPair> transport_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04005116
5117 bssl::UniquePtr<SSL> client_;
5118 bssl::UniquePtr<SSL> server_;
5119};
5120
5121UnownedSSLExData<MockQUICTransport> QUICMethodTest::ex_data_;
5122
David Benjaminfd863b62019-07-25 13:51:32 -04005123// Test a full handshake and resumption work.
Steven Valdezc8e0f902018-07-14 11:23:01 -04005124TEST_F(QUICMethodTest, Basic) {
5125 const SSL_QUIC_METHOD quic_method = {
5126 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05005127 AddHandshakeDataCallback,
Steven Valdezc8e0f902018-07-14 11:23:01 -04005128 FlushFlightCallback,
5129 SendAlertCallback,
5130 };
5131
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005132 g_last_session = nullptr;
5133
5134 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5135 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005136 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5137 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
David Benjamind6343572019-08-15 17:29:02 -04005138
Steven Valdezc8e0f902018-07-14 11:23:01 -04005139 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04005140 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdezc8e0f902018-07-14 11:23:01 -04005141
David Benjamind6343572019-08-15 17:29:02 -04005142 ExpectHandshakeSuccess();
5143 EXPECT_FALSE(SSL_session_reused(client_.get()));
5144 EXPECT_FALSE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005145
5146 // The server sent NewSessionTicket messages in the handshake.
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005147 EXPECT_FALSE(g_last_session);
5148 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5149 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
5150 EXPECT_TRUE(g_last_session);
5151
5152 // Create a second connection to verify resumption works.
David Benjamind6343572019-08-15 17:29:02 -04005153 ASSERT_TRUE(CreateClientAndServer());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005154 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
5155 SSL_set_session(client_.get(), session.get());
5156
David Benjamind6343572019-08-15 17:29:02 -04005157 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005158
David Benjamind6343572019-08-15 17:29:02 -04005159 ExpectHandshakeSuccess();
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005160 EXPECT_TRUE(SSL_session_reused(client_.get()));
5161 EXPECT_TRUE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005162}
5163
David Benjaminfd863b62019-07-25 13:51:32 -04005164// Test that HelloRetryRequest in QUIC works.
5165TEST_F(QUICMethodTest, HelloRetryRequest) {
5166 const SSL_QUIC_METHOD quic_method = {
5167 SetEncryptionSecretsCallback,
5168 AddHandshakeDataCallback,
5169 FlushFlightCallback,
5170 SendAlertCallback,
5171 };
5172
5173 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5174 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5175
5176 // BoringSSL predicts the most preferred curve, so using different preferences
5177 // will trigger HelloRetryRequest.
5178 static const int kClientPrefs[] = {NID_X25519, NID_X9_62_prime256v1};
5179 ASSERT_TRUE(SSL_CTX_set1_curves(client_ctx_.get(), kClientPrefs,
5180 OPENSSL_ARRAY_SIZE(kClientPrefs)));
5181 static const int kServerPrefs[] = {NID_X9_62_prime256v1, NID_X25519};
5182 ASSERT_TRUE(SSL_CTX_set1_curves(server_ctx_.get(), kServerPrefs,
5183 OPENSSL_ARRAY_SIZE(kServerPrefs)));
5184
5185 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04005186 ASSERT_TRUE(CompleteHandshakesForQUIC());
5187 ExpectHandshakeSuccess();
5188}
David Benjaminfd863b62019-07-25 13:51:32 -04005189
David Benjamind6343572019-08-15 17:29:02 -04005190TEST_F(QUICMethodTest, ZeroRTTAccept) {
5191 const SSL_QUIC_METHOD quic_method = {
5192 SetEncryptionSecretsCallback,
5193 AddHandshakeDataCallback,
5194 FlushFlightCallback,
5195 SendAlertCallback,
5196 };
5197
5198 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5199 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
5200 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
5201 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5202 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5203
5204 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
5205 ASSERT_TRUE(session);
5206
5207 ASSERT_TRUE(CreateClientAndServer());
5208 SSL_set_session(client_.get(), session.get());
5209
5210 // The client handshake should return immediately into the early data state.
5211 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
5212 EXPECT_TRUE(SSL_in_early_data(client_.get()));
5213 // The transport should have keys for sending 0-RTT data.
5214 EXPECT_TRUE(
5215 transport_->client()->HasSecrets(ssl_encryption_early_data));
5216
5217 // The server will consume the ClientHello and also enter the early data
5218 // state.
5219 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5220 ASSERT_EQ(SSL_do_handshake(server_.get()), 1);
5221 EXPECT_TRUE(SSL_in_early_data(server_.get()));
5222 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_early_data));
5223 // The transport should have keys for sending half-RTT data.
5224 EXPECT_TRUE(
5225 transport_->server()->HasSecrets(ssl_encryption_application));
5226
5227 // Finish up the client and server handshakes.
5228 ASSERT_TRUE(CompleteHandshakesForQUIC());
5229
5230 // Both sides can now exchange 1-RTT data.
5231 ExpectHandshakeSuccess();
5232 EXPECT_TRUE(SSL_session_reused(client_.get()));
5233 EXPECT_TRUE(SSL_session_reused(server_.get()));
5234 EXPECT_FALSE(SSL_in_early_data(client_.get()));
5235 EXPECT_FALSE(SSL_in_early_data(server_.get()));
5236 EXPECT_TRUE(SSL_early_data_accepted(client_.get()));
5237 EXPECT_TRUE(SSL_early_data_accepted(server_.get()));
5238}
5239
5240TEST_F(QUICMethodTest, ZeroRTTReject) {
5241 const SSL_QUIC_METHOD quic_method = {
5242 SetEncryptionSecretsCallback,
5243 AddHandshakeDataCallback,
5244 FlushFlightCallback,
5245 SendAlertCallback,
5246 };
5247
5248 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5249 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
5250 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
5251 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5252 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5253
5254 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
5255 ASSERT_TRUE(session);
5256
5257 for (bool reject_hrr : {false, true}) {
5258 SCOPED_TRACE(reject_hrr);
5259
5260 ASSERT_TRUE(CreateClientAndServer());
5261 if (reject_hrr) {
5262 // Configure the server to prefer P-256, which will reject 0-RTT via
5263 // HelloRetryRequest.
5264 int p256 = NID_X9_62_prime256v1;
5265 ASSERT_TRUE(SSL_set1_curves(server_.get(), &p256, 1));
5266 } else {
5267 // Disable 0-RTT on the server, so it will reject it.
5268 SSL_set_early_data_enabled(server_.get(), 0);
David Benjaminfd863b62019-07-25 13:51:32 -04005269 }
David Benjamind6343572019-08-15 17:29:02 -04005270 SSL_set_session(client_.get(), session.get());
David Benjaminfd863b62019-07-25 13:51:32 -04005271
David Benjamind6343572019-08-15 17:29:02 -04005272 // The client handshake should return immediately into the early data state.
5273 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
5274 EXPECT_TRUE(SSL_in_early_data(client_.get()));
5275 // The transport should have keys for sending 0-RTT data.
5276 EXPECT_TRUE(transport_->client()->HasSecrets(ssl_encryption_early_data));
5277
5278 // The server will consume the ClientHello, but it will not accept 0-RTT.
David Benjaminfd863b62019-07-25 13:51:32 -04005279 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
David Benjamind6343572019-08-15 17:29:02 -04005280 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
5281 EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
5282 EXPECT_FALSE(SSL_in_early_data(server_.get()));
5283 EXPECT_FALSE(transport_->server()->HasSecrets(ssl_encryption_early_data));
5284
5285 // The client consumes the server response and signals 0-RTT rejection.
5286 for (;;) {
5287 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5288 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
5289 int err = SSL_get_error(client_.get(), -1);
5290 if (err == SSL_ERROR_EARLY_DATA_REJECTED) {
5291 break;
5292 }
5293 ASSERT_EQ(SSL_ERROR_WANT_READ, err);
David Benjaminfd863b62019-07-25 13:51:32 -04005294 }
5295
David Benjamind6343572019-08-15 17:29:02 -04005296 // As in TLS over TCP, 0-RTT rejection is sticky.
5297 ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
5298 ASSERT_EQ(SSL_ERROR_EARLY_DATA_REJECTED, SSL_get_error(client_.get(), -1));
5299
5300 // Finish up the client and server handshakes.
5301 SSL_reset_early_data_reject(client_.get());
5302 ASSERT_TRUE(CompleteHandshakesForQUIC());
5303
5304 // Both sides can now exchange 1-RTT data.
5305 ExpectHandshakeSuccess();
5306 EXPECT_TRUE(SSL_session_reused(client_.get()));
5307 EXPECT_TRUE(SSL_session_reused(server_.get()));
5308 EXPECT_FALSE(SSL_in_early_data(client_.get()));
5309 EXPECT_FALSE(SSL_in_early_data(server_.get()));
5310 EXPECT_FALSE(SSL_early_data_accepted(client_.get()));
5311 EXPECT_FALSE(SSL_early_data_accepted(server_.get()));
David Benjaminfd863b62019-07-25 13:51:32 -04005312 }
David Benjaminfd863b62019-07-25 13:51:32 -04005313}
5314
David Benjaminee0716f2019-11-19 14:16:28 +08005315TEST_F(QUICMethodTest, NoZeroRTTKeysBeforeReverify) {
5316 const SSL_QUIC_METHOD quic_method = {
5317 SetEncryptionSecretsCallback,
5318 AddHandshakeDataCallback,
5319 FlushFlightCallback,
5320 SendAlertCallback,
5321 };
5322
5323 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5324 SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
5325 SSL_CTX_set_reverify_on_resume(client_ctx_.get(), 1);
5326 SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
5327 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5328 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5329
5330 bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
5331 ASSERT_TRUE(session);
5332
5333 ASSERT_TRUE(CreateClientAndServer());
5334 SSL_set_session(client_.get(), session.get());
5335
5336 // Configure the certificate (re)verification to never complete. The client
5337 // handshake should pause.
5338 SSL_set_custom_verify(
5339 client_.get(), SSL_VERIFY_PEER,
5340 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
5341 return ssl_verify_retry;
5342 });
5343 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5344 ASSERT_EQ(SSL_get_error(client_.get(), -1),
5345 SSL_ERROR_WANT_CERTIFICATE_VERIFY);
5346
5347 // The early data keys have not yet been released.
5348 EXPECT_FALSE(transport_->client()->HasSecrets(ssl_encryption_early_data));
5349
5350 // After the verification completes, the handshake progresses to the 0-RTT
5351 // point and releases keys.
5352 SSL_set_custom_verify(
5353 client_.get(), SSL_VERIFY_PEER,
5354 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
5355 return ssl_verify_ok;
5356 });
5357 ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
5358 EXPECT_TRUE(SSL_in_early_data(client_.get()));
5359 EXPECT_TRUE(transport_->client()->HasSecrets(ssl_encryption_early_data));
5360}
5361
Steven Valdezc8e0f902018-07-14 11:23:01 -04005362// Test only releasing data to QUIC one byte at a time on request, to maximize
5363// state machine pauses. Additionally, test that existing asynchronous callbacks
5364// still work.
5365TEST_F(QUICMethodTest, Async) {
5366 const SSL_QUIC_METHOD quic_method = {
5367 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05005368 AddHandshakeDataCallback,
Steven Valdezc8e0f902018-07-14 11:23:01 -04005369 FlushFlightCallback,
5370 SendAlertCallback,
5371 };
5372
5373 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5374 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5375 ASSERT_TRUE(CreateClientAndServer());
5376
5377 // Install an asynchronous certificate callback.
5378 bool cert_cb_ok = false;
5379 SSL_set_cert_cb(server_.get(),
5380 [](SSL *, void *arg) -> int {
5381 return *static_cast<bool *>(arg) ? 1 : -1;
5382 },
5383 &cert_cb_ok);
5384
5385 for (;;) {
5386 int client_ret = SSL_do_handshake(client_.get());
5387 if (client_ret != 1) {
5388 ASSERT_EQ(client_ret, -1);
5389 ASSERT_EQ(SSL_get_error(client_.get(), client_ret), SSL_ERROR_WANT_READ);
5390 ASSERT_TRUE(ProvideHandshakeData(client_.get(), 1));
5391 }
5392
5393 int server_ret = SSL_do_handshake(server_.get());
5394 if (server_ret != 1) {
5395 ASSERT_EQ(server_ret, -1);
5396 int ssl_err = SSL_get_error(server_.get(), server_ret);
5397 switch (ssl_err) {
5398 case SSL_ERROR_WANT_READ:
5399 ASSERT_TRUE(ProvideHandshakeData(server_.get(), 1));
5400 break;
5401 case SSL_ERROR_WANT_X509_LOOKUP:
5402 ASSERT_FALSE(cert_cb_ok);
5403 cert_cb_ok = true;
5404 break;
5405 default:
5406 FAIL() << "Unexpected SSL_get_error result: " << ssl_err;
5407 }
5408 }
5409
5410 if (client_ret == 1 && server_ret == 1) {
5411 break;
5412 }
5413 }
5414
David Benjamind6343572019-08-15 17:29:02 -04005415 ExpectHandshakeSuccess();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005416}
5417
5418// Test buffering write data until explicit flushes.
5419TEST_F(QUICMethodTest, Buffered) {
5420 struct BufferedFlight {
5421 std::vector<uint8_t> data[kNumQUICLevels];
5422 };
5423 static UnownedSSLExData<BufferedFlight> buffered_flights;
5424
David Benjamincc9d9352018-10-30 19:45:22 -05005425 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
5426 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005427 BufferedFlight *flight = buffered_flights.Get(ssl);
5428 flight->data[level].insert(flight->data[level].end(), data, data + len);
5429 return 1;
5430 };
5431
5432 auto flush_flight = [](SSL *ssl) -> int {
5433 BufferedFlight *flight = buffered_flights.Get(ssl);
5434 for (size_t level = 0; level < kNumQUICLevels; level++) {
5435 if (!flight->data[level].empty()) {
5436 if (!TransportFromSSL(ssl)->WriteHandshakeData(
5437 static_cast<ssl_encryption_level_t>(level),
5438 flight->data[level])) {
5439 return 0;
5440 }
5441 flight->data[level].clear();
5442 }
5443 }
5444 return 1;
5445 };
5446
5447 const SSL_QUIC_METHOD quic_method = {
5448 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05005449 add_handshake_data,
Steven Valdezc8e0f902018-07-14 11:23:01 -04005450 flush_flight,
5451 SendAlertCallback,
5452 };
5453
5454 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5455 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5456 ASSERT_TRUE(CreateClientAndServer());
5457
5458 BufferedFlight client_flight, server_flight;
5459 buffered_flights.Set(client_.get(), &client_flight);
5460 buffered_flights.Set(server_.get(), &server_flight);
5461
David Benjamind6343572019-08-15 17:29:02 -04005462 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdezc8e0f902018-07-14 11:23:01 -04005463
David Benjamind6343572019-08-15 17:29:02 -04005464 ExpectHandshakeSuccess();
Steven Valdezc8e0f902018-07-14 11:23:01 -04005465}
5466
5467// Test that excess data at one level is rejected. That is, if a single
5468// |SSL_provide_quic_data| call included both ServerHello and
5469// EncryptedExtensions in a single chunk, BoringSSL notices and rejects this on
5470// key change.
5471TEST_F(QUICMethodTest, ExcessProvidedData) {
David Benjamincc9d9352018-10-30 19:45:22 -05005472 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
5473 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005474 // Switch everything to the initial level.
5475 return TransportFromSSL(ssl)->WriteHandshakeData(ssl_encryption_initial,
5476 MakeConstSpan(data, len));
5477 };
5478
5479 const SSL_QUIC_METHOD quic_method = {
5480 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05005481 add_handshake_data,
Steven Valdezc8e0f902018-07-14 11:23:01 -04005482 FlushFlightCallback,
5483 SendAlertCallback,
5484 };
5485
5486 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5487 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5488 ASSERT_TRUE(CreateClientAndServer());
5489
5490 // Send the ClientHello and ServerHello through Finished.
5491 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5492 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
5493 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5494 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
5495 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
5496
5497 // The client is still waiting for the ServerHello at initial
5498 // encryption.
5499 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
5500
David Benjamincc9d9352018-10-30 19:45:22 -05005501 // |add_handshake_data| incorrectly wrote everything at the initial level, so
5502 // this queues up ServerHello through Finished in one chunk.
Steven Valdezc8e0f902018-07-14 11:23:01 -04005503 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5504
5505 // The client reads ServerHello successfully, but then rejects the buffered
5506 // EncryptedExtensions on key change.
5507 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5508 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_SSL);
5509 uint32_t err = ERR_get_error();
5510 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
5511 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_BUFFERED_MESSAGES_ON_CIPHER_CHANGE);
5512
5513 // The client sends an alert in response to this.
David Benjamind6343572019-08-15 17:29:02 -04005514 ASSERT_TRUE(transport_->client()->has_alert());
5515 EXPECT_EQ(transport_->client()->alert_level(), ssl_encryption_initial);
5516 EXPECT_EQ(transport_->client()->alert(), SSL_AD_UNEXPECTED_MESSAGE);
Steven Valdezc8e0f902018-07-14 11:23:01 -04005517
5518 // Sanity-check client did get far enough to process the ServerHello and
5519 // install keys.
David Benjamind6343572019-08-15 17:29:02 -04005520 EXPECT_TRUE(transport_->client()->HasSecrets(ssl_encryption_handshake));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005521}
5522
5523// Test that |SSL_provide_quic_data| will reject data at the wrong level.
5524TEST_F(QUICMethodTest, ProvideWrongLevel) {
5525 const SSL_QUIC_METHOD quic_method = {
5526 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05005527 AddHandshakeDataCallback,
Steven Valdezc8e0f902018-07-14 11:23:01 -04005528 FlushFlightCallback,
5529 SendAlertCallback,
5530 };
5531
5532 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5533 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5534 ASSERT_TRUE(CreateClientAndServer());
5535
5536 // Send the ClientHello and ServerHello through Finished.
5537 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5538 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
5539 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5540 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
5541 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
5542
5543 // The client is still waiting for the ServerHello at initial
5544 // encryption.
5545 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
5546
5547 // Data cannot be provided at the next level.
5548 std::vector<uint8_t> data;
5549 ASSERT_TRUE(
David Benjamind6343572019-08-15 17:29:02 -04005550 transport_->client()->ReadHandshakeData(&data, ssl_encryption_initial));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005551 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_handshake,
5552 data.data(), data.size()));
5553 ERR_clear_error();
5554
5555 // Progress to EncryptedExtensions.
5556 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
5557 data.data(), data.size()));
5558 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5559 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
5560 ASSERT_EQ(ssl_encryption_handshake, SSL_quic_read_level(client_.get()));
5561
5562 // Data cannot be provided at the previous level.
5563 ASSERT_TRUE(
David Benjamind6343572019-08-15 17:29:02 -04005564 transport_->client()->ReadHandshakeData(&data, ssl_encryption_handshake));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005565 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
5566 data.data(), data.size()));
5567}
5568
5569TEST_F(QUICMethodTest, TooMuchData) {
5570 const SSL_QUIC_METHOD quic_method = {
5571 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05005572 AddHandshakeDataCallback,
Steven Valdezc8e0f902018-07-14 11:23:01 -04005573 FlushFlightCallback,
5574 SendAlertCallback,
5575 };
5576
5577 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5578 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5579 ASSERT_TRUE(CreateClientAndServer());
5580
5581 size_t limit =
5582 SSL_quic_max_handshake_flight_len(client_.get(), ssl_encryption_initial);
5583 uint8_t b = 0;
5584 for (size_t i = 0; i < limit; i++) {
5585 ASSERT_TRUE(
5586 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
5587 }
5588
5589 EXPECT_FALSE(
5590 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
5591}
5592
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005593// Provide invalid post-handshake data.
5594TEST_F(QUICMethodTest, BadPostHandshake) {
5595 const SSL_QUIC_METHOD quic_method = {
5596 SetEncryptionSecretsCallback,
5597 AddHandshakeDataCallback,
5598 FlushFlightCallback,
5599 SendAlertCallback,
5600 };
5601
5602 g_last_session = nullptr;
5603
5604 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5605 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
5606 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5607 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5608 ASSERT_TRUE(CreateClientAndServer());
David Benjamind6343572019-08-15 17:29:02 -04005609 ASSERT_TRUE(CompleteHandshakesForQUIC());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005610
5611 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
5612 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
David Benjamind6343572019-08-15 17:29:02 -04005613 EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_application));
5614 EXPECT_FALSE(transport_->client()->has_alert());
5615 EXPECT_FALSE(transport_->server()->has_alert());
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005616
5617 // Junk sent as part of post-handshake data should cause an error.
5618 uint8_t kJunk[] = {0x17, 0x0, 0x0, 0x4, 0xB, 0xE, 0xE, 0xF};
5619 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_application,
5620 kJunk, sizeof(kJunk)));
5621 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 0);
5622}
5623
Adam Langley7540cc22019-04-18 09:56:13 -07005624extern "C" {
5625int BORINGSSL_enum_c_type_test(void);
5626}
5627
5628TEST(SSLTest, EnumTypes) {
5629 EXPECT_EQ(sizeof(int), sizeof(ssl_private_key_result_t));
5630 EXPECT_EQ(1, BORINGSSL_enum_c_type_test());
5631}
5632
David Benjaminb29e1e12019-05-06 14:44:46 -05005633TEST_P(SSLVersionTest, DoubleSSLError) {
5634 // Connect the inner SSL connections.
5635 ASSERT_TRUE(Connect());
5636
5637 // Make a pair of |BIO|s which wrap |client_| and |server_|.
5638 UniquePtr<BIO_METHOD> bio_method(BIO_meth_new(0, nullptr));
5639 ASSERT_TRUE(bio_method);
5640 ASSERT_TRUE(BIO_meth_set_read(
5641 bio_method.get(), [](BIO *bio, char *out, int len) -> int {
5642 SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
5643 int ret = SSL_read(ssl, out, len);
5644 int ssl_ret = SSL_get_error(ssl, ret);
5645 if (ssl_ret == SSL_ERROR_WANT_READ) {
5646 BIO_set_retry_read(bio);
5647 }
5648 return ret;
5649 }));
5650 ASSERT_TRUE(BIO_meth_set_write(
5651 bio_method.get(), [](BIO *bio, const char *in, int len) -> int {
5652 SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
5653 int ret = SSL_write(ssl, in, len);
5654 int ssl_ret = SSL_get_error(ssl, ret);
5655 if (ssl_ret == SSL_ERROR_WANT_WRITE) {
5656 BIO_set_retry_write(bio);
5657 }
5658 return ret;
5659 }));
5660 ASSERT_TRUE(BIO_meth_set_ctrl(
5661 bio_method.get(), [](BIO *bio, int cmd, long larg, void *parg) -> long {
5662 // |SSL| objects require |BIO_flush| support.
5663 if (cmd == BIO_CTRL_FLUSH) {
5664 return 1;
5665 }
5666 return 0;
5667 }));
5668
5669 UniquePtr<BIO> client_bio(BIO_new(bio_method.get()));
5670 ASSERT_TRUE(client_bio);
5671 BIO_set_data(client_bio.get(), client_.get());
5672 BIO_set_init(client_bio.get(), 1);
5673
5674 UniquePtr<BIO> server_bio(BIO_new(bio_method.get()));
5675 ASSERT_TRUE(server_bio);
5676 BIO_set_data(server_bio.get(), server_.get());
5677 BIO_set_init(server_bio.get(), 1);
5678
5679 // Wrap the inner connections in another layer of SSL.
5680 UniquePtr<SSL> client_outer(SSL_new(client_ctx_.get()));
5681 ASSERT_TRUE(client_outer);
5682 SSL_set_connect_state(client_outer.get());
5683 SSL_set_bio(client_outer.get(), client_bio.get(), client_bio.get());
5684 client_bio.release(); // |SSL_set_bio| takes ownership.
5685
5686 UniquePtr<SSL> server_outer(SSL_new(server_ctx_.get()));
5687 ASSERT_TRUE(server_outer);
5688 SSL_set_accept_state(server_outer.get());
5689 SSL_set_bio(server_outer.get(), server_bio.get(), server_bio.get());
5690 server_bio.release(); // |SSL_set_bio| takes ownership.
5691
5692 // Configure |client_outer| to reject the server certificate.
5693 SSL_set_custom_verify(
5694 client_outer.get(), SSL_VERIFY_PEER,
5695 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
5696 return ssl_verify_invalid;
5697 });
5698
5699 for (;;) {
5700 int client_ret = SSL_do_handshake(client_outer.get());
5701 int client_err = SSL_get_error(client_outer.get(), client_ret);
5702 if (client_err != SSL_ERROR_WANT_READ &&
5703 client_err != SSL_ERROR_WANT_WRITE) {
5704 // The client handshake should terminate on a certificate verification
5705 // error.
5706 EXPECT_EQ(SSL_ERROR_SSL, client_err);
5707 uint32_t err = ERR_peek_error();
5708 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
5709 EXPECT_EQ(SSL_R_CERTIFICATE_VERIFY_FAILED, ERR_GET_REASON(err));
5710 break;
5711 }
5712
5713 // Run the server handshake and continue.
5714 int server_ret = SSL_do_handshake(server_outer.get());
5715 int server_err = SSL_get_error(server_outer.get(), server_ret);
5716 ASSERT_TRUE(server_err == SSL_ERROR_NONE ||
5717 server_err == SSL_ERROR_WANT_READ ||
5718 server_err == SSL_ERROR_WANT_WRITE);
5719 }
5720}
5721
David Benjamin0e7dbd52019-05-15 16:01:18 -04005722TEST(SSLTest, WriteWhileExplicitRenegotiate) {
5723 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
5724 ASSERT_TRUE(ctx);
5725
5726 bssl::UniquePtr<X509> cert = GetTestCertificate();
5727 bssl::UniquePtr<EVP_PKEY> pkey = GetTestKey();
5728 ASSERT_TRUE(cert);
5729 ASSERT_TRUE(pkey);
5730 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
5731 ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), pkey.get()));
5732 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_2_VERSION));
5733 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_2_VERSION));
5734 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
5735 ctx.get(), "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"));
5736
5737 bssl::UniquePtr<SSL> client, server;
5738 ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
5739 ClientConfig(), true /* do_handshake */,
5740 false /* don't shed handshake config */));
5741 SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_explicit);
5742
5743 static const uint8_t kInput[] = {'h', 'e', 'l', 'l', 'o'};
5744
5745 // Write "hello" until the buffer is full, so |client| has a pending write.
5746 size_t num_writes = 0;
5747 for (;;) {
5748 int ret = SSL_write(client.get(), kInput, sizeof(kInput));
5749 if (ret != int(sizeof(kInput))) {
5750 ASSERT_EQ(-1, ret);
5751 ASSERT_EQ(SSL_ERROR_WANT_WRITE, SSL_get_error(client.get(), ret));
5752 break;
5753 }
5754 num_writes++;
5755 }
5756
5757 // Encrypt a HelloRequest.
5758 uint8_t in[] = {SSL3_MT_HELLO_REQUEST, 0, 0, 0};
5759#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
5760 // Fuzzer-mode records are unencrypted.
5761 uint8_t record[5 + sizeof(in)];
5762 record[0] = SSL3_RT_HANDSHAKE;
5763 record[1] = 3;
5764 record[2] = 3; // TLS 1.2
5765 record[3] = 0;
5766 record[4] = sizeof(record) - 5;
5767 memcpy(record + 5, in, sizeof(in));
5768#else
5769 // Extract key material from |server|.
5770 static const size_t kKeyLen = 32;
5771 static const size_t kNonceLen = 12;
5772 ASSERT_EQ(2u * (kKeyLen + kNonceLen), SSL_get_key_block_len(server.get()));
5773 uint8_t key_block[2u * (kKeyLen + kNonceLen)];
5774 ASSERT_TRUE(
5775 SSL_generate_key_block(server.get(), key_block, sizeof(key_block)));
5776 Span<uint8_t> key = MakeSpan(key_block + kKeyLen, kKeyLen);
5777 Span<uint8_t> nonce =
5778 MakeSpan(key_block + kKeyLen + kKeyLen + kNonceLen, kNonceLen);
5779
5780 uint8_t ad[13];
5781 uint64_t seq = SSL_get_write_sequence(server.get());
5782 for (size_t i = 0; i < 8; i++) {
5783 // The nonce is XORed with the sequence number.
5784 nonce[11 - i] ^= uint8_t(seq);
5785 ad[7 - i] = uint8_t(seq);
5786 seq >>= 8;
5787 }
5788
5789 ad[8] = SSL3_RT_HANDSHAKE;
5790 ad[9] = 3;
5791 ad[10] = 3; // TLS 1.2
5792 ad[11] = 0;
5793 ad[12] = sizeof(in);
5794
5795 uint8_t record[5 + sizeof(in) + 16];
5796 record[0] = SSL3_RT_HANDSHAKE;
5797 record[1] = 3;
5798 record[2] = 3; // TLS 1.2
5799 record[3] = 0;
5800 record[4] = sizeof(record) - 5;
5801
5802 ScopedEVP_AEAD_CTX aead;
5803 ASSERT_TRUE(EVP_AEAD_CTX_init(aead.get(), EVP_aead_chacha20_poly1305(),
5804 key.data(), key.size(),
5805 EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr));
5806 size_t len;
5807 ASSERT_TRUE(EVP_AEAD_CTX_seal(aead.get(), record + 5, &len,
5808 sizeof(record) - 5, nonce.data(), nonce.size(),
5809 in, sizeof(in), ad, sizeof(ad)));
5810 ASSERT_EQ(sizeof(record) - 5, len);
5811#endif // BORINGSSL_UNSAFE_FUZZER_MODE
5812
5813 ASSERT_EQ(int(sizeof(record)),
5814 BIO_write(SSL_get_wbio(server.get()), record, sizeof(record)));
5815
5816 // |SSL_read| should pick up the HelloRequest.
5817 uint8_t byte;
5818 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
5819 ASSERT_EQ(SSL_ERROR_WANT_RENEGOTIATE, SSL_get_error(client.get(), -1));
5820
5821 // Drain the data from the |client|.
5822 uint8_t buf[sizeof(kInput)];
5823 for (size_t i = 0; i < num_writes; i++) {
5824 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
5825 EXPECT_EQ(Bytes(buf), Bytes(kInput));
5826 }
5827
5828 // |client| should be able to finish the pending write and continue to write,
5829 // despite the paused HelloRequest.
5830 ASSERT_EQ(int(sizeof(kInput)),
5831 SSL_write(client.get(), kInput, sizeof(kInput)));
5832 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
5833 EXPECT_EQ(Bytes(buf), Bytes(kInput));
5834
5835 ASSERT_EQ(int(sizeof(kInput)),
5836 SSL_write(client.get(), kInput, sizeof(kInput)));
5837 ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
5838 EXPECT_EQ(Bytes(buf), Bytes(kInput));
5839
5840 // |SSL_read| is stuck until we acknowledge the HelloRequest.
5841 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
5842 ASSERT_EQ(SSL_ERROR_WANT_RENEGOTIATE, SSL_get_error(client.get(), -1));
5843
5844 ASSERT_TRUE(SSL_renegotiate(client.get()));
5845 ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
5846 ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
5847
5848 // We never renegotiate as a server.
5849 ASSERT_EQ(-1, SSL_read(server.get(), buf, sizeof(buf)));
5850 ASSERT_EQ(SSL_ERROR_SSL, SSL_get_error(server.get(), -1));
5851 uint32_t err = ERR_get_error();
5852 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
5853 EXPECT_EQ(SSL_R_NO_RENEGOTIATION, ERR_GET_REASON(err));
5854}
5855
Martin Kreichgauer72912d22017-08-04 12:06:43 -07005856} // namespace
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -07005857BSSL_NAMESPACE_END