blob: f3f792347fbb1ca594166803ccc94c2bdb99bafa [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 Benjamin751e8892014-10-19 00:59:36 -040027#include <openssl/base64.h>
28#include <openssl/bio.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040029#include <openssl/cipher.h>
David Benjamin7a1eefd2015-10-17 23:39:22 -040030#include <openssl/crypto.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040031#include <openssl/err.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040032#include <openssl/hmac.h>
David Benjaminde942382016-02-11 12:02:01 -050033#include <openssl/pem.h>
David Benjamin25490f22016-07-14 00:22:54 -040034#include <openssl/sha.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040035#include <openssl/ssl.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040036#include <openssl/rand.h>
David Benjaminde942382016-02-11 12:02:01 -050037#include <openssl/x509.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040038
Steven Valdez87eab492016-06-27 16:34:59 -040039#include "internal.h"
Steven Valdezcb966542016-08-17 16:56:14 -040040#include "../crypto/internal.h"
Sigbjorn Vik2b23d242015-06-29 15:07:26 +020041#include "../crypto/test/test_util.h"
42
David Benjamin721e8b72016-08-03 13:13:17 -040043#if defined(OPENSSL_WINDOWS)
David Benjaminc11ea9422017-08-29 16:33:21 -040044// Windows defines struct timeval in winsock2.h.
David Benjamin721e8b72016-08-03 13:13:17 -040045OPENSSL_MSVC_PRAGMA(warning(push, 3))
46#include <winsock2.h>
47OPENSSL_MSVC_PRAGMA(warning(pop))
48#else
49#include <sys/time.h>
50#endif
51
David Benjamin5b33eff2018-09-22 16:52:48 -070052#if defined(OPENSSL_THREADS)
David Benjamin6c04bd12018-07-19 18:13:09 -040053#include <thread>
54#endif
55
David Benjamin1d77e562015-03-22 17:22:08 -040056
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -070057BSSL_NAMESPACE_BEGIN
Martin Kreichgauer72912d22017-08-04 12:06:43 -070058
59namespace {
60
Martin Kreichgauer1a663262017-08-16 14:54:04 -070061#define TRACED_CALL(code) \
62 do { \
63 SCOPED_TRACE("<- called from here"); \
64 code; \
65 if (::testing::Test::HasFatalFailure()) { \
66 return; \
67 } \
68 } while (false)
69
Martin Kreichgauer72912d22017-08-04 12:06:43 -070070struct VersionParam {
71 uint16_t version;
72 enum { is_tls, is_dtls } ssl_method;
73 const char name[8];
74};
75
76static const size_t kTicketKeyLen = 48;
77
78static const VersionParam kAllVersions[] = {
Martin Kreichgauer72912d22017-08-04 12:06:43 -070079 {TLS1_VERSION, VersionParam::is_tls, "TLS1"},
80 {TLS1_1_VERSION, VersionParam::is_tls, "TLS1_1"},
81 {TLS1_2_VERSION, VersionParam::is_tls, "TLS1_2"},
Martin Kreichgauer72912d22017-08-04 12:06:43 -070082 {TLS1_3_VERSION, VersionParam::is_tls, "TLS1_3"},
Martin Kreichgauer72912d22017-08-04 12:06:43 -070083 {DTLS1_VERSION, VersionParam::is_dtls, "DTLS1"},
84 {DTLS1_2_VERSION, VersionParam::is_dtls, "DTLS1_2"},
85};
86
David Benjamin1d77e562015-03-22 17:22:08 -040087struct ExpectedCipher {
88 unsigned long id;
David Benjaminbb0a17c2014-09-20 15:35:39 -040089 int in_group_flag;
David Benjamin1d77e562015-03-22 17:22:08 -040090};
David Benjaminbb0a17c2014-09-20 15:35:39 -040091
David Benjamin1d77e562015-03-22 17:22:08 -040092struct CipherTest {
93 // The rule string to apply.
David Benjaminbb0a17c2014-09-20 15:35:39 -040094 const char *rule;
David Benjaminfb974e62015-12-16 19:34:22 -050095 // The list of expected ciphers, in order.
96 std::vector<ExpectedCipher> expected;
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -080097 // True if this cipher list should fail in strict mode.
98 bool strict_fail;
David Benjamin1d77e562015-03-22 17:22:08 -040099};
David Benjaminbb0a17c2014-09-20 15:35:39 -0400100
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100101struct CurveTest {
102 // The rule string to apply.
103 const char *rule;
104 // The list of expected curves, in order.
105 std::vector<uint16_t> expected;
106};
107
Steven Valdezc8e0f902018-07-14 11:23:01 -0400108template <typename T>
109class UnownedSSLExData {
110 public:
111 UnownedSSLExData() {
112 index_ = SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
113 }
114
115 T *Get(const SSL *ssl) {
116 return index_ < 0 ? nullptr
117 : static_cast<T *>(SSL_get_ex_data(ssl, index_));
118 }
119
120 bool Set(SSL *ssl, T *t) {
121 return index_ >= 0 && SSL_set_ex_data(ssl, index_, t);
122 }
123
124 private:
125 int index_;
126};
127
David Benjaminfb974e62015-12-16 19:34:22 -0500128static const CipherTest kCipherTests[] = {
129 // Selecting individual ciphers should work.
130 {
131 "ECDHE-ECDSA-CHACHA20-POLY1305:"
132 "ECDHE-RSA-CHACHA20-POLY1305:"
133 "ECDHE-ECDSA-AES128-GCM-SHA256:"
134 "ECDHE-RSA-AES128-GCM-SHA256",
135 {
136 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500137 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500138 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
139 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
140 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800141 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500142 },
143 // + reorders selected ciphers to the end, keeping their relative order.
144 {
145 "ECDHE-ECDSA-CHACHA20-POLY1305:"
146 "ECDHE-RSA-CHACHA20-POLY1305:"
147 "ECDHE-ECDSA-AES128-GCM-SHA256:"
148 "ECDHE-RSA-AES128-GCM-SHA256:"
149 "+aRSA",
150 {
151 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500152 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
153 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500154 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
155 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800156 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500157 },
158 // ! banishes ciphers from future selections.
159 {
160 "!aRSA:"
161 "ECDHE-ECDSA-CHACHA20-POLY1305:"
162 "ECDHE-RSA-CHACHA20-POLY1305:"
163 "ECDHE-ECDSA-AES128-GCM-SHA256:"
164 "ECDHE-RSA-AES128-GCM-SHA256",
165 {
166 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500167 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
168 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800169 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500170 },
171 // Multiple masks can be ANDed in a single rule.
172 {
173 "kRSA+AESGCM+AES128",
174 {
175 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
176 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800177 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500178 },
179 // - removes selected ciphers, but preserves their order for future
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700180 // selections. Select AES_128_GCM, but order the key exchanges RSA,
David Benjaminfb974e62015-12-16 19:34:22 -0500181 // ECDHE_RSA.
182 {
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700183 "ALL:-kECDHE:"
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700184 "-kRSA:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500185 "AESGCM+AES128+aRSA",
186 {
187 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500188 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
189 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800190 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500191 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800192 // Unknown selectors are no-ops, except in strict mode.
David Benjaminfb974e62015-12-16 19:34:22 -0500193 {
194 "ECDHE-ECDSA-CHACHA20-POLY1305:"
195 "ECDHE-RSA-CHACHA20-POLY1305:"
196 "ECDHE-ECDSA-AES128-GCM-SHA256:"
197 "ECDHE-RSA-AES128-GCM-SHA256:"
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800198 "BOGUS1",
David Benjaminfb974e62015-12-16 19:34:22 -0500199 {
200 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500201 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500202 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
203 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
204 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800205 true,
206 },
207 // Unknown selectors are no-ops, except in strict mode.
208 {
209 "ECDHE-ECDSA-CHACHA20-POLY1305:"
210 "ECDHE-RSA-CHACHA20-POLY1305:"
211 "ECDHE-ECDSA-AES128-GCM-SHA256:"
212 "ECDHE-RSA-AES128-GCM-SHA256:"
213 "-BOGUS2:+BOGUS3:!BOGUS4",
214 {
215 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
216 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
217 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
218 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
219 },
220 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500221 },
222 // Square brackets specify equi-preference groups.
223 {
224 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
225 "[ECDHE-RSA-CHACHA20-POLY1305]:"
226 "ECDHE-RSA-AES128-GCM-SHA256",
227 {
228 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
David Benjaminfb974e62015-12-16 19:34:22 -0500229 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley2e839242017-01-19 15:12:44 -0800230 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500231 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
232 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800233 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500234 },
David Benjamin6fff3862017-06-21 21:07:04 -0400235 // Standard names may be used instead of OpenSSL names.
236 {
237 "[TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256|"
David Benjaminbf5f1922017-07-01 11:13:53 -0400238 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256]:"
David Benjamin6fff3862017-06-21 21:07:04 -0400239 "[TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256]:"
240 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
241 {
242 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
243 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
244 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
245 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
246 },
247 false,
248 },
David Benjaminfb974e62015-12-16 19:34:22 -0500249 // @STRENGTH performs a stable strength-sort of the selected ciphers and
250 // only the selected ciphers.
251 {
252 // To simplify things, banish all but {ECDHE_RSA,RSA} x
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700253 // {CHACHA20,AES_256_CBC,AES_128_CBC} x SHA1.
David Benjamin6e678ee2018-04-16 19:54:42 -0400254 "!AESGCM:!3DES:"
David Benjaminfb974e62015-12-16 19:34:22 -0500255 // Order some ciphers backwards by strength.
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700256 "ALL:-CHACHA20:-AES256:-AES128:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500257 // Select ECDHE ones and sort them by strength. Ties should resolve
258 // based on the order above.
259 "kECDHE:@STRENGTH:-ALL:"
260 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
261 // by strength. Then RSA, backwards by strength.
262 "aRSA",
263 {
264 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
265 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500266 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500267 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
268 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
269 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800270 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500271 },
David Benjaminbf5f1922017-07-01 11:13:53 -0400272 // Additional masks after @STRENGTH get silently discarded.
273 //
274 // TODO(davidben): Make this an error. If not silently discarded, they get
275 // interpreted as + opcodes which are very different.
276 {
277 "ECDHE-RSA-AES128-GCM-SHA256:"
278 "ECDHE-RSA-AES256-GCM-SHA384:"
279 "@STRENGTH+AES256",
280 {
281 {TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
282 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
283 },
284 false,
285 },
286 {
287 "ECDHE-RSA-AES128-GCM-SHA256:"
288 "ECDHE-RSA-AES256-GCM-SHA384:"
289 "@STRENGTH+AES256:"
290 "ECDHE-RSA-CHACHA20-POLY1305",
291 {
292 {TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
293 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
294 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
295 },
296 false,
297 },
David Benjaminfb974e62015-12-16 19:34:22 -0500298 // Exact ciphers may not be used in multi-part rules; they are treated
299 // as unknown aliases.
300 {
301 "ECDHE-ECDSA-AES128-GCM-SHA256:"
302 "ECDHE-RSA-AES128-GCM-SHA256:"
303 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
304 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
305 {
306 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
307 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
308 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800309 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500310 },
311 // SSLv3 matches everything that existed before TLS 1.2.
312 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400313 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!SSLv3",
David Benjaminfb974e62015-12-16 19:34:22 -0500314 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400315 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500316 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800317 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500318 },
319 // TLSv1.2 matches everything added in TLS 1.2.
320 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400321 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!TLSv1.2",
David Benjaminfb974e62015-12-16 19:34:22 -0500322 {
323 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
324 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800325 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500326 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800327 // The two directives have no intersection. But each component is valid, so
328 // even in strict mode it is accepted.
David Benjaminfb974e62015-12-16 19:34:22 -0500329 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400330 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!TLSv1.2+SSLv3",
David Benjaminfb974e62015-12-16 19:34:22 -0500331 {
332 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400333 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500334 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800335 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500336 },
Adam Langley22df6912017-07-25 12:27:37 -0700337 // Spaces, semi-colons and commas are separators.
338 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400339 "AES128-SHA: ECDHE-RSA-AES128-GCM-SHA256 AES256-SHA ,ECDHE-ECDSA-AES128-GCM-SHA256 ; AES128-GCM-SHA256",
Adam Langley22df6912017-07-25 12:27:37 -0700340 {
341 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400342 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley22df6912017-07-25 12:27:37 -0700343 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400344 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley22df6912017-07-25 12:27:37 -0700345 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
346 },
347 // …but not in strict mode.
348 true,
349 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400350};
351
352static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400353 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400354 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
355 "RSA]",
356 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400357 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400358 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400359 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400360 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400361 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400362 "",
363 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400364 // COMPLEMENTOFDEFAULT is empty.
365 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400366 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400367 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400368 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400369 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
370 "[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]:@STRENGTH",
Adam Langleyf99f2442016-10-02 09:53:38 -0700373 // Opcode supplied, but missing selector.
374 "+",
Adam Langley22df6912017-07-25 12:27:37 -0700375 // Spaces are forbidden in equal-preference groups.
376 "[AES128-SHA | AES128-SHA256]",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400377};
378
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700379static const char *kMustNotIncludeNull[] = {
380 "ALL",
381 "DEFAULT",
David Benjamind6e9eec2015-11-18 09:48:55 -0500382 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700383 "FIPS",
384 "SHA",
385 "SHA1",
386 "RSA",
387 "SSLv3",
388 "TLSv1",
389 "TLSv1.2",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700390};
391
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100392static const CurveTest kCurveTests[] = {
393 {
394 "P-256",
395 { SSL_CURVE_SECP256R1 },
396 },
397 {
Adam Langley7b935932018-11-12 13:53:42 -0800398 "P-256:CECPQ2",
399 { SSL_CURVE_SECP256R1, SSL_CURVE_CECPQ2 },
400 },
401
402 {
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100403 "P-256:P-384:P-521:X25519",
404 {
405 SSL_CURVE_SECP256R1,
406 SSL_CURVE_SECP384R1,
407 SSL_CURVE_SECP521R1,
408 SSL_CURVE_X25519,
409 },
410 },
David Benjamin6dda1662017-11-02 20:44:26 -0400411 {
412 "prime256v1:secp384r1:secp521r1:x25519",
413 {
414 SSL_CURVE_SECP256R1,
415 SSL_CURVE_SECP384R1,
416 SSL_CURVE_SECP521R1,
417 SSL_CURVE_X25519,
418 },
419 },
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100420};
421
422static const char *kBadCurvesLists[] = {
423 "",
424 ":",
425 "::",
426 "P-256::X25519",
427 "RSA:P-256",
428 "P-256:RSA",
429 "X25519:P-256:",
430 ":X25519:P-256",
431};
432
David Benjamin70dbf042017-08-08 18:51:37 -0400433static std::string CipherListToString(SSL_CTX *ctx) {
David Benjamin1d77e562015-03-22 17:22:08 -0400434 bool in_group = false;
David Benjamine11726a2017-04-23 12:14:28 -0400435 std::string ret;
David Benjamin70dbf042017-08-08 18:51:37 -0400436 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
437 for (size_t i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
438 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
439 if (!in_group && SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400440 ret += "\t[\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400441 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400442 }
David Benjamine11726a2017-04-23 12:14:28 -0400443 ret += "\t";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400444 if (in_group) {
David Benjamine11726a2017-04-23 12:14:28 -0400445 ret += " ";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400446 }
David Benjamine11726a2017-04-23 12:14:28 -0400447 ret += SSL_CIPHER_get_name(cipher);
448 ret += "\n";
David Benjamin70dbf042017-08-08 18:51:37 -0400449 if (in_group && !SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400450 ret += "\t]\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400451 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400452 }
453 }
David Benjamine11726a2017-04-23 12:14:28 -0400454 return ret;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400455}
456
David Benjamin70dbf042017-08-08 18:51:37 -0400457static bool CipherListsEqual(SSL_CTX *ctx,
David Benjamine11726a2017-04-23 12:14:28 -0400458 const std::vector<ExpectedCipher> &expected) {
David Benjamin70dbf042017-08-08 18:51:37 -0400459 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
460 if (sk_SSL_CIPHER_num(ciphers) != expected.size()) {
David Benjamin1d77e562015-03-22 17:22:08 -0400461 return false;
David Benjamin65226252015-02-05 16:49:47 -0500462 }
463
David Benjamine11726a2017-04-23 12:14:28 -0400464 for (size_t i = 0; i < expected.size(); i++) {
David Benjamin70dbf042017-08-08 18:51:37 -0400465 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
David Benjamine11726a2017-04-23 12:14:28 -0400466 if (expected[i].id != SSL_CIPHER_get_id(cipher) ||
David Benjamin70dbf042017-08-08 18:51:37 -0400467 expected[i].in_group_flag != !!SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400468 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400469 }
470 }
471
David Benjamin1d77e562015-03-22 17:22:08 -0400472 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400473}
474
David Benjamine11726a2017-04-23 12:14:28 -0400475TEST(SSLTest, CipherRules) {
476 for (const CipherTest &t : kCipherTests) {
477 SCOPED_TRACE(t.rule);
478 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
479 ASSERT_TRUE(ctx);
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700480
David Benjamine11726a2017-04-23 12:14:28 -0400481 // Test lax mode.
482 ASSERT_TRUE(SSL_CTX_set_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400483 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400484 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400485 << CipherListToString(ctx.get());
David Benjamine11726a2017-04-23 12:14:28 -0400486
487 // Test strict mode.
488 if (t.strict_fail) {
489 EXPECT_FALSE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
490 } else {
491 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400492 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400493 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400494 << CipherListToString(ctx.get());
David Benjaminbb0a17c2014-09-20 15:35:39 -0400495 }
496 }
497
David Benjaminfb974e62015-12-16 19:34:22 -0500498 for (const char *rule : kBadRules) {
David Benjamine11726a2017-04-23 12:14:28 -0400499 SCOPED_TRACE(rule);
500 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
501 ASSERT_TRUE(ctx);
502
503 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), rule));
David Benjaminbb0a17c2014-09-20 15:35:39 -0400504 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400505 }
506
David Benjaminfb974e62015-12-16 19:34:22 -0500507 for (const char *rule : kMustNotIncludeNull) {
David Benjamine11726a2017-04-23 12:14:28 -0400508 SCOPED_TRACE(rule);
509 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
510 ASSERT_TRUE(ctx);
511
512 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400513 for (const SSL_CIPHER *cipher : SSL_CTX_get_ciphers(ctx.get())) {
David Benjamine3bb51c2017-08-22 23:16:02 -0700514 EXPECT_NE(NID_undef, SSL_CIPHER_get_cipher_nid(cipher));
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700515 }
516 }
David Benjaminbb0a17c2014-09-20 15:35:39 -0400517}
David Benjamin2e521212014-07-16 14:37:51 -0400518
David Benjamine11726a2017-04-23 12:14:28 -0400519TEST(SSLTest, CurveRules) {
520 for (const CurveTest &t : kCurveTests) {
521 SCOPED_TRACE(t.rule);
522 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
523 ASSERT_TRUE(ctx);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100524
David Benjamine11726a2017-04-23 12:14:28 -0400525 ASSERT_TRUE(SSL_CTX_set1_curves_list(ctx.get(), t.rule));
David Benjamin0ce090a2018-07-02 20:24:40 -0400526 ASSERT_EQ(t.expected.size(), ctx->supported_group_list.size());
David Benjamine11726a2017-04-23 12:14:28 -0400527 for (size_t i = 0; i < t.expected.size(); i++) {
528 EXPECT_EQ(t.expected[i], ctx->supported_group_list[i]);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100529 }
530 }
531
532 for (const char *rule : kBadCurvesLists) {
David Benjamine11726a2017-04-23 12:14:28 -0400533 SCOPED_TRACE(rule);
534 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
535 ASSERT_TRUE(ctx);
536
537 EXPECT_FALSE(SSL_CTX_set1_curves_list(ctx.get(), rule));
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100538 ERR_clear_error();
539 }
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100540}
541
Adam Langley364f7a62016-12-12 10:51:00 -0800542// kOpenSSLSession is a serialized SSL_SESSION.
Adam Langley10f97f32016-07-12 08:09:33 -0700543static const char kOpenSSLSession[] =
Adam Langley364f7a62016-12-12 10:51:00 -0800544 "MIIFqgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700545 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
546 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
547 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
548 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
549 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
550 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
551 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
552 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
553 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
554 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
555 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
556 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
557 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
558 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
559 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
560 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
561 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
562 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
563 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
564 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
565 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
566 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
567 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
568 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
569 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
570 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
571 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
572 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
573 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
Adam Langley364f7a62016-12-12 10:51:00 -0800574 "i4gv7Y5oliyntgMBAQA=";
Adam Langley10f97f32016-07-12 08:09:33 -0700575
576// kCustomSession is a custom serialized SSL_SESSION generated by
577// filling in missing fields from |kOpenSSLSession|. This includes
578// providing |peer_sha256|, so |peer| is not serialized.
579static const char kCustomSession[] =
David Benjamina8614602017-09-06 15:40:19 -0400580 "MIIBZAIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700581 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
David Benjamina8614602017-09-06 15:40:19 -0400582 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUqAcEBXdvcmxkqQUCAwGJwKqBpwSB"
583 "pBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38"
584 "VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd"
585 "3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hg"
586 "b+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYGBgYGBgYGBgYGBgYGBgYGBgYG"
587 "BgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
Adam Langley10f97f32016-07-12 08:09:33 -0700588
589// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
590static const char kBoringSSLSession[] =
591 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
592 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
593 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
594 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
595 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
596 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
597 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
598 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
599 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
600 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
601 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
602 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
603 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
604 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
605 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
606 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
607 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
608 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
609 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
610 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
611 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
612 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
613 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
614 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
615 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
616 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
617 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
618 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
619 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
620 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
621 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
622 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
623 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
624 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
625 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
626 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
627 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
628 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
629 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
630 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
631 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
632 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
633 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
634 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
635 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
636 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
637 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
638 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
639 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
640 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
641 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
642 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
643 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
644 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
645 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
646 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
647 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
648 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
649 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
650 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
651 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
652 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
653 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
654 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
655 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
656 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
657 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
658 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
659 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
660 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
661 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
662 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
663 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
664 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
665 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
666 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
667 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
668 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
669 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
670 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
671 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
672 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
673 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
674 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
675 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
676 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
677 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
678 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
679 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
680 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
681 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
682 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
683 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
684 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
685 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
686
687// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
688// the final (optional) element of |kCustomSession| with tag number 30.
689static const char kBadSessionExtraField[] =
690 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
691 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
692 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
693 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
694 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
695 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
696 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
697 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
698
699// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
700// the version of |kCustomSession| with 2.
701static const char kBadSessionVersion[] =
702 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
703 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
704 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
705 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
706 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
707 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
708 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
709 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
710
711// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
712// appended.
713static const char kBadSessionTrailingData[] =
714 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
715 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
716 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
717 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
718 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
719 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
720 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
721 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
722
David Benjamin1d77e562015-03-22 17:22:08 -0400723static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400724 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400725 if (!EVP_DecodedLength(&len, strlen(in))) {
726 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400727 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400728 }
729
David Benjamin1d77e562015-03-22 17:22:08 -0400730 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800731 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400732 strlen(in))) {
733 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400734 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400735 }
David Benjamin1d77e562015-03-22 17:22:08 -0400736 out->resize(len);
737 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400738}
739
David Benjamin1d77e562015-03-22 17:22:08 -0400740static bool TestSSL_SESSIONEncoding(const char *input_b64) {
David Benjamin751e8892014-10-19 00:59:36 -0400741 const uint8_t *cptr;
742 uint8_t *ptr;
David Benjamin751e8892014-10-19 00:59:36 -0400743
David Benjamin1d77e562015-03-22 17:22:08 -0400744 // Decode the input.
745 std::vector<uint8_t> input;
746 if (!DecodeBase64(&input, input_b64)) {
747 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400748 }
749
David Benjamin1d77e562015-03-22 17:22:08 -0400750 // Verify the SSL_SESSION decodes.
Adam Langley46db7af2017-02-01 15:49:37 -0800751 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
752 if (!ssl_ctx) {
753 return false;
754 }
755 bssl::UniquePtr<SSL_SESSION> session(
756 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
David Benjaminfd67aa82015-06-15 19:41:48 -0400757 if (!session) {
758 fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400759 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400760 }
761
David Benjamin1d77e562015-03-22 17:22:08 -0400762 // Verify the SSL_SESSION encoding round-trips.
763 size_t encoded_len;
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700764 bssl::UniquePtr<uint8_t> encoded;
David Benjamin1d77e562015-03-22 17:22:08 -0400765 uint8_t *encoded_raw;
766 if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
David Benjamin3cac4502014-10-21 01:46:30 -0400767 fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400768 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400769 }
David Benjamin1d77e562015-03-22 17:22:08 -0400770 encoded.reset(encoded_raw);
771 if (encoded_len != input.size() ||
David Benjamin17cf2cb2016-12-13 01:07:13 -0500772 OPENSSL_memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin3cac4502014-10-21 01:46:30 -0400773 fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
Sigbjorn Vik2b23d242015-06-29 15:07:26 +0200774 hexdump(stderr, "Before: ", input.data(), input.size());
775 hexdump(stderr, "After: ", encoded_raw, encoded_len);
David Benjamin1d77e562015-03-22 17:22:08 -0400776 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400777 }
David Benjamin3cac4502014-10-21 01:46:30 -0400778
David Benjaminfd67aa82015-06-15 19:41:48 -0400779 // Verify the SSL_SESSION also decodes with the legacy API.
David Benjaminef14b2d2015-11-11 14:01:27 -0800780 cptr = input.data();
David Benjaminfd67aa82015-06-15 19:41:48 -0400781 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
David Benjaminef14b2d2015-11-11 14:01:27 -0800782 if (!session || cptr != input.data() + input.size()) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400783 fprintf(stderr, "d2i_SSL_SESSION failed\n");
784 return false;
785 }
786
David Benjamin1d77e562015-03-22 17:22:08 -0400787 // Verify the SSL_SESSION encoding round-trips via the legacy API.
788 int len = i2d_SSL_SESSION(session.get(), NULL);
789 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400790 fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400791 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400792 }
793
David Benjamin1d77e562015-03-22 17:22:08 -0400794 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
795 if (!encoded) {
David Benjamin751e8892014-10-19 00:59:36 -0400796 fprintf(stderr, "malloc failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400797 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400798 }
David Benjamin1d77e562015-03-22 17:22:08 -0400799
800 ptr = encoded.get();
801 len = i2d_SSL_SESSION(session.get(), &ptr);
802 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400803 fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400804 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400805 }
David Benjamin1d77e562015-03-22 17:22:08 -0400806 if (ptr != encoded.get() + input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400807 fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400808 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400809 }
David Benjamin17cf2cb2016-12-13 01:07:13 -0500810 if (OPENSSL_memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin751e8892014-10-19 00:59:36 -0400811 fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400812 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400813 }
814
David Benjamin1d77e562015-03-22 17:22:08 -0400815 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400816}
817
David Benjaminf297e022015-05-28 19:55:29 -0400818static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
819 std::vector<uint8_t> input;
820 if (!DecodeBase64(&input, input_b64)) {
821 return false;
822 }
823
824 // Verify that the SSL_SESSION fails to decode.
Adam Langley46db7af2017-02-01 15:49:37 -0800825 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
826 if (!ssl_ctx) {
827 return false;
828 }
829 bssl::UniquePtr<SSL_SESSION> session(
830 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
David Benjaminf297e022015-05-28 19:55:29 -0400831 if (session) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400832 fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
David Benjaminf297e022015-05-28 19:55:29 -0400833 return false;
834 }
835 ERR_clear_error();
836 return true;
837}
838
David Benjamin321fcdc2017-04-24 11:42:42 -0400839static void ExpectDefaultVersion(uint16_t min_version, uint16_t max_version,
840 const SSL_METHOD *(*method)(void)) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700841 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
David Benjamin321fcdc2017-04-24 11:42:42 -0400842 ASSERT_TRUE(ctx);
David Benjaminfc08dfc2017-06-20 14:39:32 -0400843 EXPECT_EQ(min_version, ctx->conf_min_version);
844 EXPECT_EQ(max_version, ctx->conf_max_version);
David Benjamin321fcdc2017-04-24 11:42:42 -0400845}
846
847TEST(SSLTest, DefaultVersion) {
848 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
849 ExpectDefaultVersion(TLS1_VERSION, TLS1_2_VERSION, &TLS_method);
850 ExpectDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method);
851 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method);
852 ExpectDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method);
853 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method);
854 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method);
855 ExpectDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method);
David Benjamin82c9e902014-12-12 15:55:27 -0500856}
857
David Benjamin348f0d82017-08-10 16:06:27 -0400858TEST(SSLTest, CipherProperties) {
David Benjamin6fff3862017-06-21 21:07:04 -0400859 static const struct {
860 int id;
861 const char *standard_name;
David Benjamin348f0d82017-08-10 16:06:27 -0400862 int cipher_nid;
863 int digest_nid;
864 int kx_nid;
865 int auth_nid;
David Benjaminb1b76ae2017-09-21 17:03:34 -0400866 int prf_nid;
David Benjamin6fff3862017-06-21 21:07:04 -0400867 } kTests[] = {
David Benjamin348f0d82017-08-10 16:06:27 -0400868 {
869 SSL3_CK_RSA_DES_192_CBC3_SHA,
870 "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
871 NID_des_ede3_cbc,
872 NID_sha1,
873 NID_kx_rsa,
874 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400875 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400876 },
877 {
878 TLS1_CK_RSA_WITH_AES_128_SHA,
879 "TLS_RSA_WITH_AES_128_CBC_SHA",
880 NID_aes_128_cbc,
881 NID_sha1,
882 NID_kx_rsa,
883 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400884 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400885 },
886 {
887 TLS1_CK_PSK_WITH_AES_256_CBC_SHA,
888 "TLS_PSK_WITH_AES_256_CBC_SHA",
889 NID_aes_256_cbc,
890 NID_sha1,
891 NID_kx_psk,
892 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400893 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400894 },
895 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400896 TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA,
897 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
David Benjamin348f0d82017-08-10 16:06:27 -0400898 NID_aes_128_cbc,
David Benjamin6e678ee2018-04-16 19:54:42 -0400899 NID_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400900 NID_kx_ecdhe,
901 NID_auth_rsa,
David Benjamin6e678ee2018-04-16 19:54:42 -0400902 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400903 },
904 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400905 TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA,
906 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
David Benjamin348f0d82017-08-10 16:06:27 -0400907 NID_aes_256_cbc,
David Benjamin6e678ee2018-04-16 19:54:42 -0400908 NID_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400909 NID_kx_ecdhe,
910 NID_auth_rsa,
David Benjamin6e678ee2018-04-16 19:54:42 -0400911 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400912 },
913 {
914 TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
915 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
916 NID_aes_128_gcm,
917 NID_undef,
918 NID_kx_ecdhe,
919 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400920 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400921 },
922 {
923 TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
924 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
925 NID_aes_128_gcm,
926 NID_undef,
927 NID_kx_ecdhe,
928 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400929 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400930 },
931 {
932 TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
933 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
934 NID_aes_256_gcm,
935 NID_undef,
936 NID_kx_ecdhe,
937 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400938 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -0400939 },
940 {
941 TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
942 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
943 NID_aes_128_cbc,
944 NID_sha1,
945 NID_kx_ecdhe,
946 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400947 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400948 },
949 {
950 TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
951 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
952 NID_chacha20_poly1305,
953 NID_undef,
954 NID_kx_ecdhe,
955 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400956 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400957 },
958 {
959 TLS1_CK_AES_256_GCM_SHA384,
960 "TLS_AES_256_GCM_SHA384",
961 NID_aes_256_gcm,
962 NID_undef,
963 NID_kx_any,
964 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400965 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -0400966 },
967 {
968 TLS1_CK_AES_128_GCM_SHA256,
969 "TLS_AES_128_GCM_SHA256",
970 NID_aes_128_gcm,
971 NID_undef,
972 NID_kx_any,
973 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400974 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400975 },
976 {
977 TLS1_CK_CHACHA20_POLY1305_SHA256,
978 "TLS_CHACHA20_POLY1305_SHA256",
979 NID_chacha20_poly1305,
980 NID_undef,
981 NID_kx_any,
982 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400983 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400984 },
David Benjamin6fff3862017-06-21 21:07:04 -0400985 };
David Benjamin65226252015-02-05 16:49:47 -0500986
David Benjamin6fff3862017-06-21 21:07:04 -0400987 for (const auto &t : kTests) {
988 SCOPED_TRACE(t.standard_name);
David Benjamine11726a2017-04-23 12:14:28 -0400989
990 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(t.id & 0xffff);
991 ASSERT_TRUE(cipher);
David Benjamin6fff3862017-06-21 21:07:04 -0400992 EXPECT_STREQ(t.standard_name, SSL_CIPHER_standard_name(cipher));
993
David Benjamine11726a2017-04-23 12:14:28 -0400994 bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
995 ASSERT_TRUE(rfc_name);
David Benjamin6fff3862017-06-21 21:07:04 -0400996 EXPECT_STREQ(t.standard_name, rfc_name.get());
David Benjamin348f0d82017-08-10 16:06:27 -0400997
998 EXPECT_EQ(t.cipher_nid, SSL_CIPHER_get_cipher_nid(cipher));
999 EXPECT_EQ(t.digest_nid, SSL_CIPHER_get_digest_nid(cipher));
1000 EXPECT_EQ(t.kx_nid, SSL_CIPHER_get_kx_nid(cipher));
1001 EXPECT_EQ(t.auth_nid, SSL_CIPHER_get_auth_nid(cipher));
David Benjaminb1b76ae2017-09-21 17:03:34 -04001002 EXPECT_EQ(t.prf_nid, SSL_CIPHER_get_prf_nid(cipher));
David Benjamin65226252015-02-05 16:49:47 -05001003 }
David Benjamin65226252015-02-05 16:49:47 -05001004}
1005
Steven Valdeza833c352016-11-01 13:39:36 -04001006// CreateSessionWithTicket returns a sample |SSL_SESSION| with the specified
1007// version and ticket length or nullptr on failure.
1008static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(uint16_t version,
1009 size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -04001010 std::vector<uint8_t> der;
1011 if (!DecodeBase64(&der, kOpenSSLSession)) {
1012 return nullptr;
1013 }
Adam Langley46db7af2017-02-01 15:49:37 -08001014
1015 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
1016 if (!ssl_ctx) {
1017 return nullptr;
1018 }
David Benjaminaaef8332018-06-29 16:45:49 -04001019 // Use a garbage ticket.
1020 std::vector<uint8_t> ticket(ticket_len, 'a');
Steven Valdeza833c352016-11-01 13:39:36 -04001021 bssl::UniquePtr<SSL_SESSION> session(
Adam Langley46db7af2017-02-01 15:49:37 -08001022 SSL_SESSION_from_bytes(der.data(), der.size(), ssl_ctx.get()));
David Benjaminaaef8332018-06-29 16:45:49 -04001023 if (!session ||
1024 !SSL_SESSION_set_protocol_version(session.get(), version) ||
1025 !SSL_SESSION_set_ticket(session.get(), ticket.data(), ticket.size())) {
David Benjamin422fe082015-07-21 22:03:43 -04001026 return nullptr;
1027 }
David Benjamin1269ddd2015-10-18 15:18:55 -04001028 // Fix up the timeout.
David Benjamin9b63f292016-11-15 00:44:05 -05001029#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
David Benjaminaaef8332018-06-29 16:45:49 -04001030 SSL_SESSION_set_time(session.get(), 1234);
David Benjamin9b63f292016-11-15 00:44:05 -05001031#else
David Benjaminaaef8332018-06-29 16:45:49 -04001032 SSL_SESSION_set_time(session.get(), time(nullptr));
David Benjamin9b63f292016-11-15 00:44:05 -05001033#endif
David Benjamin422fe082015-07-21 22:03:43 -04001034 return session;
1035}
1036
David Benjaminafc64de2016-07-19 17:12:41 +02001037static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001038 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +02001039 if (!bio) {
1040 return false;
1041 }
1042 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -04001043 BIO_up_ref(bio.get());
1044 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +02001045 int ret = SSL_connect(ssl);
1046 if (ret > 0) {
1047 // SSL_connect should fail without a BIO to write to.
1048 return false;
1049 }
1050 ERR_clear_error();
1051
1052 const uint8_t *client_hello;
1053 size_t client_hello_len;
1054 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
1055 return false;
1056 }
1057 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
1058 return true;
1059}
1060
Steven Valdeza833c352016-11-01 13:39:36 -04001061// GetClientHelloLen creates a client SSL connection with the specified version
1062// and ticket length. It returns the length of the ClientHello, not including
1063// the record header, on success and zero on error.
1064static size_t GetClientHelloLen(uint16_t max_version, uint16_t session_version,
1065 size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001066 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Steven Valdeza833c352016-11-01 13:39:36 -04001067 bssl::UniquePtr<SSL_SESSION> session =
1068 CreateSessionWithTicket(session_version, ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -04001069 if (!ctx || !session) {
1070 return 0;
1071 }
Steven Valdeza833c352016-11-01 13:39:36 -04001072
1073 // Set a one-element cipher list so the baseline ClientHello is unpadded.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001074 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
Steven Valdez2c62fe92016-10-14 12:08:12 -04001075 if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -08001076 !SSL_set_strict_cipher_list(ssl.get(), "ECDHE-RSA-AES128-GCM-SHA256") ||
Steven Valdeza833c352016-11-01 13:39:36 -04001077 !SSL_set_max_proto_version(ssl.get(), max_version)) {
David Benjamin422fe082015-07-21 22:03:43 -04001078 return 0;
1079 }
Steven Valdeza833c352016-11-01 13:39:36 -04001080
David Benjaminafc64de2016-07-19 17:12:41 +02001081 std::vector<uint8_t> client_hello;
1082 if (!GetClientHello(ssl.get(), &client_hello) ||
1083 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -04001084 return 0;
1085 }
Steven Valdeza833c352016-11-01 13:39:36 -04001086
David Benjaminafc64de2016-07-19 17:12:41 +02001087 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -04001088}
1089
1090struct PaddingTest {
1091 size_t input_len, padded_len;
1092};
1093
1094static const PaddingTest kPaddingTests[] = {
1095 // ClientHellos of length below 0x100 do not require padding.
1096 {0xfe, 0xfe},
1097 {0xff, 0xff},
1098 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
1099 {0x100, 0x200},
1100 {0x123, 0x200},
1101 {0x1fb, 0x200},
1102 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
1103 // padding extension takes a minimum of four bytes plus one required content
1104 // byte. (To work around yet more server bugs, we avoid empty final
1105 // extensions.)
1106 {0x1fc, 0x201},
1107 {0x1fd, 0x202},
1108 {0x1fe, 0x203},
1109 {0x1ff, 0x204},
1110 // Finally, larger ClientHellos need no padding.
1111 {0x200, 0x200},
1112 {0x201, 0x201},
1113};
1114
Steven Valdeza833c352016-11-01 13:39:36 -04001115static bool TestPaddingExtension(uint16_t max_version,
1116 uint16_t session_version) {
David Benjamin422fe082015-07-21 22:03:43 -04001117 // Sample a baseline length.
Steven Valdeza833c352016-11-01 13:39:36 -04001118 size_t base_len = GetClientHelloLen(max_version, session_version, 1);
David Benjamin422fe082015-07-21 22:03:43 -04001119 if (base_len == 0) {
1120 return false;
1121 }
1122
1123 for (const PaddingTest &test : kPaddingTests) {
1124 if (base_len > test.input_len) {
Steven Valdeza833c352016-11-01 13:39:36 -04001125 fprintf(stderr,
1126 "Baseline ClientHello too long (max_version = %04x, "
1127 "session_version = %04x).\n",
1128 max_version, session_version);
David Benjamin422fe082015-07-21 22:03:43 -04001129 return false;
1130 }
1131
Steven Valdeza833c352016-11-01 13:39:36 -04001132 size_t padded_len = GetClientHelloLen(max_version, session_version,
1133 1 + test.input_len - base_len);
David Benjamin422fe082015-07-21 22:03:43 -04001134 if (padded_len != test.padded_len) {
Steven Valdeza833c352016-11-01 13:39:36 -04001135 fprintf(stderr,
1136 "%u-byte ClientHello padded to %u bytes, not %u (max_version = "
1137 "%04x, session_version = %04x).\n",
David Benjamin422fe082015-07-21 22:03:43 -04001138 static_cast<unsigned>(test.input_len),
1139 static_cast<unsigned>(padded_len),
Steven Valdeza833c352016-11-01 13:39:36 -04001140 static_cast<unsigned>(test.padded_len), max_version,
1141 session_version);
David Benjamin422fe082015-07-21 22:03:43 -04001142 return false;
1143 }
1144 }
Steven Valdeza833c352016-11-01 13:39:36 -04001145
David Benjamin422fe082015-07-21 22:03:43 -04001146 return true;
1147}
1148
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001149static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001150 static const char kCertPEM[] =
1151 "-----BEGIN CERTIFICATE-----\n"
1152 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1153 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1154 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1155 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1156 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1157 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1158 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1159 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1160 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1161 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1162 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1163 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1164 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1165 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001166 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
David Benjamin1444c3a2016-12-20 17:23:11 -05001167 return bssl::UniquePtr<X509>(
1168 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjaminde942382016-02-11 12:02:01 -05001169}
1170
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001171static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001172 static const char kKeyPEM[] =
1173 "-----BEGIN RSA PRIVATE KEY-----\n"
1174 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1175 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1176 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1177 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1178 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1179 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1180 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1181 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1182 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1183 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1184 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1185 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1186 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1187 "-----END RSA PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001188 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1189 return bssl::UniquePtr<EVP_PKEY>(
David Benjaminde942382016-02-11 12:02:01 -05001190 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1191}
1192
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001193static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001194 static const char kCertPEM[] =
1195 "-----BEGIN CERTIFICATE-----\n"
1196 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1197 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1198 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1199 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1200 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1201 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1202 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1203 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1204 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1205 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1206 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001207 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1208 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjamin0fc37ef2016-08-17 15:29:46 -04001209}
1210
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001211static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001212 static const char kKeyPEM[] =
1213 "-----BEGIN PRIVATE KEY-----\n"
1214 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1215 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1216 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1217 "-----END PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001218 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1219 return bssl::UniquePtr<EVP_PKEY>(
David Benjamin0fc37ef2016-08-17 15:29:46 -04001220 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1221}
1222
Adam Langleyd04ca952017-02-28 11:26:51 -08001223static bssl::UniquePtr<CRYPTO_BUFFER> BufferFromPEM(const char *pem) {
1224 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1225 char *name, *header;
1226 uint8_t *data;
1227 long data_len;
1228 if (!PEM_read_bio(bio.get(), &name, &header, &data,
1229 &data_len)) {
1230 return nullptr;
1231 }
1232 OPENSSL_free(name);
1233 OPENSSL_free(header);
1234
1235 auto ret = bssl::UniquePtr<CRYPTO_BUFFER>(
1236 CRYPTO_BUFFER_new(data, data_len, nullptr));
1237 OPENSSL_free(data);
1238 return ret;
1239}
1240
1241static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestCertificateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001242 static const char kCertPEM[] =
1243 "-----BEGIN CERTIFICATE-----\n"
1244 "MIIC0jCCAbqgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQiBD\n"
1245 "QTAeFw0xNjAyMjgyMDI3MDNaFw0yNjAyMjUyMDI3MDNaMBgxFjAUBgNVBAMMDUNs\n"
1246 "aWVudCBDZXJ0IEEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRvaz8\n"
1247 "CC/cshpCafJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/\n"
1248 "kLRcH89M/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3\n"
1249 "tHb+xs2PSs8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+c\n"
1250 "IDs2rQ+lP7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1\n"
1251 "z7C8jU50Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9V\n"
1252 "iLeXANgZi+Xx9KgfAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI\n"
1253 "KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBFEVbmYl+2RtNw\n"
1254 "rDftRDF1v2QUbcN2ouSnQDHxeDQdSgasLzT3ui8iYu0Rw2WWcZ0DV5e0ztGPhWq7\n"
1255 "AO0B120aFRMOY+4+bzu9Q2FFkQqc7/fKTvTDzIJI5wrMnFvUfzzvxh3OHWMYSs/w\n"
1256 "giq33hTKeHEq6Jyk3btCny0Ycecyc3yGXH10sizUfiHlhviCkDuESk8mFDwDDzqW\n"
1257 "ZF0IipzFbEDHoIxLlm3GQxpiLoEV4k8KYJp3R5KBLFyxM6UGPz8h72mIPCJp2RuK\n"
1258 "MYgF91UDvVzvnYm6TfseM2+ewKirC00GOrZ7rEcFvtxnKSqYf4ckqfNdSU1Y+RRC\n"
1259 "1ngWZ7Ih\n"
1260 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001261 return BufferFromPEM(kCertPEM);
David Benjamin1444c3a2016-12-20 17:23:11 -05001262}
1263
Adam Langleyd04ca952017-02-28 11:26:51 -08001264static bssl::UniquePtr<X509> X509FromBuffer(
1265 bssl::UniquePtr<CRYPTO_BUFFER> buffer) {
1266 if (!buffer) {
1267 return nullptr;
1268 }
1269 const uint8_t *derp = CRYPTO_BUFFER_data(buffer.get());
1270 return bssl::UniquePtr<X509>(
1271 d2i_X509(NULL, &derp, CRYPTO_BUFFER_len(buffer.get())));
1272}
1273
1274static bssl::UniquePtr<X509> GetChainTestCertificate() {
1275 return X509FromBuffer(GetChainTestCertificateBuffer());
1276}
1277
1278static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestIntermediateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001279 static const char kCertPEM[] =
1280 "-----BEGIN CERTIFICATE-----\n"
1281 "MIICwjCCAaqgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS\n"
1282 "b290IENBMB4XDTE2MDIyODIwMjcwM1oXDTI2MDIyNTIwMjcwM1owDzENMAsGA1UE\n"
1283 "AwwEQiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALsSCYmDip2D\n"
1284 "GkjFxw7ykz26JSjELkl6ArlYjFJ3aT/SCh8qbS4gln7RH8CPBd78oFdfhIKQrwtZ\n"
1285 "3/q21ykD9BAS3qHe2YdcJfm8/kWAy5DvXk6NXU4qX334KofBAEpgdA/igEFq1P1l\n"
1286 "HAuIfZCpMRfT+i5WohVsGi8f/NgpRvVaMONLNfgw57mz1lbtFeBEISmX0kbsuJxF\n"
1287 "Qj/Bwhi5/0HAEXG8e7zN4cEx0yPRvmOATRdVb/8dW2pwOHRJq9R5M0NUkIsTSnL7\n"
1288 "6N/z8hRAHMsV3IudC5Yd7GXW1AGu9a+iKU+Q4xcZCoj0DC99tL4VKujrV1kAeqsM\n"
1289 "cz5/dKzi6+cCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
1290 "AQYwDQYJKoZIhvcNAQELBQADggEBAIIeZiEeNhWWQ8Y4D+AGDwqUUeG8NjCbKrXQ\n"
1291 "BlHg5wZ8xftFaiP1Dp/UAezmx2LNazdmuwrYB8lm3FVTyaPDTKEGIPS4wJKHgqH1\n"
1292 "QPDhqNm85ey7TEtI9oYjsNim/Rb+iGkIAMXaxt58SzxbjvP0kMr1JfJIZbic9vye\n"
1293 "NwIspMFIpP3FB8ywyu0T0hWtCQgL4J47nigCHpOu58deP88fS/Nyz/fyGVWOZ76b\n"
1294 "WhWwgM3P3X95fQ3d7oFPR/bVh0YV+Cf861INwplokXgXQ3/TCQ+HNXeAMWn3JLWv\n"
1295 "XFwk8owk9dq/kQGdndGgy3KTEW4ctPX5GNhf3LJ9Q7dLji4ReQ4=\n"
1296 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001297 return BufferFromPEM(kCertPEM);
1298}
1299
1300static bssl::UniquePtr<X509> GetChainTestIntermediate() {
1301 return X509FromBuffer(GetChainTestIntermediateBuffer());
David Benjamin1444c3a2016-12-20 17:23:11 -05001302}
1303
1304static bssl::UniquePtr<EVP_PKEY> GetChainTestKey() {
1305 static const char kKeyPEM[] =
1306 "-----BEGIN PRIVATE KEY-----\n"
1307 "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRvaz8CC/cshpC\n"
1308 "afJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/kLRcH89M\n"
1309 "/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3tHb+xs2P\n"
1310 "Ss8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+cIDs2rQ+l\n"
1311 "P7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1z7C8jU50\n"
1312 "Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9ViLeXANgZ\n"
1313 "i+Xx9KgfAgMBAAECggEBAK0VjSJzkyPaamcyTVSWjo7GdaBGcK60lk657RjR+lK0\n"
1314 "YJ7pkej4oM2hdsVZFsP8Cs4E33nXLa/0pDsRov/qrp0WQm2skwqGMC1I/bZ0WRPk\n"
1315 "wHaDrBBfESWnJDX/AGpVtlyOjPmgmK6J2usMPihQUDkKdAYrVWJePrMIxt1q6BMe\n"
1316 "iczs3qriMmtY3bUc4UyUwJ5fhDLjshHvfuIpYQyI6EXZM6dZksn9LylXJnigY6QJ\n"
1317 "HxOYO0BDwOsZ8yQ8J8afLk88i0GizEkgE1z3REtQUwgWfxr1WV/ud+T6/ZhSAgH9\n"
1318 "042mQvSFZnIUSEsmCvjhWuAunfxHKCTcAoYISWfzWpkCgYEA7gpf3HHU5Tn+CgUn\n"
1319 "1X5uGpG3DmcMgfeGgs2r2f/IIg/5Ac1dfYILiybL1tN9zbyLCJfcbFpWBc9hJL6f\n"
1320 "CPc5hUiwWFJqBJewxQkC1Ae/HakHbip+IZ+Jr0842O4BAArvixk4Lb7/N2Ct9sTE\n"
1321 "NJO6RtK9lbEZ5uK61DglHy8CS2UCgYEA4ZC1o36kPAMQBggajgnucb2yuUEelk0f\n"
1322 "AEr+GI32MGE+93xMr7rAhBoqLg4AITyIfEnOSQ5HwagnIHonBbv1LV/Gf9ursx8Z\n"
1323 "YOGbvT8zzzC+SU1bkDzdjAYnFQVGIjMtKOBJ3K07++ypwX1fr4QsQ8uKL8WSOWwt\n"
1324 "Z3Bym6XiZzMCgYADnhy+2OwHX85AkLt+PyGlPbmuelpyTzS4IDAQbBa6jcuW/2wA\n"
1325 "UE2km75VUXmD+u2R/9zVuLm99NzhFhSMqlUxdV1YukfqMfP5yp1EY6m/5aW7QuIP\n"
1326 "2MDa7TVL9rIFMiVZ09RKvbBbQxjhuzPQKL6X/PPspnhiTefQ+dl2k9xREQKBgHDS\n"
1327 "fMfGNEeAEKezrfSVqxphE9/tXms3L+ZpnCaT+yu/uEr5dTIAawKoQ6i9f/sf1/Sy\n"
1328 "xedsqR+IB+oKrzIDDWMgoJybN4pkZ8E5lzhVQIjFjKgFdWLzzqyW9z1gYfABQPlN\n"
1329 "FiS20WX0vgP1vcKAjdNrHzc9zyHBpgQzDmAj3NZZAoGBAI8vKCKdH7w3aL5CNkZQ\n"
1330 "2buIeWNA2HZazVwAGG5F2TU/LmXfRKnG6dX5bkU+AkBZh56jNZy//hfFSewJB4Kk\n"
1331 "buB7ERSdaNbO21zXt9FEA3+z0RfMd/Zv2vlIWOSB5nzl/7UKti3sribK6s9ZVLfi\n"
1332 "SxpiPQ8d/hmSGwn4ksrWUsJD\n"
1333 "-----END PRIVATE KEY-----\n";
1334 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1335 return bssl::UniquePtr<EVP_PKEY>(
1336 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1337}
1338
David Benjaminc79ae7a2017-08-29 16:09:44 -04001339// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
1340// before configuring as a server.
1341TEST(SSLTest, ClientCAList) {
1342 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1343 ASSERT_TRUE(ctx);
1344 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1345 ASSERT_TRUE(ssl);
1346
1347 bssl::UniquePtr<X509_NAME> name(X509_NAME_new());
1348 ASSERT_TRUE(name);
1349
1350 bssl::UniquePtr<X509_NAME> name_dup(X509_NAME_dup(name.get()));
1351 ASSERT_TRUE(name_dup);
1352
1353 bssl::UniquePtr<STACK_OF(X509_NAME)> stack(sk_X509_NAME_new_null());
1354 ASSERT_TRUE(stack);
David Benjamin2908dd12018-06-29 17:46:42 -04001355 ASSERT_TRUE(PushToStack(stack.get(), std::move(name_dup)));
David Benjaminc79ae7a2017-08-29 16:09:44 -04001356
1357 // |SSL_set_client_CA_list| takes ownership.
1358 SSL_set_client_CA_list(ssl.get(), stack.release());
1359
1360 STACK_OF(X509_NAME) *result = SSL_get_client_CA_list(ssl.get());
1361 ASSERT_TRUE(result);
1362 ASSERT_EQ(1u, sk_X509_NAME_num(result));
1363 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(result, 0), name.get()));
1364}
1365
1366TEST(SSLTest, AddClientCA) {
1367 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1368 ASSERT_TRUE(ctx);
1369 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1370 ASSERT_TRUE(ssl);
1371
1372 bssl::UniquePtr<X509> cert1 = GetTestCertificate();
1373 bssl::UniquePtr<X509> cert2 = GetChainTestCertificate();
1374 ASSERT_TRUE(cert1 && cert2);
1375 X509_NAME *name1 = X509_get_subject_name(cert1.get());
1376 X509_NAME *name2 = X509_get_subject_name(cert2.get());
1377
1378 EXPECT_EQ(0u, sk_X509_NAME_num(SSL_get_client_CA_list(ssl.get())));
1379
1380 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1381 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert2.get()));
1382
1383 STACK_OF(X509_NAME) *list = SSL_get_client_CA_list(ssl.get());
1384 ASSERT_EQ(2u, sk_X509_NAME_num(list));
1385 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1386 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1387
1388 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1389
1390 list = SSL_get_client_CA_list(ssl.get());
1391 ASSERT_EQ(3u, sk_X509_NAME_num(list));
1392 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1393 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1394 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 2), name1));
1395}
1396
1397static void AppendSession(SSL_SESSION *session, void *arg) {
1398 std::vector<SSL_SESSION*> *out =
1399 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
1400 out->push_back(session);
1401}
1402
1403// CacheEquals returns true if |ctx|'s session cache consists of |expected|, in
1404// order.
1405static bool CacheEquals(SSL_CTX *ctx,
1406 const std::vector<SSL_SESSION*> &expected) {
1407 // Check the linked list.
1408 SSL_SESSION *ptr = ctx->session_cache_head;
1409 for (SSL_SESSION *session : expected) {
1410 if (ptr != session) {
1411 return false;
1412 }
1413 // TODO(davidben): This is an absurd way to denote the end of the list.
1414 if (ptr->next ==
1415 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
1416 ptr = nullptr;
1417 } else {
1418 ptr = ptr->next;
1419 }
1420 }
1421 if (ptr != nullptr) {
1422 return false;
1423 }
1424
1425 // Check the hash table.
1426 std::vector<SSL_SESSION*> actual, expected_copy;
David Benjamin9eaa3bd2017-09-27 17:03:54 -04001427 lh_SSL_SESSION_doall_arg(ctx->sessions, AppendSession, &actual);
David Benjaminc79ae7a2017-08-29 16:09:44 -04001428 expected_copy = expected;
1429
1430 std::sort(actual.begin(), actual.end());
1431 std::sort(expected_copy.begin(), expected_copy.end());
1432
1433 return actual == expected_copy;
1434}
1435
1436static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
1437 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
1438 if (!ssl_ctx) {
1439 return nullptr;
1440 }
1441 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new(ssl_ctx.get()));
1442 if (!ret) {
1443 return nullptr;
1444 }
1445
David Benjaminaaef8332018-06-29 16:45:49 -04001446 uint8_t id[SSL3_SSL_SESSION_ID_LENGTH] = {0};
1447 OPENSSL_memcpy(id, &number, sizeof(number));
1448 if (!SSL_SESSION_set1_id(ret.get(), id, sizeof(id))) {
1449 return nullptr;
1450 }
David Benjaminc79ae7a2017-08-29 16:09:44 -04001451 return ret;
1452}
1453
1454// Test that the internal session cache behaves as expected.
1455TEST(SSLTest, InternalSessionCache) {
1456 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1457 ASSERT_TRUE(ctx);
1458
1459 // Prepare 10 test sessions.
1460 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
1461 for (int i = 0; i < 10; i++) {
1462 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
1463 ASSERT_TRUE(session);
1464 sessions.push_back(std::move(session));
1465 }
1466
1467 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1468
1469 // Insert all the test sessions.
1470 for (const auto &session : sessions) {
1471 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), session.get()));
1472 }
1473
1474 // Only the last five should be in the list.
1475 ASSERT_TRUE(CacheEquals(
1476 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
1477 sessions[6].get(), sessions[5].get()}));
1478
1479 // Inserting an element already in the cache should fail and leave the cache
1480 // unchanged.
1481 ASSERT_FALSE(SSL_CTX_add_session(ctx.get(), sessions[7].get()));
1482 ASSERT_TRUE(CacheEquals(
1483 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
1484 sessions[6].get(), sessions[5].get()}));
1485
1486 // Although collisions should be impossible (256-bit session IDs), the cache
1487 // must handle them gracefully.
1488 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
1489 ASSERT_TRUE(collision);
1490 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), collision.get()));
1491 ASSERT_TRUE(CacheEquals(
1492 ctx.get(), {collision.get(), sessions[9].get(), sessions[8].get(),
1493 sessions[6].get(), sessions[5].get()}));
1494
1495 // Removing sessions behaves correctly.
1496 ASSERT_TRUE(SSL_CTX_remove_session(ctx.get(), sessions[6].get()));
1497 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
1498 sessions[8].get(), sessions[5].get()}));
1499
1500 // Removing sessions requires an exact match.
1501 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[0].get()));
1502 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[7].get()));
1503
1504 // The cache remains unchanged.
1505 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
1506 sessions[8].get(), sessions[5].get()}));
1507}
1508
1509static uint16_t EpochFromSequence(uint64_t seq) {
1510 return static_cast<uint16_t>(seq >> 48);
1511}
1512
David Benjamin71dfad42017-07-16 17:27:39 -04001513static const uint8_t kTestName[] = {
1514 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
1515 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
1516 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
1517 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
1518 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
1519 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64,
1520};
1521
David Benjaminb79cc842016-12-07 15:57:14 -05001522static bool CompleteHandshakes(SSL *client, SSL *server) {
1523 // Drive both their handshakes to completion.
1524 for (;;) {
1525 int client_ret = SSL_do_handshake(client);
1526 int client_err = SSL_get_error(client, client_ret);
1527 if (client_err != SSL_ERROR_NONE &&
1528 client_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001529 client_err != SSL_ERROR_WANT_WRITE &&
1530 client_err != SSL_ERROR_PENDING_TICKET) {
David Benjaminb79cc842016-12-07 15:57:14 -05001531 fprintf(stderr, "Client error: %d\n", client_err);
1532 return false;
1533 }
1534
1535 int server_ret = SSL_do_handshake(server);
1536 int server_err = SSL_get_error(server, server_ret);
1537 if (server_err != SSL_ERROR_NONE &&
1538 server_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001539 server_err != SSL_ERROR_WANT_WRITE &&
1540 server_err != SSL_ERROR_PENDING_TICKET) {
David Benjaminb79cc842016-12-07 15:57:14 -05001541 fprintf(stderr, "Server error: %d\n", server_err);
1542 return false;
1543 }
1544
1545 if (client_ret == 1 && server_ret == 1) {
1546 break;
1547 }
1548 }
1549
1550 return true;
1551}
1552
David Benjamina8614602017-09-06 15:40:19 -04001553struct ClientConfig {
1554 SSL_SESSION *session = nullptr;
1555 std::string servername;
1556};
1557
David Benjaminb79cc842016-12-07 15:57:14 -05001558static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client,
1559 bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001560 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
Adam Langleyddb57cf2018-01-26 09:17:53 -08001561 const ClientConfig &config = ClientConfig(),
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001562 bool do_handshake = true,
1563 bool shed_handshake_config = true) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001564 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001565 if (!client || !server) {
1566 return false;
1567 }
1568 SSL_set_connect_state(client.get());
1569 SSL_set_accept_state(server.get());
1570
David Benjamina8614602017-09-06 15:40:19 -04001571 if (config.session) {
1572 SSL_set_session(client.get(), config.session);
1573 }
1574 if (!config.servername.empty() &&
1575 !SSL_set_tlsext_host_name(client.get(), config.servername.c_str())) {
1576 return false;
1577 }
David Benjamina20e5352016-08-02 19:09:41 -04001578
David Benjaminde942382016-02-11 12:02:01 -05001579 BIO *bio1, *bio2;
1580 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1581 return false;
1582 }
1583 // SSL_set_bio takes ownership.
1584 SSL_set_bio(client.get(), bio1, bio1);
1585 SSL_set_bio(server.get(), bio2, bio2);
1586
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001587 SSL_set_shed_handshake_config(client.get(), shed_handshake_config);
1588 SSL_set_shed_handshake_config(server.get(), shed_handshake_config);
1589
Adam Langleyddb57cf2018-01-26 09:17:53 -08001590 if (do_handshake && !CompleteHandshakes(client.get(), server.get())) {
David Benjaminb79cc842016-12-07 15:57:14 -05001591 return false;
David Benjaminde942382016-02-11 12:02:01 -05001592 }
1593
David Benjamin686bb192016-05-10 15:15:41 -04001594 *out_client = std::move(client);
1595 *out_server = std::move(server);
1596 return true;
1597}
1598
David Benjaminc11ea9422017-08-29 16:33:21 -04001599// SSLVersionTest executes its test cases under all available protocol versions.
1600// Test cases call |Connect| to create a connection using context objects with
1601// the protocol version fixed to the current version under test.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001602class SSLVersionTest : public ::testing::TestWithParam<VersionParam> {
1603 protected:
1604 SSLVersionTest() : cert_(GetTestCertificate()), key_(GetTestKey()) {}
1605
1606 void SetUp() { ResetContexts(); }
1607
1608 bssl::UniquePtr<SSL_CTX> CreateContext() const {
1609 const SSL_METHOD *method = is_dtls() ? DTLS_method() : TLS_method();
1610 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
1611 if (!ctx || !SSL_CTX_set_min_proto_version(ctx.get(), version()) ||
1612 !SSL_CTX_set_max_proto_version(ctx.get(), version())) {
1613 return nullptr;
1614 }
1615 return ctx;
David Benjamin0fef3052016-11-18 15:11:10 +09001616 }
David Benjamin686bb192016-05-10 15:15:41 -04001617
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001618 void ResetContexts() {
1619 ASSERT_TRUE(cert_);
1620 ASSERT_TRUE(key_);
1621 client_ctx_ = CreateContext();
1622 ASSERT_TRUE(client_ctx_);
1623 server_ctx_ = CreateContext();
1624 ASSERT_TRUE(server_ctx_);
1625 // Set up a server cert. Client certs can be set up explicitly.
1626 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09001627 }
David Benjamin686bb192016-05-10 15:15:41 -04001628
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001629 bool UseCertAndKey(SSL_CTX *ctx) const {
1630 return SSL_CTX_use_certificate(ctx, cert_.get()) &&
1631 SSL_CTX_use_PrivateKey(ctx, key_.get());
David Benjamin0fef3052016-11-18 15:11:10 +09001632 }
David Benjamin686bb192016-05-10 15:15:41 -04001633
David Benjamina8614602017-09-06 15:40:19 -04001634 bool Connect(const ClientConfig &config = ClientConfig()) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001635 return ConnectClientAndServer(&client_, &server_, client_ctx_.get(),
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001636 server_ctx_.get(), config, true,
1637 shed_handshake_config_);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001638 }
1639
1640 uint16_t version() const { return GetParam().version; }
1641
1642 bool is_dtls() const {
1643 return GetParam().ssl_method == VersionParam::is_dtls;
1644 }
1645
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001646 bool shed_handshake_config_ = true;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001647 bssl::UniquePtr<SSL> client_, server_;
1648 bssl::UniquePtr<SSL_CTX> server_ctx_, client_ctx_;
1649 bssl::UniquePtr<X509> cert_;
1650 bssl::UniquePtr<EVP_PKEY> key_;
1651};
1652
1653INSTANTIATE_TEST_CASE_P(WithVersion, SSLVersionTest,
1654 testing::ValuesIn(kAllVersions),
1655 [](const testing::TestParamInfo<VersionParam> &i) {
1656 return i.param.name;
1657 });
1658
1659TEST_P(SSLVersionTest, SequenceNumber) {
1660 ASSERT_TRUE(Connect());
1661
David Benjamin0fef3052016-11-18 15:11:10 +09001662 // Drain any post-handshake messages to ensure there are no unread records
1663 // on either end.
1664 uint8_t byte = 0;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001665 ASSERT_LE(SSL_read(client_.get(), &byte, 1), 0);
1666 ASSERT_LE(SSL_read(server_.get(), &byte, 1), 0);
David Benjaminde942382016-02-11 12:02:01 -05001667
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001668 uint64_t client_read_seq = SSL_get_read_sequence(client_.get());
1669 uint64_t client_write_seq = SSL_get_write_sequence(client_.get());
1670 uint64_t server_read_seq = SSL_get_read_sequence(server_.get());
1671 uint64_t server_write_seq = SSL_get_write_sequence(server_.get());
Steven Valdez2c62fe92016-10-14 12:08:12 -04001672
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001673 if (is_dtls()) {
David Benjamin0fef3052016-11-18 15:11:10 +09001674 // Both client and server must be at epoch 1.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001675 EXPECT_EQ(EpochFromSequence(client_read_seq), 1);
1676 EXPECT_EQ(EpochFromSequence(client_write_seq), 1);
1677 EXPECT_EQ(EpochFromSequence(server_read_seq), 1);
1678 EXPECT_EQ(EpochFromSequence(server_write_seq), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09001679
1680 // The next record to be written should exceed the largest received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001681 EXPECT_GT(client_write_seq, server_read_seq);
1682 EXPECT_GT(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09001683 } else {
1684 // The next record to be written should equal the next to be received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001685 EXPECT_EQ(client_write_seq, server_read_seq);
1686 EXPECT_EQ(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09001687 }
1688
1689 // Send a record from client to server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001690 EXPECT_EQ(SSL_write(client_.get(), &byte, 1), 1);
1691 EXPECT_EQ(SSL_read(server_.get(), &byte, 1), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09001692
1693 // The client write and server read sequence numbers should have
1694 // incremented.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001695 EXPECT_EQ(client_write_seq + 1, SSL_get_write_sequence(client_.get()));
1696 EXPECT_EQ(server_read_seq + 1, SSL_get_read_sequence(server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05001697}
1698
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001699TEST_P(SSLVersionTest, OneSidedShutdown) {
David Benjamin68f37b72016-11-18 15:14:42 +09001700 // SSL_shutdown is a no-op in DTLS.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001701 if (is_dtls()) {
1702 return;
David Benjamin686bb192016-05-10 15:15:41 -04001703 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001704 ASSERT_TRUE(Connect());
David Benjamin686bb192016-05-10 15:15:41 -04001705
1706 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1707 // one side has shut down.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001708 ASSERT_EQ(SSL_shutdown(client_.get()), 0);
David Benjamin686bb192016-05-10 15:15:41 -04001709
1710 // Reading from the server should consume the EOF.
1711 uint8_t byte;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001712 ASSERT_EQ(SSL_read(server_.get(), &byte, 1), 0);
1713 ASSERT_EQ(SSL_get_error(server_.get(), 0), SSL_ERROR_ZERO_RETURN);
David Benjamin686bb192016-05-10 15:15:41 -04001714
1715 // However, the server may continue to write data and then shut down the
1716 // connection.
1717 byte = 42;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001718 ASSERT_EQ(SSL_write(server_.get(), &byte, 1), 1);
1719 ASSERT_EQ(SSL_read(client_.get(), &byte, 1), 1);
1720 ASSERT_EQ(byte, 42);
David Benjamin686bb192016-05-10 15:15:41 -04001721
1722 // The server may then shutdown the connection.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001723 EXPECT_EQ(SSL_shutdown(server_.get()), 1);
1724 EXPECT_EQ(SSL_shutdown(client_.get()), 1);
David Benjamin686bb192016-05-10 15:15:41 -04001725}
David Benjamin68f37b72016-11-18 15:14:42 +09001726
David Benjaminf0d8e222017-02-04 10:58:26 -05001727TEST(SSLTest, SessionDuplication) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001728 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1729 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001730 ASSERT_TRUE(client_ctx);
1731 ASSERT_TRUE(server_ctx);
Steven Valdez87eab492016-06-27 16:34:59 -04001732
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001733 bssl::UniquePtr<X509> cert = GetTestCertificate();
1734 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminf0d8e222017-02-04 10:58:26 -05001735 ASSERT_TRUE(cert);
1736 ASSERT_TRUE(key);
1737 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
1738 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04001739
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001740 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05001741 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04001742 server_ctx.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04001743
1744 SSL_SESSION *session0 = SSL_get_session(client.get());
David Benjamin31b0c9b2017-07-20 14:49:15 -04001745 bssl::UniquePtr<SSL_SESSION> session1 =
1746 bssl::SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL);
David Benjaminf0d8e222017-02-04 10:58:26 -05001747 ASSERT_TRUE(session1);
David Benjamin4501bd52016-08-01 13:39:41 -04001748
David Benjamina3a71e92018-06-29 13:24:45 -04001749 session1->not_resumable = false;
Steven Valdez84b5c002016-08-25 16:30:58 -04001750
Steven Valdez87eab492016-06-27 16:34:59 -04001751 uint8_t *s0_bytes, *s1_bytes;
1752 size_t s0_len, s1_len;
1753
David Benjaminf0d8e222017-02-04 10:58:26 -05001754 ASSERT_TRUE(SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001755 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001756
David Benjaminf0d8e222017-02-04 10:58:26 -05001757 ASSERT_TRUE(SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001758 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001759
David Benjamin7d7554b2017-02-04 11:48:59 -05001760 EXPECT_EQ(Bytes(s0_bytes, s0_len), Bytes(s1_bytes, s1_len));
Steven Valdez87eab492016-06-27 16:34:59 -04001761}
David Benjamin686bb192016-05-10 15:15:41 -04001762
David Benjaminf0d8e222017-02-04 10:58:26 -05001763static void ExpectFDs(const SSL *ssl, int rfd, int wfd) {
David Benjaminca743582017-06-15 17:51:35 -04001764 EXPECT_EQ(rfd, SSL_get_fd(ssl));
David Benjaminf0d8e222017-02-04 10:58:26 -05001765 EXPECT_EQ(rfd, SSL_get_rfd(ssl));
1766 EXPECT_EQ(wfd, SSL_get_wfd(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04001767
1768 // The wrapper BIOs are always equal when fds are equal, even if set
1769 // individually.
David Benjaminf0d8e222017-02-04 10:58:26 -05001770 if (rfd == wfd) {
1771 EXPECT_EQ(SSL_get_rbio(ssl), SSL_get_wbio(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04001772 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001773}
1774
David Benjaminf0d8e222017-02-04 10:58:26 -05001775TEST(SSLTest, SetFD) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001776 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001777 ASSERT_TRUE(ctx);
David Benjamin5c0fb882016-06-14 14:03:51 -04001778
1779 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001780 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001781 ASSERT_TRUE(ssl);
1782 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1783 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
1784 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04001785
1786 // Test setting the same FD.
1787 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001788 ASSERT_TRUE(ssl);
1789 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1790 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001791
1792 // Test setting the same FD one side at a time.
1793 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001794 ASSERT_TRUE(ssl);
1795 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1796 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1797 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001798
1799 // Test setting the same FD in the other order.
1800 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001801 ASSERT_TRUE(ssl);
1802 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1803 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1804 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001805
David Benjamin5c0fb882016-06-14 14:03:51 -04001806 // Test changing the read FD partway through.
1807 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001808 ASSERT_TRUE(ssl);
1809 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1810 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 2));
1811 ExpectFDs(ssl.get(), 2, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001812
1813 // Test changing the write FD partway through.
1814 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001815 ASSERT_TRUE(ssl);
1816 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1817 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
1818 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04001819
1820 // Test a no-op change to the read FD partway through.
1821 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001822 ASSERT_TRUE(ssl);
1823 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1824 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1825 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001826
1827 // Test a no-op change to the write FD partway through.
1828 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001829 ASSERT_TRUE(ssl);
1830 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1831 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1832 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001833
1834 // ASan builds will implicitly test that the internal |BIO| reference-counting
1835 // is correct.
David Benjamin5c0fb882016-06-14 14:03:51 -04001836}
1837
David Benjaminf0d8e222017-02-04 10:58:26 -05001838TEST(SSLTest, SetBIO) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001839 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001840 ASSERT_TRUE(ctx);
David Benjamin4501bd52016-08-01 13:39:41 -04001841
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001842 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1843 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04001844 bio3(BIO_new(BIO_s_mem()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001845 ASSERT_TRUE(ssl);
1846 ASSERT_TRUE(bio1);
1847 ASSERT_TRUE(bio2);
1848 ASSERT_TRUE(bio3);
David Benjamin4501bd52016-08-01 13:39:41 -04001849
1850 // SSL_set_bio takes one reference when the parameters are the same.
1851 BIO_up_ref(bio1.get());
1852 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1853
1854 // Repeating the call does nothing.
1855 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1856
1857 // It takes one reference each when the parameters are different.
1858 BIO_up_ref(bio2.get());
1859 BIO_up_ref(bio3.get());
1860 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1861
1862 // Repeating the call does nothing.
1863 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1864
1865 // It takes one reference when changing only wbio.
1866 BIO_up_ref(bio1.get());
1867 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1868
1869 // It takes one reference when changing only rbio and the two are different.
1870 BIO_up_ref(bio3.get());
1871 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1872
1873 // If setting wbio to rbio, it takes no additional references.
1874 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1875
1876 // From there, wbio may be switched to something else.
1877 BIO_up_ref(bio1.get());
1878 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1879
1880 // If setting rbio to wbio, it takes no additional references.
1881 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1882
1883 // From there, rbio may be switched to something else, but, for historical
1884 // reasons, it takes a reference to both parameters.
1885 BIO_up_ref(bio1.get());
1886 BIO_up_ref(bio2.get());
1887 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1888
1889 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1890 // is correct.
David Benjamin4501bd52016-08-01 13:39:41 -04001891}
1892
David Benjamin25490f22016-07-14 00:22:54 -04001893static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1894
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001895TEST_P(SSLVersionTest, GetPeerCertificate) {
1896 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04001897
David Benjamin0fef3052016-11-18 15:11:10 +09001898 // Configure both client and server to accept any certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001899 SSL_CTX_set_verify(client_ctx_.get(),
1900 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1901 nullptr);
1902 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
1903 SSL_CTX_set_verify(server_ctx_.get(),
1904 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1905 nullptr);
1906 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjaminadd5e522016-07-14 00:33:24 -04001907
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001908 ASSERT_TRUE(Connect());
David Benjaminadd5e522016-07-14 00:33:24 -04001909
David Benjamin0fef3052016-11-18 15:11:10 +09001910 // Client and server should both see the leaf certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001911 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1912 ASSERT_TRUE(peer);
1913 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04001914
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001915 peer.reset(SSL_get_peer_certificate(client_.get()));
1916 ASSERT_TRUE(peer);
1917 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04001918
David Benjamine664a532017-07-20 20:19:36 -04001919 // However, for historical reasons, the X509 chain includes the leaf on the
David Benjamin0fef3052016-11-18 15:11:10 +09001920 // client, but does not on the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001921 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(client_.get())), 1u);
1922 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(client_.get())),
1923 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04001924
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001925 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(server_.get())), 0u);
1926 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(server_.get())),
1927 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04001928}
1929
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001930TEST_P(SSLVersionTest, NoPeerCertificate) {
1931 SSL_CTX_set_verify(server_ctx_.get(), SSL_VERIFY_PEER, nullptr);
1932 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
1933 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
David Benjamine664a532017-07-20 20:19:36 -04001934
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001935 ASSERT_TRUE(Connect());
David Benjamine664a532017-07-20 20:19:36 -04001936
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001937 // Server should not see a peer certificate.
1938 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1939 ASSERT_FALSE(peer);
1940 ASSERT_FALSE(SSL_get0_peer_certificates(server_.get()));
David Benjamine664a532017-07-20 20:19:36 -04001941}
1942
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001943TEST_P(SSLVersionTest, RetainOnlySHA256OfCerts) {
David Benjamin25490f22016-07-14 00:22:54 -04001944 uint8_t *cert_der = NULL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001945 int cert_der_len = i2d_X509(cert_.get(), &cert_der);
1946 ASSERT_GE(cert_der_len, 0);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001947 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04001948
1949 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1950 SHA256(cert_der, cert_der_len, cert_sha256);
1951
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001952 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
1953
David Benjamin0fef3052016-11-18 15:11:10 +09001954 // Configure both client and server to accept any certificate, but the
1955 // server must retain only the SHA-256 of the peer.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001956 SSL_CTX_set_verify(client_ctx_.get(),
1957 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1958 nullptr);
1959 SSL_CTX_set_verify(server_ctx_.get(),
1960 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1961 nullptr);
1962 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
1963 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
1964 SSL_CTX_set_retain_only_sha256_of_client_certs(server_ctx_.get(), 1);
David Benjamin25490f22016-07-14 00:22:54 -04001965
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001966 ASSERT_TRUE(Connect());
David Benjamin25490f22016-07-14 00:22:54 -04001967
David Benjamin0fef3052016-11-18 15:11:10 +09001968 // The peer certificate has been dropped.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001969 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1970 EXPECT_FALSE(peer);
David Benjamin25490f22016-07-14 00:22:54 -04001971
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001972 SSL_SESSION *session = SSL_get_session(server_.get());
David Benjamin02de7bd2018-05-08 18:13:54 -04001973 EXPECT_TRUE(SSL_SESSION_has_peer_sha256(session));
David Benjamin25490f22016-07-14 00:22:54 -04001974
David Benjamin02de7bd2018-05-08 18:13:54 -04001975 const uint8_t *peer_sha256;
1976 size_t peer_sha256_len;
1977 SSL_SESSION_get0_peer_sha256(session, &peer_sha256, &peer_sha256_len);
1978 EXPECT_EQ(Bytes(cert_sha256), Bytes(peer_sha256, peer_sha256_len));
David Benjamin25490f22016-07-14 00:22:54 -04001979}
1980
David Benjamin737d2df2017-09-25 15:05:19 -04001981// Tests that our ClientHellos do not change unexpectedly. These are purely
1982// change detection tests. If they fail as part of an intentional ClientHello
1983// change, update the test vector.
1984TEST(SSLTest, ClientHello) {
1985 struct {
1986 uint16_t max_version;
1987 std::vector<uint8_t> expected;
1988 } kTests[] = {
David Benjamin737d2df2017-09-25 15:05:19 -04001989 {TLS1_VERSION,
1990 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x01, 0x00,
1991 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1992 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1993 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
1994 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
Adam Langleyd6680952018-08-23 08:01:23 -07001995 0x01, 0x00, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01,
1996 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
1997 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
David Benjamin737d2df2017-09-25 15:05:19 -04001998 {TLS1_1_VERSION,
1999 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x02, 0x00,
2000 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2001 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2002 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
2003 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
Adam Langleyd6680952018-08-23 08:01:23 -07002004 0x01, 0x00, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01,
2005 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
2006 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
David Benjamin737d2df2017-09-25 15:05:19 -04002007 {TLS1_2_VERSION,
David Benjamin6e678ee2018-04-16 19:54:42 -04002008 {0x16, 0x03, 0x01, 0x00, 0x82, 0x01, 0x00, 0x00, 0x7e, 0x03, 0x03, 0x00,
David Benjamin737d2df2017-09-25 15:05:19 -04002009 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2010 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
David Benjamin6e678ee2018-04-16 19:54:42 -04002011 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xcc, 0xa9,
David Benjamin737d2df2017-09-25 15:05:19 -04002012 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xc0, 0x09,
David Benjamin6e678ee2018-04-16 19:54:42 -04002013 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
Adam Langleyd6680952018-08-23 08:01:23 -07002014 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37, 0x00, 0x17, 0x00, 0x00,
2015 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00,
2016 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
2017 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04, 0x03, 0x08,
2018 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06,
2019 0x01, 0x02, 0x01}},
David Benjamin737d2df2017-09-25 15:05:19 -04002020 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
2021 // implementation has settled enough that it won't change.
David Benjaminafc64de2016-07-19 17:12:41 +02002022 };
David Benjamin737d2df2017-09-25 15:05:19 -04002023
2024 for (const auto &t : kTests) {
2025 SCOPED_TRACE(t.max_version);
2026
2027 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2028 ASSERT_TRUE(ctx);
2029 // Our default cipher list varies by CPU capabilities, so manually place the
2030 // ChaCha20 ciphers in front.
2031 const char *cipher_list = "CHACHA20:ALL";
David Benjamin737d2df2017-09-25 15:05:19 -04002032 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), t.max_version));
2033 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list));
2034
2035 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
2036 ASSERT_TRUE(ssl);
2037 std::vector<uint8_t> client_hello;
2038 ASSERT_TRUE(GetClientHello(ssl.get(), &client_hello));
2039
2040 // Zero the client_random.
2041 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
2042 1 + 3 + // handshake message header
2043 2; // client_version
2044 ASSERT_GE(client_hello.size(), kRandomOffset + SSL3_RANDOM_SIZE);
2045 OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
2046
2047 if (client_hello != t.expected) {
2048 ADD_FAILURE() << "ClientHellos did not match.";
2049 // Print the value manually so it is easier to update the test vector.
2050 for (size_t i = 0; i < client_hello.size(); i += 12) {
2051 printf(" %c", i == 0 ? '{' : ' ');
2052 for (size_t j = i; j < client_hello.size() && j < i + 12; j++) {
2053 if (j > i) {
2054 printf(" ");
2055 }
2056 printf("0x%02x", client_hello[j]);
2057 if (j < client_hello.size() - 1) {
2058 printf(",");
2059 }
2060 }
2061 if (i + 12 >= client_hello.size()) {
Adam Langleyd6680952018-08-23 08:01:23 -07002062 printf("}},");
David Benjamin737d2df2017-09-25 15:05:19 -04002063 }
2064 printf("\n");
2065 }
2066 }
David Benjaminafc64de2016-07-19 17:12:41 +02002067 }
David Benjaminafc64de2016-07-19 17:12:41 +02002068}
2069
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002070static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04002071
2072static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
2073 // Save the most recent session.
2074 g_last_session.reset(session);
2075 return 1;
2076}
2077
David Benjamina8614602017-09-06 15:40:19 -04002078static bssl::UniquePtr<SSL_SESSION> CreateClientSession(
2079 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2080 const ClientConfig &config = ClientConfig()) {
David Benjamina20e5352016-08-02 19:09:41 -04002081 g_last_session = nullptr;
2082 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2083
2084 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002085 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04002086 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
David Benjamina8614602017-09-06 15:40:19 -04002087 config)) {
David Benjamina20e5352016-08-02 19:09:41 -04002088 fprintf(stderr, "Failed to connect client and server.\n");
2089 return nullptr;
2090 }
2091
2092 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2093 SSL_read(client.get(), nullptr, 0);
2094
2095 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2096
2097 if (!g_last_session) {
2098 fprintf(stderr, "Client did not receive a session.\n");
2099 return nullptr;
2100 }
2101 return std::move(g_last_session);
2102}
2103
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002104static void ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2105 SSL_SESSION *session, bool want_reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002106 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002107 ClientConfig config;
2108 config.session = session;
2109 EXPECT_TRUE(
2110 ConnectClientAndServer(&client, &server, client_ctx, server_ctx, config));
David Benjamina20e5352016-08-02 19:09:41 -04002111
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002112 EXPECT_EQ(SSL_session_reused(client.get()), SSL_session_reused(server.get()));
David Benjamina20e5352016-08-02 19:09:41 -04002113
2114 bool was_reused = !!SSL_session_reused(client.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002115 EXPECT_EQ(was_reused, want_reused);
David Benjamina20e5352016-08-02 19:09:41 -04002116}
2117
David Benjamin3c51d9b2016-11-01 17:50:42 -04002118static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
2119 SSL_CTX *server_ctx,
2120 SSL_SESSION *session) {
2121 g_last_session = nullptr;
2122 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2123
2124 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002125 ClientConfig config;
2126 config.session = session;
2127 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
2128 config)) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002129 fprintf(stderr, "Failed to connect client and server.\n");
2130 return nullptr;
2131 }
2132
2133 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2134 fprintf(stderr, "Client and server were inconsistent.\n");
2135 return nullptr;
2136 }
2137
2138 if (!SSL_session_reused(client.get())) {
2139 fprintf(stderr, "Session was not reused.\n");
2140 return nullptr;
2141 }
2142
2143 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2144 SSL_read(client.get(), nullptr, 0);
2145
2146 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2147
2148 if (!g_last_session) {
2149 fprintf(stderr, "Client did not receive a renewed session.\n");
2150 return nullptr;
2151 }
2152 return std::move(g_last_session);
2153}
2154
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002155static void ExpectTicketKeyChanged(SSL_CTX *ctx, uint8_t *inout_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002156 bool changed) {
2157 uint8_t new_key[kTicketKeyLen];
David Benjaminc11ea9422017-08-29 16:33:21 -04002158 // May return 0, 1 or 48.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002159 ASSERT_EQ(SSL_CTX_get_tlsext_ticket_keys(ctx, new_key, kTicketKeyLen), 1);
2160 if (changed) {
2161 ASSERT_NE(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
2162 } else {
2163 ASSERT_EQ(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002164 }
2165 OPENSSL_memcpy(inout_key, new_key, kTicketKeyLen);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002166}
2167
David Benjamina933c382016-10-28 00:10:03 -04002168static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
2169 static const uint8_t kContext[] = {3};
2170
2171 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
2172 return SSL_TLSEXT_ERR_ALERT_FATAL;
2173 }
2174
2175 return SSL_TLSEXT_ERR_OK;
2176}
2177
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002178TEST_P(SSLVersionTest, SessionIDContext) {
David Benjamina20e5352016-08-02 19:09:41 -04002179 static const uint8_t kContext1[] = {1};
2180 static const uint8_t kContext2[] = {2};
2181
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002182 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2183 sizeof(kContext1)));
David Benjamina20e5352016-08-02 19:09:41 -04002184
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002185 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2186 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002187
David Benjamin0fef3052016-11-18 15:11:10 +09002188 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002189 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2190 ASSERT_TRUE(session);
David Benjamina20e5352016-08-02 19:09:41 -04002191
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002192 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2193 session.get(),
2194 true /* expect session reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002195
David Benjamin0fef3052016-11-18 15:11:10 +09002196 // Change the session ID context.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002197 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext2,
2198 sizeof(kContext2)));
David Benjamina20e5352016-08-02 19:09:41 -04002199
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002200 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2201 session.get(),
2202 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002203
David Benjamin0fef3052016-11-18 15:11:10 +09002204 // Change the session ID context back and install an SNI callback to switch
2205 // it.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002206 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2207 sizeof(kContext1)));
David Benjamina933c382016-10-28 00:10:03 -04002208
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002209 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09002210 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04002211
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002212 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2213 session.get(),
2214 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002215
David Benjamin0fef3052016-11-18 15:11:10 +09002216 // Switch the session ID context with the early callback instead.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002217 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), nullptr);
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002218 SSL_CTX_set_select_certificate_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002219 server_ctx_.get(),
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002220 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
2221 static const uint8_t kContext[] = {3};
2222
2223 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
2224 sizeof(kContext))) {
2225 return ssl_select_cert_error;
2226 }
2227
2228 return ssl_select_cert_success;
2229 });
David Benjamina933c382016-10-28 00:10:03 -04002230
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002231 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2232 session.get(),
2233 false /* expect session not reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002234}
2235
David Benjamin721e8b72016-08-03 13:13:17 -04002236static timeval g_current_time;
2237
2238static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2239 *out_clock = g_current_time;
2240}
2241
David Benjamin17b30832017-01-28 14:00:32 -05002242static void FrozenTimeCallback(const SSL *ssl, timeval *out_clock) {
2243 out_clock->tv_sec = 1000;
2244 out_clock->tv_usec = 0;
2245}
2246
David Benjamin3c51d9b2016-11-01 17:50:42 -04002247static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
2248 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
2249 int encrypt) {
2250 static const uint8_t kZeros[16] = {0};
2251
2252 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -05002253 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamin3c51d9b2016-11-01 17:50:42 -04002254 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -05002255 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002256 return 0;
2257 }
2258
2259 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
2260 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
2261 return -1;
2262 }
2263
2264 // Returning two from the callback in decrypt mode renews the
2265 // session in TLS 1.2 and below.
2266 return encrypt ? 1 : 2;
2267}
2268
David Benjamin123db572016-11-03 16:59:25 -04002269static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjaminaaef8332018-06-29 16:45:49 -04002270 const uint8_t *ticket;
2271 size_t ticket_len;
2272 SSL_SESSION_get0_ticket(session, &ticket, &ticket_len);
2273 if (ticket_len < 16 + 16 + SHA256_DIGEST_LENGTH) {
David Benjamin123db572016-11-03 16:59:25 -04002274 return false;
2275 }
2276
David Benjaminaaef8332018-06-29 16:45:49 -04002277 const uint8_t *ciphertext = ticket + 16 + 16;
2278 size_t len = ticket_len - 16 - 16 - SHA256_DIGEST_LENGTH;
David Benjamin123db572016-11-03 16:59:25 -04002279 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
2280
David Benjamin9b63f292016-11-15 00:44:05 -05002281#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
2282 // Fuzzer-mode tickets are unencrypted.
David Benjamin17cf2cb2016-12-13 01:07:13 -05002283 OPENSSL_memcpy(plaintext.get(), ciphertext, len);
David Benjamin9b63f292016-11-15 00:44:05 -05002284#else
2285 static const uint8_t kZeros[16] = {0};
David Benjaminaaef8332018-06-29 16:45:49 -04002286 const uint8_t *iv = ticket + 16;
David Benjamin123db572016-11-03 16:59:25 -04002287 bssl::ScopedEVP_CIPHER_CTX ctx;
2288 int len1, len2;
2289 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
2290 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
2291 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
2292 return false;
2293 }
2294
2295 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05002296#endif
David Benjamin123db572016-11-03 16:59:25 -04002297
Adam Langley46db7af2017-02-01 15:49:37 -08002298 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
2299 if (!ssl_ctx) {
2300 return false;
2301 }
David Benjamin123db572016-11-03 16:59:25 -04002302 bssl::UniquePtr<SSL_SESSION> server_session(
Adam Langley46db7af2017-02-01 15:49:37 -08002303 SSL_SESSION_from_bytes(plaintext.get(), len, ssl_ctx.get()));
David Benjamin123db572016-11-03 16:59:25 -04002304 if (!server_session) {
2305 return false;
2306 }
2307
David Benjaminaaef8332018-06-29 16:45:49 -04002308 *out = SSL_SESSION_get_time(server_session.get());
David Benjamin123db572016-11-03 16:59:25 -04002309 return true;
2310}
2311
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002312TEST_P(SSLVersionTest, SessionTimeout) {
2313 for (bool server_test : {false, true}) {
2314 SCOPED_TRACE(server_test);
David Benjamin721e8b72016-08-03 13:13:17 -04002315
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002316 ResetContexts();
2317 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2318 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
2319
David Benjamin17b30832017-01-28 14:00:32 -05002320 static const time_t kStartTime = 1000;
David Benjamin0fef3052016-11-18 15:11:10 +09002321 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002322
David Benjamin17b30832017-01-28 14:00:32 -05002323 // We are willing to use a longer lifetime for TLS 1.3 sessions as
2324 // resumptions still perform ECDHE.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002325 const time_t timeout = version() == TLS1_3_VERSION
David Benjamin17b30832017-01-28 14:00:32 -05002326 ? SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT
2327 : SSL_DEFAULT_SESSION_TIMEOUT;
2328
David Benjamin17b30832017-01-28 14:00:32 -05002329 // Both client and server must enforce session timeouts. We configure the
2330 // other side with a frozen clock so it never expires tickets.
David Benjamin0fef3052016-11-18 15:11:10 +09002331 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002332 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2333 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002334 } else {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002335 SSL_CTX_set_current_time_cb(client_ctx_.get(), CurrentTimeCallback);
2336 SSL_CTX_set_current_time_cb(server_ctx_.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002337 }
2338
2339 // Configure a ticket callback which renews tickets.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002340 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002341
2342 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002343 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2344 ASSERT_TRUE(session);
David Benjamin0fef3052016-11-18 15:11:10 +09002345
2346 // Advance the clock just behind the timeout.
David Benjamin17b30832017-01-28 14:00:32 -05002347 g_current_time.tv_sec += timeout - 1;
David Benjamin0fef3052016-11-18 15:11:10 +09002348
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002349 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2350 session.get(),
2351 true /* expect session reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002352
2353 // Advance the clock one more second.
2354 g_current_time.tv_sec++;
2355
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002356 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2357 session.get(),
2358 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002359
2360 // Rewind the clock to before the session was minted.
2361 g_current_time.tv_sec = kStartTime - 1;
2362
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002363 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2364 session.get(),
2365 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002366
David Benjamin0fef3052016-11-18 15:11:10 +09002367 // Renew the session 10 seconds before expiration.
David Benjamin17b30832017-01-28 14:00:32 -05002368 time_t new_start_time = kStartTime + timeout - 10;
2369 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002370 bssl::UniquePtr<SSL_SESSION> new_session = ExpectSessionRenewed(
2371 client_ctx_.get(), server_ctx_.get(), session.get());
2372 ASSERT_TRUE(new_session);
David Benjamin0fef3052016-11-18 15:11:10 +09002373
2374 // This new session is not the same object as before.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002375 EXPECT_NE(session.get(), new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002376
2377 // Check the sessions have timestamps measured from issuance.
2378 long session_time = 0;
2379 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002380 ASSERT_TRUE(GetServerTicketTime(&session_time, new_session.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09002381 } else {
David Benjaminaaef8332018-06-29 16:45:49 -04002382 session_time = SSL_SESSION_get_time(new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002383 }
David Benjamin721e8b72016-08-03 13:13:17 -04002384
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002385 ASSERT_EQ(session_time, g_current_time.tv_sec);
David Benjamin721e8b72016-08-03 13:13:17 -04002386
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002387 if (version() == TLS1_3_VERSION) {
David Benjamin17b30832017-01-28 14:00:32 -05002388 // Renewal incorporates fresh key material in TLS 1.3, so we extend the
2389 // lifetime TLS 1.3.
2390 g_current_time.tv_sec = new_start_time + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002391 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2392 new_session.get(),
2393 true /* expect session reused */));
David Benjamin721e8b72016-08-03 13:13:17 -04002394
David Benjamin17b30832017-01-28 14:00:32 -05002395 // The new session expires after the new timeout.
2396 g_current_time.tv_sec = new_start_time + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002397 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2398 new_session.get(),
2399 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002400
2401 // Renew the session until it begins just past the auth timeout.
2402 time_t auth_end_time = kStartTime + SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
2403 while (new_start_time < auth_end_time - 1000) {
2404 // Get as close as possible to target start time.
2405 new_start_time =
2406 std::min(auth_end_time - 1000, new_start_time + timeout - 1);
2407 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002408 new_session = ExpectSessionRenewed(client_ctx_.get(), server_ctx_.get(),
David Benjamin17b30832017-01-28 14:00:32 -05002409 new_session.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002410 ASSERT_TRUE(new_session);
David Benjamin17b30832017-01-28 14:00:32 -05002411 }
2412
2413 // Now the session's lifetime is bound by the auth timeout.
2414 g_current_time.tv_sec = auth_end_time - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002415 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2416 new_session.get(),
2417 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002418
2419 g_current_time.tv_sec = auth_end_time + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002420 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2421 new_session.get(),
2422 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002423 } else {
2424 // The new session is usable just before the old expiration.
2425 g_current_time.tv_sec = kStartTime + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002426 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2427 new_session.get(),
2428 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002429
2430 // Renewal does not extend the lifetime, so it is not usable beyond the
2431 // old expiration.
2432 g_current_time.tv_sec = kStartTime + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002433 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2434 new_session.get(),
2435 false /* expect session not reused */));
David Benjamin1b22f852016-10-27 16:36:32 -04002436 }
David Benjamin721e8b72016-08-03 13:13:17 -04002437 }
David Benjamin721e8b72016-08-03 13:13:17 -04002438}
2439
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002440TEST_P(SSLVersionTest, DefaultTicketKeyInitialization) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002441 static const uint8_t kZeroKey[kTicketKeyLen] = {};
2442 uint8_t ticket_key[kTicketKeyLen];
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002443 ASSERT_EQ(1, SSL_CTX_get_tlsext_ticket_keys(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002444 kTicketKeyLen));
2445 ASSERT_NE(0, OPENSSL_memcmp(ticket_key, kZeroKey, kTicketKeyLen));
2446}
2447
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002448TEST_P(SSLVersionTest, DefaultTicketKeyRotation) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002449 static const time_t kStartTime = 1001;
2450 g_current_time.tv_sec = kStartTime;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002451
David Benjaminc11ea9422017-08-29 16:33:21 -04002452 // We use session reuse as a proxy for ticket decryption success, hence
2453 // disable session timeouts.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002454 SSL_CTX_set_timeout(server_ctx_.get(), std::numeric_limits<uint32_t>::max());
2455 SSL_CTX_set_session_psk_dhe_timeout(server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002456 std::numeric_limits<uint32_t>::max());
2457
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002458 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2459 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002460
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002461 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2462 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_OFF);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002463
David Benjamin1f0d54b2018-08-09 16:19:13 -05002464 // Initialize ticket_key with the current key and check that it was
2465 // initialized to something, not all zeros.
2466 uint8_t ticket_key[kTicketKeyLen] = {0};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002467 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2468 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002469
David Benjaminc11ea9422017-08-29 16:33:21 -04002470 // Verify ticket resumption actually works.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002471 bssl::UniquePtr<SSL> client, server;
2472 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002473 CreateClientSession(client_ctx_.get(), server_ctx_.get());
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002474 ASSERT_TRUE(session);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002475 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002476 session.get(), true /* reused */));
2477
David Benjaminc11ea9422017-08-29 16:33:21 -04002478 // Advance time to just before key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002479 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002480 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002481 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002482 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002483 false /* NOT changed */));
2484
David Benjaminc11ea9422017-08-29 16:33:21 -04002485 // Force key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002486 g_current_time.tv_sec += 1;
2487 bssl::UniquePtr<SSL_SESSION> new_session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002488 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2489 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2490 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002491
David Benjaminc11ea9422017-08-29 16:33:21 -04002492 // Resumption with both old and new ticket should work.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002493 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002494 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002495 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002496 new_session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002497 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002498 false /* NOT changed */));
2499
David Benjaminc11ea9422017-08-29 16:33:21 -04002500 // Force key rotation again. Resumption with the old ticket now fails.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002501 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002502 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002503 session.get(), false /* NOT reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002504 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2505 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002506
David Benjaminc11ea9422017-08-29 16:33:21 -04002507 // But resumption with the newer session still works.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002508 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002509 new_session.get(), true /* reused */));
2510}
2511
David Benjamin0fc37ef2016-08-17 15:29:46 -04002512static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002513 SSL_CTX *ctx = reinterpret_cast<SSL_CTX *>(arg);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002514 SSL_set_SSL_CTX(ssl, ctx);
2515 return SSL_TLSEXT_ERR_OK;
2516}
2517
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002518TEST_P(SSLVersionTest, SNICallback) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002519 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002520 ASSERT_TRUE(cert2);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002521 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002522 ASSERT_TRUE(key2);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002523
David Benjamin0fef3052016-11-18 15:11:10 +09002524 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
2525 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002526
David Benjamin83a32122017-02-14 18:34:54 -05002527 static const uint8_t kSCTList[] = {0, 6, 0, 4, 5, 6, 7, 8};
2528 static const uint8_t kOCSPResponse[] = {1, 2, 3, 4};
2529
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002530 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
2531 ASSERT_TRUE(server_ctx2);
2532 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()));
2533 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()));
2534 ASSERT_TRUE(SSL_CTX_set_signed_cert_timestamp_list(
2535 server_ctx2.get(), kSCTList, sizeof(kSCTList)));
2536 ASSERT_TRUE(SSL_CTX_set_ocsp_response(server_ctx2.get(), kOCSPResponse,
2537 sizeof(kOCSPResponse)));
2538 // Historically signing preferences would be lost in some cases with the
2539 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2540 // this doesn't happen when |version| is TLS 1.2, configure the private
2541 // key to only sign SHA-256.
2542 ASSERT_TRUE(SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
2543 &kECDSAWithSHA256, 1));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002544
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002545 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), SwitchContext);
2546 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002547
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002548 SSL_CTX_enable_signed_cert_timestamps(client_ctx_.get());
2549 SSL_CTX_enable_ocsp_stapling(client_ctx_.get());
David Benjamin83a32122017-02-14 18:34:54 -05002550
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002551 ASSERT_TRUE(Connect());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002552
David Benjamin0fef3052016-11-18 15:11:10 +09002553 // The client should have received |cert2|.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002554 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client_.get()));
2555 ASSERT_TRUE(peer);
2556 EXPECT_EQ(X509_cmp(peer.get(), cert2.get()), 0);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002557
David Benjamin83a32122017-02-14 18:34:54 -05002558 // The client should have received |server_ctx2|'s SCT list.
2559 const uint8_t *data;
2560 size_t len;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002561 SSL_get0_signed_cert_timestamp_list(client_.get(), &data, &len);
2562 EXPECT_EQ(Bytes(kSCTList), Bytes(data, len));
David Benjamin83a32122017-02-14 18:34:54 -05002563
2564 // The client should have received |server_ctx2|'s OCSP response.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002565 SSL_get0_ocsp_response(client_.get(), &data, &len);
2566 EXPECT_EQ(Bytes(kOCSPResponse), Bytes(data, len));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002567}
2568
David Benjaminf0d8e222017-02-04 10:58:26 -05002569// Test that the early callback can swap the maximum version.
2570TEST(SSLTest, EarlyCallbackVersionSwitch) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002571 bssl::UniquePtr<X509> cert = GetTestCertificate();
2572 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2573 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2574 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002575 ASSERT_TRUE(cert);
2576 ASSERT_TRUE(key);
2577 ASSERT_TRUE(server_ctx);
2578 ASSERT_TRUE(client_ctx);
2579 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
2580 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
2581 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
2582 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
David Benjamin99620572016-08-30 00:35:36 -04002583
David Benjaminf0d8e222017-02-04 10:58:26 -05002584 SSL_CTX_set_select_certificate_cb(
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002585 server_ctx.get(),
2586 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
David Benjaminf0d8e222017-02-04 10:58:26 -05002587 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002588 return ssl_select_cert_error;
David Benjaminf0d8e222017-02-04 10:58:26 -05002589 }
2590
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002591 return ssl_select_cert_success;
David Benjaminf0d8e222017-02-04 10:58:26 -05002592 });
David Benjamin99620572016-08-30 00:35:36 -04002593
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002594 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05002595 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04002596 server_ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002597 EXPECT_EQ(TLS1_2_VERSION, SSL_version(client.get()));
David Benjamin99620572016-08-30 00:35:36 -04002598}
2599
David Benjaminf0d8e222017-02-04 10:58:26 -05002600TEST(SSLTest, SetVersion) {
David Benjamin2dc02042016-09-19 19:57:37 -04002601 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002602 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002603
David Benjaminf0d8e222017-02-04 10:58:26 -05002604 // Set valid TLS versions.
2605 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2606 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
2607 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2608 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002609
David Benjaminf0d8e222017-02-04 10:58:26 -05002610 // Invalid TLS versions are rejected.
2611 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2612 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x0200));
2613 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2614 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2615 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x0200));
2616 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002617
David Benjaminf0d8e222017-02-04 10:58:26 -05002618 // Zero is the default version.
2619 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002620 EXPECT_EQ(TLS1_2_VERSION, ctx->conf_max_version);
David Benjaminf0d8e222017-02-04 10:58:26 -05002621 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002622 EXPECT_EQ(TLS1_VERSION, ctx->conf_min_version);
David Benjamin3cfeb952017-03-01 16:48:38 -05002623
David Benjamin9bb15f52018-06-26 00:07:40 -04002624 // TLS 1.3 is available, but not by default.
David Benjamin3cfeb952017-03-01 16:48:38 -05002625 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002626 EXPECT_EQ(TLS1_3_VERSION, ctx->conf_max_version);
David Benjamine34bcc92016-09-21 16:53:09 -04002627
David Benjamin9bb15f52018-06-26 00:07:40 -04002628 // SSL 3.0 is not available.
2629 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION));
2630
David Benjamin2dc02042016-09-19 19:57:37 -04002631 ctx.reset(SSL_CTX_new(DTLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002632 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002633
David Benjaminf0d8e222017-02-04 10:58:26 -05002634 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2635 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION));
2636 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2637 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002638
David Benjaminf0d8e222017-02-04 10:58:26 -05002639 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2640 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2641 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2642 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2643 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2644 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2645 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2646 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002647
David Benjaminf0d8e222017-02-04 10:58:26 -05002648 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002649 EXPECT_EQ(TLS1_2_VERSION, ctx->conf_max_version);
David Benjaminf0d8e222017-02-04 10:58:26 -05002650 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002651 EXPECT_EQ(TLS1_1_VERSION, ctx->conf_min_version);
David Benjamin2dc02042016-09-19 19:57:37 -04002652}
2653
David Benjamin458334a2016-12-15 13:53:25 -05002654static const char *GetVersionName(uint16_t version) {
2655 switch (version) {
David Benjamin458334a2016-12-15 13:53:25 -05002656 case TLS1_VERSION:
2657 return "TLSv1";
2658 case TLS1_1_VERSION:
2659 return "TLSv1.1";
2660 case TLS1_2_VERSION:
2661 return "TLSv1.2";
2662 case TLS1_3_VERSION:
2663 return "TLSv1.3";
2664 case DTLS1_VERSION:
2665 return "DTLSv1";
2666 case DTLS1_2_VERSION:
2667 return "DTLSv1.2";
2668 default:
2669 return "???";
2670 }
2671}
2672
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002673TEST_P(SSLVersionTest, Version) {
2674 ASSERT_TRUE(Connect());
David Benjamincb18ac22016-09-27 14:09:15 -04002675
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002676 EXPECT_EQ(SSL_version(client_.get()), version());
2677 EXPECT_EQ(SSL_version(server_.get()), version());
David Benjamincb18ac22016-09-27 14:09:15 -04002678
David Benjamin458334a2016-12-15 13:53:25 -05002679 // Test the version name is reported as expected.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002680 const char *version_name = GetVersionName(version());
2681 EXPECT_EQ(strcmp(version_name, SSL_get_version(client_.get())), 0);
2682 EXPECT_EQ(strcmp(version_name, SSL_get_version(server_.get())), 0);
David Benjamin458334a2016-12-15 13:53:25 -05002683
2684 // Test SSL_SESSION reports the same name.
2685 const char *client_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002686 SSL_SESSION_get_version(SSL_get_session(client_.get()));
David Benjamin458334a2016-12-15 13:53:25 -05002687 const char *server_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002688 SSL_SESSION_get_version(SSL_get_session(server_.get()));
2689 EXPECT_EQ(strcmp(version_name, client_name), 0);
2690 EXPECT_EQ(strcmp(version_name, server_name), 0);
David Benjamincb18ac22016-09-27 14:09:15 -04002691}
2692
David Benjamin9ef31f02016-10-31 18:01:13 -04002693// Tests that that |SSL_get_pending_cipher| is available during the ALPN
2694// selection callback.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002695TEST_P(SSLVersionTest, ALPNCipherAvailable) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002696 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2697
David Benjamin9ef31f02016-10-31 18:01:13 -04002698 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002699 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
2700 sizeof(kALPNProtos)),
2701 0);
David Benjamin0fef3052016-11-18 15:11:10 +09002702
2703 // The ALPN callback does not fail the handshake on error, so have the
2704 // callback write a boolean.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002705 std::pair<uint16_t, bool> callback_state(version(), false);
David Benjamin0fef3052016-11-18 15:11:10 +09002706 SSL_CTX_set_alpn_select_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002707 server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09002708 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
2709 unsigned in_len, void *arg) -> int {
2710 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
2711 if (SSL_get_pending_cipher(ssl) != nullptr &&
2712 SSL_version(ssl) == state->first) {
2713 state->second = true;
2714 }
2715 return SSL_TLSEXT_ERR_NOACK;
2716 },
2717 &callback_state);
2718
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002719 ASSERT_TRUE(Connect());
David Benjamin0fef3052016-11-18 15:11:10 +09002720
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002721 ASSERT_TRUE(callback_state.second);
David Benjamin0fef3052016-11-18 15:11:10 +09002722}
2723
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002724TEST_P(SSLVersionTest, SSLClearSessionResumption) {
David Benjaminb79cc842016-12-07 15:57:14 -05002725 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
2726 // API pattern.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002727 if (version() == TLS1_3_VERSION) {
2728 return;
David Benjaminb79cc842016-12-07 15:57:14 -05002729 }
2730
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07002731 shed_handshake_config_ = false;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002732 ASSERT_TRUE(Connect());
David Benjaminb79cc842016-12-07 15:57:14 -05002733
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002734 EXPECT_FALSE(SSL_session_reused(client_.get()));
2735 EXPECT_FALSE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002736
2737 // Reset everything.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002738 ASSERT_TRUE(SSL_clear(client_.get()));
2739 ASSERT_TRUE(SSL_clear(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002740
2741 // Attempt to connect a second time.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002742 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002743
2744 // |SSL_clear| should implicitly offer the previous session to the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002745 EXPECT_TRUE(SSL_session_reused(client_.get()));
2746 EXPECT_TRUE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002747}
2748
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07002749TEST_P(SSLVersionTest, SSLClearFailsWithShedding) {
2750 shed_handshake_config_ = false;
2751 ASSERT_TRUE(Connect());
2752 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
2753
2754 // Reset everything.
2755 ASSERT_TRUE(SSL_clear(client_.get()));
2756 ASSERT_TRUE(SSL_clear(server_.get()));
2757
2758 // Now enable shedding, and connect a second time.
2759 shed_handshake_config_ = true;
2760 ASSERT_TRUE(Connect());
2761 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
2762
2763 // |SSL_clear| should now fail.
2764 ASSERT_FALSE(SSL_clear(client_.get()));
2765 ASSERT_FALSE(SSL_clear(server_.get()));
2766}
2767
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002768static bool ChainsEqual(STACK_OF(X509) * chain,
2769 const std::vector<X509 *> &expected) {
David Benjamin1444c3a2016-12-20 17:23:11 -05002770 if (sk_X509_num(chain) != expected.size()) {
2771 return false;
2772 }
2773
2774 for (size_t i = 0; i < expected.size(); i++) {
2775 if (X509_cmp(sk_X509_value(chain, i), expected[i]) != 0) {
2776 return false;
2777 }
2778 }
2779
2780 return true;
2781}
2782
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002783TEST_P(SSLVersionTest, AutoChain) {
2784 cert_ = GetChainTestCertificate();
2785 ASSERT_TRUE(cert_);
2786 key_ = GetChainTestKey();
2787 ASSERT_TRUE(key_);
David Benjamin1444c3a2016-12-20 17:23:11 -05002788 bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002789 ASSERT_TRUE(intermediate);
2790
2791 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2792 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin1444c3a2016-12-20 17:23:11 -05002793
2794 // Configure both client and server to accept any certificate. Add
2795 // |intermediate| to the cert store.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002796 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx_.get()),
2797 intermediate.get()));
2798 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(server_ctx_.get()),
2799 intermediate.get()));
2800 SSL_CTX_set_verify(client_ctx_.get(),
2801 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2802 nullptr);
2803 SSL_CTX_set_verify(server_ctx_.get(),
2804 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2805 nullptr);
2806 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
2807 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjamin1444c3a2016-12-20 17:23:11 -05002808
2809 // By default, the client and server should each only send the leaf.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002810 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002811
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002812 EXPECT_TRUE(
2813 ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()), {cert_.get()}));
2814 EXPECT_TRUE(
2815 ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()), {cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002816
2817 // If auto-chaining is enabled, then the intermediate is sent.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002818 SSL_CTX_clear_mode(client_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
2819 SSL_CTX_clear_mode(server_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
2820 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002821
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002822 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
2823 {cert_.get(), intermediate.get()}));
2824 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
2825 {cert_.get(), intermediate.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002826
2827 // Auto-chaining does not override explicitly-configured intermediates.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002828 ASSERT_TRUE(SSL_CTX_add1_chain_cert(client_ctx_.get(), cert_.get()));
2829 ASSERT_TRUE(SSL_CTX_add1_chain_cert(server_ctx_.get(), cert_.get()));
2830 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002831
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002832 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
2833 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002834
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002835 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
2836 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002837}
2838
David Benjamin48063c22017-01-01 23:56:36 -05002839static bool ExpectBadWriteRetry() {
2840 int err = ERR_get_error();
2841 if (ERR_GET_LIB(err) != ERR_LIB_SSL ||
2842 ERR_GET_REASON(err) != SSL_R_BAD_WRITE_RETRY) {
2843 char buf[ERR_ERROR_STRING_BUF_LEN];
2844 ERR_error_string_n(err, buf, sizeof(buf));
2845 fprintf(stderr, "Wanted SSL_R_BAD_WRITE_RETRY, got: %s.\n", buf);
2846 return false;
2847 }
2848
2849 if (ERR_peek_error() != 0) {
2850 fprintf(stderr, "Unexpected error following SSL_R_BAD_WRITE_RETRY.\n");
2851 return false;
2852 }
2853
2854 return true;
2855}
2856
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002857TEST_P(SSLVersionTest, SSLWriteRetry) {
2858 if (is_dtls()) {
2859 return;
David Benjamin48063c22017-01-01 23:56:36 -05002860 }
2861
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002862 for (bool enable_partial_write : {false, true}) {
2863 SCOPED_TRACE(enable_partial_write);
2864
David Benjamin48063c22017-01-01 23:56:36 -05002865 // Connect a client and server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002866 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2867
2868 ASSERT_TRUE(Connect());
David Benjamin48063c22017-01-01 23:56:36 -05002869
2870 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002871 SSL_set_mode(client_.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002872 }
2873
2874 // Write without reading until the buffer is full and we have an unfinished
2875 // write. Keep a count so we may reread it again later. "hello!" will be
2876 // written in two chunks, "hello" and "!".
2877 char data[] = "hello!";
2878 static const int kChunkLen = 5; // The length of "hello".
2879 unsigned count = 0;
2880 for (;;) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002881 int ret = SSL_write(client_.get(), data, kChunkLen);
David Benjamin48063c22017-01-01 23:56:36 -05002882 if (ret <= 0) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002883 ASSERT_EQ(SSL_get_error(client_.get(), ret), SSL_ERROR_WANT_WRITE);
2884 break;
David Benjamin48063c22017-01-01 23:56:36 -05002885 }
2886
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002887 ASSERT_EQ(ret, 5);
David Benjamin48063c22017-01-01 23:56:36 -05002888
2889 count++;
2890 }
2891
2892 // Retrying with the same parameters is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002893 ASSERT_EQ(
2894 SSL_get_error(client_.get(), SSL_write(client_.get(), data, kChunkLen)),
2895 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002896
2897 // Retrying with the same buffer but shorter length is not legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002898 ASSERT_EQ(SSL_get_error(client_.get(),
2899 SSL_write(client_.get(), data, kChunkLen - 1)),
2900 SSL_ERROR_SSL);
2901 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002902
2903 // Retrying with a different buffer pointer is not legal.
2904 char data2[] = "hello";
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002905 ASSERT_EQ(SSL_get_error(client_.get(),
2906 SSL_write(client_.get(), data2, kChunkLen)),
2907 SSL_ERROR_SSL);
2908 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002909
2910 // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002911 SSL_set_mode(client_.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
2912 ASSERT_EQ(SSL_get_error(client_.get(),
2913 SSL_write(client_.get(), data2, kChunkLen)),
2914 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002915
2916 // |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| does not disable length checks.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002917 ASSERT_EQ(SSL_get_error(client_.get(),
2918 SSL_write(client_.get(), data2, kChunkLen - 1)),
2919 SSL_ERROR_SSL);
2920 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002921
2922 // Retrying with a larger buffer is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002923 ASSERT_EQ(SSL_get_error(client_.get(),
2924 SSL_write(client_.get(), data, kChunkLen + 1)),
2925 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002926
2927 // Drain the buffer.
2928 char buf[20];
2929 for (unsigned i = 0; i < count; i++) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002930 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
2931 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
David Benjamin48063c22017-01-01 23:56:36 -05002932 }
2933
2934 // Now that there is space, a retry with a larger buffer should flush the
2935 // pending record, skip over that many bytes of input (on assumption they
2936 // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE
2937 // is set, this will complete in two steps.
2938 char data3[] = "_____!";
2939 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002940 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen);
2941 ASSERT_EQ(SSL_write(client_.get(), data3 + kChunkLen, 1), 1);
2942 } else {
2943 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen + 1);
David Benjamin48063c22017-01-01 23:56:36 -05002944 }
2945
2946 // Check the last write was correct. The data will be spread over two
2947 // records, so SSL_read returns twice.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002948 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
2949 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
2950 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), 1);
2951 ASSERT_EQ(buf[0], '!');
David Benjamin48063c22017-01-01 23:56:36 -05002952 }
David Benjamin48063c22017-01-01 23:56:36 -05002953}
2954
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002955TEST_P(SSLVersionTest, RecordCallback) {
2956 for (bool test_server : {true, false}) {
2957 SCOPED_TRACE(test_server);
2958 ResetContexts();
David Benjamin5df5be1a2017-06-22 19:43:11 -04002959
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002960 bool read_seen = false;
2961 bool write_seen = false;
2962 auto cb = [&](int is_write, int cb_version, int cb_type, const void *buf,
2963 size_t len, SSL *ssl) {
2964 if (cb_type != SSL3_RT_HEADER) {
2965 return;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002966 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002967
2968 // The callback does not report a version for records.
2969 EXPECT_EQ(0, cb_version);
2970
2971 if (is_write) {
2972 write_seen = true;
2973 } else {
2974 read_seen = true;
2975 }
2976
2977 // Sanity-check that the record header is plausible.
2978 CBS cbs;
2979 CBS_init(&cbs, reinterpret_cast<const uint8_t *>(buf), len);
2980 uint8_t type;
2981 uint16_t record_version, length;
2982 ASSERT_TRUE(CBS_get_u8(&cbs, &type));
2983 ASSERT_TRUE(CBS_get_u16(&cbs, &record_version));
Steven Valdez64cc1212017-12-04 11:15:37 -05002984 EXPECT_EQ(record_version & 0xff00, version() & 0xff00);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002985 if (is_dtls()) {
2986 uint16_t epoch;
2987 ASSERT_TRUE(CBS_get_u16(&cbs, &epoch));
2988 EXPECT_TRUE(epoch == 0 || epoch == 1) << "Invalid epoch: " << epoch;
2989 ASSERT_TRUE(CBS_skip(&cbs, 6));
2990 }
2991 ASSERT_TRUE(CBS_get_u16(&cbs, &length));
2992 EXPECT_EQ(0u, CBS_len(&cbs));
2993 };
2994 using CallbackType = decltype(cb);
2995 SSL_CTX *ctx = test_server ? server_ctx_.get() : client_ctx_.get();
2996 SSL_CTX_set_msg_callback(
2997 ctx, [](int is_write, int cb_version, int cb_type, const void *buf,
2998 size_t len, SSL *ssl, void *arg) {
2999 CallbackType *cb_ptr = reinterpret_cast<CallbackType *>(arg);
3000 (*cb_ptr)(is_write, cb_version, cb_type, buf, len, ssl);
3001 });
3002 SSL_CTX_set_msg_callback_arg(ctx, &cb);
3003
3004 ASSERT_TRUE(Connect());
3005
3006 EXPECT_TRUE(read_seen);
3007 EXPECT_TRUE(write_seen);
David Benjamin0fef3052016-11-18 15:11:10 +09003008 }
David Benjamin9ef31f02016-10-31 18:01:13 -04003009}
3010
David Benjamina8614602017-09-06 15:40:19 -04003011TEST_P(SSLVersionTest, GetServerName) {
David Benjamina8614602017-09-06 15:40:19 -04003012 ClientConfig config;
3013 config.servername = "host1";
3014
3015 SSL_CTX_set_tlsext_servername_callback(
3016 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
3017 // During the handshake, |SSL_get_servername| must match |config|.
3018 ClientConfig *config_p = reinterpret_cast<ClientConfig *>(arg);
3019 EXPECT_STREQ(config_p->servername.c_str(),
3020 SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name));
3021 return SSL_TLSEXT_ERR_OK;
3022 });
3023 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), &config);
3024
3025 ASSERT_TRUE(Connect(config));
3026 // After the handshake, it must also be available.
3027 EXPECT_STREQ(config.servername.c_str(),
3028 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3029
3030 // Establish a session under host1.
3031 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3032 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3033 bssl::UniquePtr<SSL_SESSION> session =
3034 CreateClientSession(client_ctx_.get(), server_ctx_.get(), config);
3035
3036 // If the client resumes a session with a different name, |SSL_get_servername|
3037 // must return the new name.
3038 ASSERT_TRUE(session);
3039 config.session = session.get();
3040 config.servername = "host2";
3041 ASSERT_TRUE(Connect(config));
3042 EXPECT_STREQ(config.servername.c_str(),
3043 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3044}
3045
David Benjamin3d8f0802017-09-06 16:12:52 -04003046// Test that session cache mode bits are honored in the client session callback.
3047TEST_P(SSLVersionTest, ClientSessionCacheMode) {
3048 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_OFF);
3049 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3050
3051 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_CLIENT);
3052 EXPECT_TRUE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3053
3054 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_SERVER);
3055 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3056}
3057
Adam Langleye1e78132017-01-31 15:24:31 -08003058TEST(SSLTest, AddChainCertHack) {
3059 // Ensure that we don't accidently break the hack that we have in place to
3060 // keep curl and serf happy when they use an |X509| even after transfering
3061 // ownership.
3062
3063 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3064 ASSERT_TRUE(ctx);
3065 X509 *cert = GetTestCertificate().release();
3066 ASSERT_TRUE(cert);
3067 SSL_CTX_add0_chain_cert(ctx.get(), cert);
3068
3069 // This should not trigger a use-after-free.
3070 X509_cmp(cert, cert);
3071}
3072
David Benjaminb2ff2622017-02-03 17:06:18 -05003073TEST(SSLTest, GetCertificate) {
3074 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3075 ASSERT_TRUE(ctx);
3076 bssl::UniquePtr<X509> cert = GetTestCertificate();
3077 ASSERT_TRUE(cert);
3078 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
3079 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3080 ASSERT_TRUE(ssl);
3081
3082 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
3083 ASSERT_TRUE(cert2);
3084 X509 *cert3 = SSL_get_certificate(ssl.get());
3085 ASSERT_TRUE(cert3);
3086
3087 // The old and new certificates must be identical.
3088 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
3089 EXPECT_EQ(0, X509_cmp(cert.get(), cert3));
3090
3091 uint8_t *der = nullptr;
3092 long der_len = i2d_X509(cert.get(), &der);
3093 ASSERT_LT(0, der_len);
3094 bssl::UniquePtr<uint8_t> free_der(der);
3095
3096 uint8_t *der2 = nullptr;
3097 long der2_len = i2d_X509(cert2, &der2);
3098 ASSERT_LT(0, der2_len);
3099 bssl::UniquePtr<uint8_t> free_der2(der2);
3100
3101 uint8_t *der3 = nullptr;
3102 long der3_len = i2d_X509(cert3, &der3);
3103 ASSERT_LT(0, der3_len);
3104 bssl::UniquePtr<uint8_t> free_der3(der3);
3105
3106 // They must also encode identically.
David Benjamin7d7554b2017-02-04 11:48:59 -05003107 EXPECT_EQ(Bytes(der, der_len), Bytes(der2, der2_len));
3108 EXPECT_EQ(Bytes(der, der_len), Bytes(der3, der3_len));
David Benjaminb2ff2622017-02-03 17:06:18 -05003109}
3110
Adam Langleyd04ca952017-02-28 11:26:51 -08003111TEST(SSLTest, SetChainAndKeyMismatch) {
3112 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_with_buffers_method()));
3113 ASSERT_TRUE(ctx);
3114
3115 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3116 ASSERT_TRUE(key);
3117 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3118 ASSERT_TRUE(leaf);
3119 std::vector<CRYPTO_BUFFER*> chain = {
3120 leaf.get(),
3121 };
3122
3123 // Should fail because |GetTestKey| doesn't match the chain-test certificate.
3124 ASSERT_FALSE(SSL_CTX_set_chain_and_key(ctx.get(), &chain[0], chain.size(),
3125 key.get(), nullptr));
3126 ERR_clear_error();
3127}
3128
3129TEST(SSLTest, SetChainAndKey) {
3130 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3131 ASSERT_TRUE(client_ctx);
3132 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3133 ASSERT_TRUE(server_ctx);
3134
3135 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3136 ASSERT_TRUE(key);
3137 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3138 ASSERT_TRUE(leaf);
3139 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3140 GetChainTestIntermediateBuffer();
3141 ASSERT_TRUE(intermediate);
3142 std::vector<CRYPTO_BUFFER*> chain = {
3143 leaf.get(), intermediate.get(),
3144 };
3145 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3146 chain.size(), key.get(), nullptr));
3147
David Benjamin3a1dd462017-07-11 16:13:10 -04003148 SSL_CTX_set_custom_verify(
3149 client_ctx.get(), SSL_VERIFY_PEER,
3150 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3151 return ssl_verify_ok;
3152 });
Adam Langleyd04ca952017-02-28 11:26:51 -08003153
3154 bssl::UniquePtr<SSL> client, server;
3155 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003156 server_ctx.get()));
Adam Langleyd04ca952017-02-28 11:26:51 -08003157}
3158
Matthew Braithwaite5301c102018-01-23 12:08:55 -08003159TEST(SSLTest, BuffersFailWithoutCustomVerify) {
3160 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3161 ASSERT_TRUE(client_ctx);
3162 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3163 ASSERT_TRUE(server_ctx);
3164
3165 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3166 ASSERT_TRUE(key);
3167 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3168 ASSERT_TRUE(leaf);
3169 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
3170 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3171 chain.size(), key.get(), nullptr));
3172
3173 // Without SSL_CTX_set_custom_verify(), i.e. with everything in the default
3174 // configuration, certificate verification should fail.
3175 bssl::UniquePtr<SSL> client, server;
3176 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3177 server_ctx.get()));
3178
3179 // Whereas with a verifier, the connection should succeed.
3180 SSL_CTX_set_custom_verify(
3181 client_ctx.get(), SSL_VERIFY_PEER,
3182 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3183 return ssl_verify_ok;
3184 });
3185 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3186 server_ctx.get()));
3187}
3188
3189TEST(SSLTest, CustomVerify) {
3190 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3191 ASSERT_TRUE(client_ctx);
3192 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3193 ASSERT_TRUE(server_ctx);
3194
3195 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3196 ASSERT_TRUE(key);
3197 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3198 ASSERT_TRUE(leaf);
3199 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
3200 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3201 chain.size(), key.get(), nullptr));
3202
3203 SSL_CTX_set_custom_verify(
3204 client_ctx.get(), SSL_VERIFY_PEER,
3205 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3206 return ssl_verify_ok;
3207 });
3208
3209 bssl::UniquePtr<SSL> client, server;
3210 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3211 server_ctx.get()));
3212
3213 // With SSL_VERIFY_PEER, ssl_verify_invalid should result in a dropped
3214 // connection.
3215 SSL_CTX_set_custom_verify(
3216 client_ctx.get(), SSL_VERIFY_PEER,
3217 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3218 return ssl_verify_invalid;
3219 });
3220
3221 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3222 server_ctx.get()));
3223
3224 // But with SSL_VERIFY_NONE, ssl_verify_invalid should not cause a dropped
3225 // connection.
3226 SSL_CTX_set_custom_verify(
3227 client_ctx.get(), SSL_VERIFY_NONE,
3228 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3229 return ssl_verify_invalid;
3230 });
3231
3232 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3233 server_ctx.get()));
3234}
3235
David Benjamin71dfad42017-07-16 17:27:39 -04003236TEST(SSLTest, ClientCABuffers) {
3237 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3238 ASSERT_TRUE(client_ctx);
3239 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3240 ASSERT_TRUE(server_ctx);
3241
3242 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3243 ASSERT_TRUE(key);
3244 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3245 ASSERT_TRUE(leaf);
3246 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3247 GetChainTestIntermediateBuffer();
3248 ASSERT_TRUE(intermediate);
3249 std::vector<CRYPTO_BUFFER *> chain = {
3250 leaf.get(),
3251 intermediate.get(),
3252 };
3253 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3254 chain.size(), key.get(), nullptr));
3255
3256 bssl::UniquePtr<CRYPTO_BUFFER> ca_name(
3257 CRYPTO_BUFFER_new(kTestName, sizeof(kTestName), nullptr));
3258 ASSERT_TRUE(ca_name);
3259 bssl::UniquePtr<STACK_OF(CRYPTO_BUFFER)> ca_names(
3260 sk_CRYPTO_BUFFER_new_null());
3261 ASSERT_TRUE(ca_names);
David Benjamin2908dd12018-06-29 17:46:42 -04003262 ASSERT_TRUE(PushToStack(ca_names.get(), std::move(ca_name)));
David Benjamin71dfad42017-07-16 17:27:39 -04003263 SSL_CTX_set0_client_CAs(server_ctx.get(), ca_names.release());
3264
3265 // Configure client and server to accept all certificates.
3266 SSL_CTX_set_custom_verify(
3267 client_ctx.get(), SSL_VERIFY_PEER,
3268 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3269 return ssl_verify_ok;
3270 });
3271 SSL_CTX_set_custom_verify(
3272 server_ctx.get(), SSL_VERIFY_PEER,
3273 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3274 return ssl_verify_ok;
3275 });
3276
3277 bool cert_cb_called = false;
3278 SSL_CTX_set_cert_cb(
3279 client_ctx.get(),
3280 [](SSL *ssl, void *arg) -> int {
David Benjamin5f001d12018-05-08 16:46:48 -04003281 const STACK_OF(CRYPTO_BUFFER) *peer_names =
David Benjamin71dfad42017-07-16 17:27:39 -04003282 SSL_get0_server_requested_CAs(ssl);
3283 EXPECT_EQ(1u, sk_CRYPTO_BUFFER_num(peer_names));
3284 CRYPTO_BUFFER *peer_name = sk_CRYPTO_BUFFER_value(peer_names, 0);
3285 EXPECT_EQ(Bytes(kTestName), Bytes(CRYPTO_BUFFER_data(peer_name),
3286 CRYPTO_BUFFER_len(peer_name)));
3287 *reinterpret_cast<bool *>(arg) = true;
3288 return 1;
3289 },
3290 &cert_cb_called);
3291
3292 bssl::UniquePtr<SSL> client, server;
3293 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003294 server_ctx.get()));
David Benjamin71dfad42017-07-16 17:27:39 -04003295 EXPECT_TRUE(cert_cb_called);
3296}
3297
David Benjamin91222b82017-03-09 20:10:56 -05003298// Configuring the empty cipher list, though an error, should still modify the
3299// configuration.
3300TEST(SSLTest, EmptyCipherList) {
3301 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3302 ASSERT_TRUE(ctx);
3303
3304 // Initially, the cipher list is not empty.
3305 EXPECT_NE(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3306
3307 // Configuring the empty cipher list fails.
3308 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), ""));
3309 ERR_clear_error();
3310
3311 // But the cipher list is still updated to empty.
3312 EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3313}
3314
Adam Langley4c341d02017-03-08 19:33:21 -08003315// ssl_test_ticket_aead_failure_mode enumerates the possible ways in which the
3316// test |SSL_TICKET_AEAD_METHOD| can fail.
3317enum ssl_test_ticket_aead_failure_mode {
3318 ssl_test_ticket_aead_ok = 0,
3319 ssl_test_ticket_aead_seal_fail,
3320 ssl_test_ticket_aead_open_soft_fail,
3321 ssl_test_ticket_aead_open_hard_fail,
3322};
3323
3324struct ssl_test_ticket_aead_state {
3325 unsigned retry_count;
3326 ssl_test_ticket_aead_failure_mode failure_mode;
3327};
3328
3329static int ssl_test_ticket_aead_ex_index_dup(CRYPTO_EX_DATA *to,
3330 const CRYPTO_EX_DATA *from,
3331 void **from_d, int index,
3332 long argl, void *argp) {
3333 abort();
3334}
3335
3336static void ssl_test_ticket_aead_ex_index_free(void *parent, void *ptr,
3337 CRYPTO_EX_DATA *ad, int index,
3338 long argl, void *argp) {
3339 auto state = reinterpret_cast<ssl_test_ticket_aead_state*>(ptr);
3340 if (state == nullptr) {
3341 return;
3342 }
3343
3344 OPENSSL_free(state);
3345}
3346
3347static CRYPTO_once_t g_ssl_test_ticket_aead_ex_index_once = CRYPTO_ONCE_INIT;
3348static int g_ssl_test_ticket_aead_ex_index;
3349
3350static int ssl_test_ticket_aead_get_ex_index() {
3351 CRYPTO_once(&g_ssl_test_ticket_aead_ex_index_once, [] {
3352 g_ssl_test_ticket_aead_ex_index = SSL_get_ex_new_index(
3353 0, nullptr, nullptr, ssl_test_ticket_aead_ex_index_dup,
3354 ssl_test_ticket_aead_ex_index_free);
3355 });
3356 return g_ssl_test_ticket_aead_ex_index;
3357}
3358
3359static size_t ssl_test_ticket_aead_max_overhead(SSL *ssl) {
3360 return 1;
3361}
3362
3363static int ssl_test_ticket_aead_seal(SSL *ssl, uint8_t *out, size_t *out_len,
3364 size_t max_out_len, const uint8_t *in,
3365 size_t in_len) {
3366 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3367 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3368
3369 if (state->failure_mode == ssl_test_ticket_aead_seal_fail ||
3370 max_out_len < in_len + 1) {
3371 return 0;
3372 }
3373
3374 OPENSSL_memmove(out, in, in_len);
3375 out[in_len] = 0xff;
3376 *out_len = in_len + 1;
3377
3378 return 1;
3379}
3380
3381static ssl_ticket_aead_result_t ssl_test_ticket_aead_open(
3382 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len,
3383 const uint8_t *in, size_t in_len) {
3384 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3385 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3386
3387 if (state->retry_count > 0) {
3388 state->retry_count--;
3389 return ssl_ticket_aead_retry;
3390 }
3391
3392 switch (state->failure_mode) {
3393 case ssl_test_ticket_aead_ok:
3394 break;
3395 case ssl_test_ticket_aead_seal_fail:
3396 // If |seal| failed then there shouldn't be any ticket to try and
3397 // decrypt.
3398 abort();
3399 break;
3400 case ssl_test_ticket_aead_open_soft_fail:
3401 return ssl_ticket_aead_ignore_ticket;
3402 case ssl_test_ticket_aead_open_hard_fail:
3403 return ssl_ticket_aead_error;
3404 }
3405
3406 if (in_len == 0 || in[in_len - 1] != 0xff) {
3407 return ssl_ticket_aead_ignore_ticket;
3408 }
3409
3410 if (max_out_len < in_len - 1) {
3411 return ssl_ticket_aead_error;
3412 }
3413
3414 OPENSSL_memmove(out, in, in_len - 1);
3415 *out_len = in_len - 1;
3416 return ssl_ticket_aead_success;
3417}
3418
3419static const SSL_TICKET_AEAD_METHOD kSSLTestTicketMethod = {
3420 ssl_test_ticket_aead_max_overhead,
3421 ssl_test_ticket_aead_seal,
3422 ssl_test_ticket_aead_open,
3423};
3424
3425static void ConnectClientAndServerWithTicketMethod(
3426 bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
3427 SSL_CTX *client_ctx, SSL_CTX *server_ctx, unsigned retry_count,
3428 ssl_test_ticket_aead_failure_mode failure_mode, SSL_SESSION *session) {
3429 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
3430 ASSERT_TRUE(client);
3431 ASSERT_TRUE(server);
3432 SSL_set_connect_state(client.get());
3433 SSL_set_accept_state(server.get());
3434
3435 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3436 OPENSSL_malloc(sizeof(ssl_test_ticket_aead_state)));
3437 ASSERT_TRUE(state);
3438 OPENSSL_memset(state, 0, sizeof(ssl_test_ticket_aead_state));
3439 state->retry_count = retry_count;
3440 state->failure_mode = failure_mode;
3441
3442 ASSERT_TRUE(SSL_set_ex_data(server.get(), ssl_test_ticket_aead_get_ex_index(),
3443 state));
3444
3445 SSL_set_session(client.get(), session);
3446
3447 BIO *bio1, *bio2;
3448 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
3449
3450 // SSL_set_bio takes ownership.
3451 SSL_set_bio(client.get(), bio1, bio1);
3452 SSL_set_bio(server.get(), bio2, bio2);
3453
3454 if (CompleteHandshakes(client.get(), server.get())) {
3455 *out_client = std::move(client);
3456 *out_server = std::move(server);
3457 } else {
3458 out_client->reset();
3459 out_server->reset();
3460 }
3461}
3462
David Benjaminc9775322018-04-13 16:39:12 -04003463using TicketAEADMethodParam =
3464 testing::tuple<uint16_t, unsigned, ssl_test_ticket_aead_failure_mode>;
3465
Adam Langley4c341d02017-03-08 19:33:21 -08003466class TicketAEADMethodTest
David Benjaminc9775322018-04-13 16:39:12 -04003467 : public ::testing::TestWithParam<TicketAEADMethodParam> {};
Adam Langley4c341d02017-03-08 19:33:21 -08003468
3469TEST_P(TicketAEADMethodTest, Resume) {
3470 bssl::UniquePtr<X509> cert = GetTestCertificate();
3471 ASSERT_TRUE(cert);
3472 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3473 ASSERT_TRUE(key);
3474
3475 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
3476 ASSERT_TRUE(server_ctx);
3477 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
3478 ASSERT_TRUE(client_ctx);
3479
3480 const uint16_t version = testing::get<0>(GetParam());
3481 const unsigned retry_count = testing::get<1>(GetParam());
3482 const ssl_test_ticket_aead_failure_mode failure_mode =
3483 testing::get<2>(GetParam());
3484
3485 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3486 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3487 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), version));
3488 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), version));
3489 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), version));
3490 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), version));
3491
3492 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
3493 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
3494 SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
3495 SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
David Benjamin707af292017-03-10 17:47:18 -05003496 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langley4c341d02017-03-08 19:33:21 -08003497
3498 SSL_CTX_set_ticket_aead_method(server_ctx.get(), &kSSLTestTicketMethod);
3499
3500 bssl::UniquePtr<SSL> client, server;
3501 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3502 server_ctx.get(), retry_count,
3503 failure_mode, nullptr);
3504 switch (failure_mode) {
3505 case ssl_test_ticket_aead_ok:
3506 case ssl_test_ticket_aead_open_hard_fail:
3507 case ssl_test_ticket_aead_open_soft_fail:
3508 ASSERT_TRUE(client);
3509 break;
3510 case ssl_test_ticket_aead_seal_fail:
3511 EXPECT_FALSE(client);
3512 return;
3513 }
3514 EXPECT_FALSE(SSL_session_reused(client.get()));
3515 EXPECT_FALSE(SSL_session_reused(server.get()));
3516
David Benjamin707af292017-03-10 17:47:18 -05003517 // Run the read loop to account for post-handshake tickets in TLS 1.3.
3518 SSL_read(client.get(), nullptr, 0);
3519
3520 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
Adam Langley4c341d02017-03-08 19:33:21 -08003521 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3522 server_ctx.get(), retry_count,
David Benjamin707af292017-03-10 17:47:18 -05003523 failure_mode, session.get());
Adam Langley4c341d02017-03-08 19:33:21 -08003524 switch (failure_mode) {
3525 case ssl_test_ticket_aead_ok:
3526 ASSERT_TRUE(client);
3527 EXPECT_TRUE(SSL_session_reused(client.get()));
3528 EXPECT_TRUE(SSL_session_reused(server.get()));
3529 break;
3530 case ssl_test_ticket_aead_seal_fail:
3531 abort();
3532 break;
3533 case ssl_test_ticket_aead_open_hard_fail:
3534 EXPECT_FALSE(client);
3535 break;
3536 case ssl_test_ticket_aead_open_soft_fail:
3537 ASSERT_TRUE(client);
3538 EXPECT_FALSE(SSL_session_reused(client.get()));
3539 EXPECT_FALSE(SSL_session_reused(server.get()));
3540 }
3541}
3542
David Benjaminc9775322018-04-13 16:39:12 -04003543std::string TicketAEADMethodParamToString(
3544 const testing::TestParamInfo<TicketAEADMethodParam> &params) {
3545 std::string ret = GetVersionName(std::get<0>(params.param));
3546 // GTest only allows alphanumeric characters and '_' in the parameter
3547 // string. Additionally filter out the 'v' to get "TLS13" over "TLSv13".
3548 for (auto it = ret.begin(); it != ret.end();) {
3549 if (*it == '.' || *it == 'v') {
3550 it = ret.erase(it);
3551 } else {
3552 ++it;
3553 }
3554 }
3555 char retry_count[256];
3556 snprintf(retry_count, sizeof(retry_count), "%d", std::get<1>(params.param));
3557 ret += "_";
3558 ret += retry_count;
3559 ret += "Retries_";
3560 switch (std::get<2>(params.param)) {
3561 case ssl_test_ticket_aead_ok:
3562 ret += "OK";
3563 break;
3564 case ssl_test_ticket_aead_seal_fail:
3565 ret += "SealFail";
3566 break;
3567 case ssl_test_ticket_aead_open_soft_fail:
3568 ret += "OpenSoftFail";
3569 break;
3570 case ssl_test_ticket_aead_open_hard_fail:
3571 ret += "OpenHardFail";
3572 break;
3573 }
3574 return ret;
3575}
3576
Adam Langley4c341d02017-03-08 19:33:21 -08003577INSTANTIATE_TEST_CASE_P(
3578 TicketAEADMethodTests, TicketAEADMethodTest,
David Benjaminc9775322018-04-13 16:39:12 -04003579 testing::Combine(testing::Values(TLS1_2_VERSION, TLS1_3_VERSION),
3580 testing::Values(0, 1, 2),
3581 testing::Values(ssl_test_ticket_aead_ok,
3582 ssl_test_ticket_aead_seal_fail,
3583 ssl_test_ticket_aead_open_soft_fail,
3584 ssl_test_ticket_aead_open_hard_fail)),
3585 TicketAEADMethodParamToString);
Adam Langley4c341d02017-03-08 19:33:21 -08003586
David Benjaminca743582017-06-15 17:51:35 -04003587TEST(SSLTest, SelectNextProto) {
3588 uint8_t *result;
3589 uint8_t result_len;
3590
3591 // If there is an overlap, it should be returned.
3592 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3593 SSL_select_next_proto(&result, &result_len,
3594 (const uint8_t *)"\1a\2bb\3ccc", 9,
3595 (const uint8_t *)"\1x\1y\1a\1z", 8));
3596 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
3597
3598 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3599 SSL_select_next_proto(&result, &result_len,
3600 (const uint8_t *)"\1a\2bb\3ccc", 9,
3601 (const uint8_t *)"\1x\1y\2bb\1z", 9));
3602 EXPECT_EQ(Bytes("bb"), Bytes(result, result_len));
3603
3604 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3605 SSL_select_next_proto(&result, &result_len,
3606 (const uint8_t *)"\1a\2bb\3ccc", 9,
3607 (const uint8_t *)"\1x\1y\3ccc\1z", 10));
3608 EXPECT_EQ(Bytes("ccc"), Bytes(result, result_len));
3609
3610 // Peer preference order takes precedence over local.
3611 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3612 SSL_select_next_proto(&result, &result_len,
3613 (const uint8_t *)"\1a\2bb\3ccc", 9,
3614 (const uint8_t *)"\3ccc\2bb\1a", 9));
3615 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
3616
3617 // If there is no overlap, return the first local protocol.
3618 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
3619 SSL_select_next_proto(&result, &result_len,
3620 (const uint8_t *)"\1a\2bb\3ccc", 9,
3621 (const uint8_t *)"\1x\2yy\3zzz", 9));
3622 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
3623
3624 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
3625 SSL_select_next_proto(&result, &result_len, nullptr, 0,
3626 (const uint8_t *)"\1x\2yy\3zzz", 9));
3627 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
3628}
3629
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003630TEST(SSLTest, SealRecord) {
3631 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3632 server_ctx(SSL_CTX_new(TLS_method()));
3633 ASSERT_TRUE(client_ctx);
3634 ASSERT_TRUE(server_ctx);
3635
3636 bssl::UniquePtr<X509> cert = GetTestCertificate();
3637 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3638 ASSERT_TRUE(cert);
3639 ASSERT_TRUE(key);
3640 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3641 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3642
3643 bssl::UniquePtr<SSL> client, server;
3644 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003645 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003646
3647 const std::vector<uint8_t> record = {1, 2, 3, 4, 5};
3648 std::vector<uint8_t> prefix(
3649 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003650 body(record.size()),
3651 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003652 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3653 bssl::MakeSpan(body), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003654 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003655
3656 std::vector<uint8_t> sealed;
3657 sealed.insert(sealed.end(), prefix.begin(), prefix.end());
3658 sealed.insert(sealed.end(), body.begin(), body.end());
3659 sealed.insert(sealed.end(), suffix.begin(), suffix.end());
3660 std::vector<uint8_t> sealed_copy = sealed;
3661
3662 bssl::Span<uint8_t> plaintext;
3663 size_t record_len;
3664 uint8_t alert = 255;
3665 EXPECT_EQ(bssl::OpenRecord(server.get(), &plaintext, &record_len, &alert,
3666 bssl::MakeSpan(sealed)),
3667 bssl::OpenRecordResult::kOK);
3668 EXPECT_EQ(record_len, sealed.size());
3669 EXPECT_EQ(plaintext, record);
3670 EXPECT_EQ(255, alert);
3671}
3672
3673TEST(SSLTest, SealRecordInPlace) {
3674 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3675 server_ctx(SSL_CTX_new(TLS_method()));
3676 ASSERT_TRUE(client_ctx);
3677 ASSERT_TRUE(server_ctx);
3678
3679 bssl::UniquePtr<X509> cert = GetTestCertificate();
3680 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3681 ASSERT_TRUE(cert);
3682 ASSERT_TRUE(key);
3683 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3684 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3685
3686 bssl::UniquePtr<SSL> client, server;
3687 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003688 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003689
3690 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
3691 std::vector<uint8_t> record = plaintext;
3692 std::vector<uint8_t> prefix(
3693 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003694 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003695 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3696 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003697 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003698 record.insert(record.begin(), prefix.begin(), prefix.end());
3699 record.insert(record.end(), suffix.begin(), suffix.end());
3700
3701 bssl::Span<uint8_t> result;
3702 size_t record_len;
3703 uint8_t alert;
3704 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
3705 bssl::MakeSpan(record)),
3706 bssl::OpenRecordResult::kOK);
3707 EXPECT_EQ(record_len, record.size());
3708 EXPECT_EQ(plaintext, result);
3709}
3710
3711TEST(SSLTest, SealRecordTrailingData) {
3712 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3713 server_ctx(SSL_CTX_new(TLS_method()));
3714 ASSERT_TRUE(client_ctx);
3715 ASSERT_TRUE(server_ctx);
3716
3717 bssl::UniquePtr<X509> cert = GetTestCertificate();
3718 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3719 ASSERT_TRUE(cert);
3720 ASSERT_TRUE(key);
3721 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3722 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3723
3724 bssl::UniquePtr<SSL> client, server;
3725 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003726 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003727
3728 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
3729 std::vector<uint8_t> record = plaintext;
3730 std::vector<uint8_t> prefix(
3731 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003732 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003733 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3734 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003735 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003736 record.insert(record.begin(), prefix.begin(), prefix.end());
3737 record.insert(record.end(), suffix.begin(), suffix.end());
3738 record.insert(record.end(), {5, 4, 3, 2, 1});
3739
3740 bssl::Span<uint8_t> result;
3741 size_t record_len;
3742 uint8_t alert;
3743 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
3744 bssl::MakeSpan(record)),
3745 bssl::OpenRecordResult::kOK);
3746 EXPECT_EQ(record_len, record.size() - 5);
3747 EXPECT_EQ(plaintext, result);
3748}
3749
3750TEST(SSLTest, SealRecordInvalidSpanSize) {
3751 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3752 server_ctx(SSL_CTX_new(TLS_method()));
3753 ASSERT_TRUE(client_ctx);
3754 ASSERT_TRUE(server_ctx);
3755
3756 bssl::UniquePtr<X509> cert = GetTestCertificate();
3757 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3758 ASSERT_TRUE(cert);
3759 ASSERT_TRUE(key);
3760 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3761 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3762
3763 bssl::UniquePtr<SSL> client, server;
3764 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003765 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003766
3767 std::vector<uint8_t> record = {1, 2, 3, 4, 5};
3768 std::vector<uint8_t> prefix(
3769 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003770 body(record.size()),
3771 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003772
3773 auto expect_err = []() {
3774 int err = ERR_get_error();
3775 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
3776 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_BUFFER_TOO_SMALL);
3777 ERR_clear_error();
3778 };
3779 EXPECT_FALSE(bssl::SealRecord(
3780 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003781 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003782 expect_err();
3783 EXPECT_FALSE(bssl::SealRecord(
3784 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003785 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003786 expect_err();
3787
3788 EXPECT_FALSE(
3789 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3790 bssl::MakeSpan(record.data(), record.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003791 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003792 expect_err();
3793 EXPECT_FALSE(
3794 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3795 bssl::MakeSpan(record.data(), record.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003796 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003797 expect_err();
3798
3799 EXPECT_FALSE(bssl::SealRecord(
3800 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003801 bssl::MakeSpan(suffix.data(), suffix.size() - 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003802 expect_err();
3803 EXPECT_FALSE(bssl::SealRecord(
3804 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003805 bssl::MakeSpan(suffix.data(), suffix.size() + 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003806 expect_err();
3807}
3808
David Benjamin617b8182017-08-29 15:33:10 -04003809// The client should gracefully handle no suitable ciphers being enabled.
3810TEST(SSLTest, NoCiphersAvailable) {
3811 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3812 ASSERT_TRUE(ctx);
3813
3814 // Configure |client_ctx| with a cipher list that does not intersect with its
3815 // version configuration.
3816 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
3817 ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
3818 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
3819
3820 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3821 ASSERT_TRUE(ssl);
3822 SSL_set_connect_state(ssl.get());
3823
3824 UniquePtr<BIO> rbio(BIO_new(BIO_s_mem())), wbio(BIO_new(BIO_s_mem()));
3825 ASSERT_TRUE(rbio);
3826 ASSERT_TRUE(wbio);
3827 SSL_set0_rbio(ssl.get(), rbio.release());
3828 SSL_set0_wbio(ssl.get(), wbio.release());
3829
3830 int ret = SSL_do_handshake(ssl.get());
3831 EXPECT_EQ(-1, ret);
3832 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), ret));
3833 uint32_t err = ERR_get_error();
3834 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
3835 EXPECT_EQ(SSL_R_NO_CIPHERS_AVAILABLE, ERR_GET_REASON(err));
3836}
3837
David Benjamina4bafd32017-10-03 15:06:29 -04003838TEST_P(SSLVersionTest, SessionVersion) {
3839 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3840 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3841
3842 bssl::UniquePtr<SSL_SESSION> session =
3843 CreateClientSession(client_ctx_.get(), server_ctx_.get());
3844 ASSERT_TRUE(session);
3845 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
3846
3847 // Sessions in TLS 1.3 and later should be single-use.
3848 EXPECT_EQ(version() == TLS1_3_VERSION,
3849 !!SSL_SESSION_should_be_single_use(session.get()));
3850
3851 // Making fake sessions for testing works.
3852 session.reset(SSL_SESSION_new(client_ctx_.get()));
3853 ASSERT_TRUE(session);
3854 ASSERT_TRUE(SSL_SESSION_set_protocol_version(session.get(), version()));
3855 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
3856}
3857
David Benjaminfdb7a352017-10-12 17:34:18 -04003858TEST_P(SSLVersionTest, SSLPending) {
3859 UniquePtr<SSL> ssl(SSL_new(client_ctx_.get()));
3860 ASSERT_TRUE(ssl);
3861 EXPECT_EQ(0, SSL_pending(ssl.get()));
3862
3863 ASSERT_TRUE(Connect());
3864 EXPECT_EQ(0, SSL_pending(client_.get()));
3865
3866 ASSERT_EQ(5, SSL_write(server_.get(), "hello", 5));
3867 ASSERT_EQ(5, SSL_write(server_.get(), "world", 5));
3868 EXPECT_EQ(0, SSL_pending(client_.get()));
3869
3870 char buf[10];
3871 ASSERT_EQ(1, SSL_peek(client_.get(), buf, 1));
3872 EXPECT_EQ(5, SSL_pending(client_.get()));
3873
3874 ASSERT_EQ(1, SSL_read(client_.get(), buf, 1));
3875 EXPECT_EQ(4, SSL_pending(client_.get()));
3876
3877 ASSERT_EQ(4, SSL_read(client_.get(), buf, 10));
3878 EXPECT_EQ(0, SSL_pending(client_.get()));
3879
3880 ASSERT_EQ(2, SSL_read(client_.get(), buf, 2));
3881 EXPECT_EQ(3, SSL_pending(client_.get()));
3882}
3883
David Benjamina031b612017-10-11 20:48:25 -04003884// Test that post-handshake tickets consumed by |SSL_shutdown| are ignored.
3885TEST(SSLTest, ShutdownIgnoresTickets) {
3886 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3887 ASSERT_TRUE(ctx);
3888 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_3_VERSION));
3889 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
3890
3891 bssl::UniquePtr<X509> cert = GetTestCertificate();
3892 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3893 ASSERT_TRUE(cert);
3894 ASSERT_TRUE(key);
3895 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
3896 ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
3897
3898 SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_BOTH);
3899
3900 bssl::UniquePtr<SSL> client, server;
3901 ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
3902
3903 SSL_CTX_sess_set_new_cb(ctx.get(), [](SSL *ssl, SSL_SESSION *session) -> int {
3904 ADD_FAILURE() << "New session callback called during SSL_shutdown";
3905 return 0;
3906 });
3907
3908 // Send close_notify.
3909 EXPECT_EQ(0, SSL_shutdown(server.get()));
3910 EXPECT_EQ(0, SSL_shutdown(client.get()));
3911
3912 // Receive close_notify.
3913 EXPECT_EQ(1, SSL_shutdown(server.get()));
3914 EXPECT_EQ(1, SSL_shutdown(client.get()));
3915}
3916
David Benjamin6cc352e2017-11-02 17:21:39 -04003917TEST(SSLTest, SignatureAlgorithmProperties) {
3918 EXPECT_EQ(EVP_PKEY_NONE, SSL_get_signature_algorithm_key_type(0x1234));
3919 EXPECT_EQ(nullptr, SSL_get_signature_algorithm_digest(0x1234));
3920 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(0x1234));
3921
3922 EXPECT_EQ(EVP_PKEY_RSA,
3923 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
3924 EXPECT_EQ(EVP_md5_sha1(),
3925 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
3926 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
3927
3928 EXPECT_EQ(EVP_PKEY_EC, SSL_get_signature_algorithm_key_type(
3929 SSL_SIGN_ECDSA_SECP256R1_SHA256));
3930 EXPECT_EQ(EVP_sha256(), SSL_get_signature_algorithm_digest(
3931 SSL_SIGN_ECDSA_SECP256R1_SHA256));
3932 EXPECT_FALSE(
3933 SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_ECDSA_SECP256R1_SHA256));
3934
3935 EXPECT_EQ(EVP_PKEY_RSA,
David Benjamin6879e192018-04-13 16:01:02 -04003936 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04003937 EXPECT_EQ(EVP_sha384(),
David Benjamin6879e192018-04-13 16:01:02 -04003938 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PSS_RSAE_SHA384));
3939 EXPECT_TRUE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04003940}
3941
Adam Langley85967952018-07-03 08:04:58 -07003942static int XORCompressFunc(SSL *ssl, CBB *out, const uint8_t *in,
3943 size_t in_len) {
3944 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07003945 if (!CBB_add_u8(out, in[i] ^ 0x55)) {
Adam Langley85967952018-07-03 08:04:58 -07003946 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07003947 }
3948 }
3949
3950 SSL_set_app_data(ssl, XORCompressFunc);
3951
Adam Langley85967952018-07-03 08:04:58 -07003952 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07003953}
3954
Adam Langley85967952018-07-03 08:04:58 -07003955static int XORDecompressFunc(SSL *ssl, CRYPTO_BUFFER **out,
3956 size_t uncompressed_len, const uint8_t *in,
3957 size_t in_len) {
3958 if (in_len != uncompressed_len) {
3959 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07003960 }
3961
3962 uint8_t *data;
Adam Langley85967952018-07-03 08:04:58 -07003963 *out = CRYPTO_BUFFER_alloc(&data, uncompressed_len);
3964 if (*out == nullptr) {
3965 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07003966 }
3967
Adam Langley85967952018-07-03 08:04:58 -07003968 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07003969 data[i] = in[i] ^ 0x55;
3970 }
3971
3972 SSL_set_app_data(ssl, XORDecompressFunc);
3973
Adam Langley85967952018-07-03 08:04:58 -07003974 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07003975}
3976
3977TEST(SSLTest, CertCompression) {
3978 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
3979 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
3980 ASSERT_TRUE(client_ctx);
3981 ASSERT_TRUE(server_ctx);
3982
3983 bssl::UniquePtr<X509> cert = GetTestCertificate();
3984 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3985 ASSERT_TRUE(cert);
3986 ASSERT_TRUE(key);
3987 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3988 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3989
3990 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
3991 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
3992 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
3993 client_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
3994 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
3995 server_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
3996
3997 bssl::UniquePtr<SSL> client, server;
3998 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3999 server_ctx.get()));
4000
4001 EXPECT_TRUE(SSL_get_app_data(client.get()) == XORDecompressFunc);
4002 EXPECT_TRUE(SSL_get_app_data(server.get()) == XORCompressFunc);
4003}
4004
Adam Langleyddb57cf2018-01-26 09:17:53 -08004005void MoveBIOs(SSL *dest, SSL *src) {
4006 BIO *rbio = SSL_get_rbio(src);
4007 BIO_up_ref(rbio);
4008 SSL_set0_rbio(dest, rbio);
4009
4010 BIO *wbio = SSL_get_wbio(src);
4011 BIO_up_ref(wbio);
4012 SSL_set0_wbio(dest, wbio);
4013
4014 SSL_set0_rbio(src, nullptr);
4015 SSL_set0_wbio(src, nullptr);
4016}
4017
4018TEST(SSLTest, Handoff) {
4019 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4020 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4021 bssl::UniquePtr<SSL_CTX> handshaker_ctx(SSL_CTX_new(TLS_method()));
4022 ASSERT_TRUE(client_ctx);
4023 ASSERT_TRUE(server_ctx);
4024 ASSERT_TRUE(handshaker_ctx);
4025
4026 SSL_CTX_set_handoff_mode(server_ctx.get(), 1);
4027 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
4028 ASSERT_TRUE(
4029 SSL_CTX_set_max_proto_version(handshaker_ctx.get(), TLS1_2_VERSION));
4030
4031 bssl::UniquePtr<X509> cert = GetTestCertificate();
4032 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4033 ASSERT_TRUE(cert);
4034 ASSERT_TRUE(key);
4035 ASSERT_TRUE(SSL_CTX_use_certificate(handshaker_ctx.get(), cert.get()));
4036 ASSERT_TRUE(SSL_CTX_use_PrivateKey(handshaker_ctx.get(), key.get()));
4037
4038 bssl::UniquePtr<SSL> client, server;
4039 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4040 server_ctx.get(), ClientConfig(),
4041 false /* don't handshake */));
4042
4043 int client_ret = SSL_do_handshake(client.get());
4044 int client_err = SSL_get_error(client.get(), client_ret);
4045 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4046
4047 int server_ret = SSL_do_handshake(server.get());
4048 int server_err = SSL_get_error(server.get(), server_ret);
4049 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
4050
4051 ScopedCBB cbb;
4052 Array<uint8_t> handoff;
4053 ASSERT_TRUE(CBB_init(cbb.get(), 256));
4054 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get()));
4055 ASSERT_TRUE(CBBFinishArray(cbb.get(), &handoff));
4056
4057 bssl::UniquePtr<SSL> handshaker(SSL_new(handshaker_ctx.get()));
4058 ASSERT_TRUE(SSL_apply_handoff(handshaker.get(), handoff));
4059
4060 MoveBIOs(handshaker.get(), server.get());
4061
4062 int handshake_ret = SSL_do_handshake(handshaker.get());
4063 int handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
Matthew Braithwaite56986f92018-03-22 11:48:33 -07004064 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
Adam Langleyddb57cf2018-01-26 09:17:53 -08004065
Matthew Braithwaite56986f92018-03-22 11:48:33 -07004066 // Double-check that additional calls to |SSL_do_handshake| continue
4067 // to get |SSL_ERRROR_HANDBACK|.
4068 handshake_ret = SSL_do_handshake(handshaker.get());
4069 handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
4070 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
Adam Langleyddb57cf2018-01-26 09:17:53 -08004071
4072 ScopedCBB cbb_handback;
4073 Array<uint8_t> handback;
4074 ASSERT_TRUE(CBB_init(cbb_handback.get(), 1024));
4075 ASSERT_TRUE(SSL_serialize_handback(handshaker.get(), cbb_handback.get()));
4076 ASSERT_TRUE(CBBFinishArray(cbb_handback.get(), &handback));
4077
4078 bssl::UniquePtr<SSL> server2(SSL_new(server_ctx.get()));
4079 ASSERT_TRUE(SSL_apply_handback(server2.get(), handback));
4080
4081 MoveBIOs(server2.get(), handshaker.get());
Matthew Braithwaite56986f92018-03-22 11:48:33 -07004082 ASSERT_TRUE(CompleteHandshakes(client.get(), server2.get()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004083
4084 uint8_t byte = 42;
4085 EXPECT_EQ(SSL_write(client.get(), &byte, 1), 1);
4086 EXPECT_EQ(SSL_read(server2.get(), &byte, 1), 1);
4087 EXPECT_EQ(42, byte);
4088
4089 byte = 43;
4090 EXPECT_EQ(SSL_write(server2.get(), &byte, 1), 1);
4091 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
4092 EXPECT_EQ(43, byte);
4093}
4094
4095TEST(SSLTest, HandoffDeclined) {
4096 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4097 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4098 ASSERT_TRUE(client_ctx);
4099 ASSERT_TRUE(server_ctx);
4100
4101 SSL_CTX_set_handoff_mode(server_ctx.get(), 1);
4102 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
4103
4104 bssl::UniquePtr<X509> cert = GetTestCertificate();
4105 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4106 ASSERT_TRUE(cert);
4107 ASSERT_TRUE(key);
4108 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
4109 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
4110
4111 bssl::UniquePtr<SSL> client, server;
4112 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4113 server_ctx.get(), ClientConfig(),
4114 false /* don't handshake */));
4115
4116 int client_ret = SSL_do_handshake(client.get());
4117 int client_err = SSL_get_error(client.get(), client_ret);
4118 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4119
4120 int server_ret = SSL_do_handshake(server.get());
4121 int server_err = SSL_get_error(server.get(), server_ret);
4122 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
4123
4124 ScopedCBB cbb;
4125 ASSERT_TRUE(CBB_init(cbb.get(), 256));
4126 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get()));
4127
4128 ASSERT_TRUE(SSL_decline_handoff(server.get()));
4129
4130 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
4131
4132 uint8_t byte = 42;
4133 EXPECT_EQ(SSL_write(client.get(), &byte, 1), 1);
4134 EXPECT_EQ(SSL_read(server.get(), &byte, 1), 1);
4135 EXPECT_EQ(42, byte);
4136
4137 byte = 43;
4138 EXPECT_EQ(SSL_write(server.get(), &byte, 1), 1);
4139 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
4140 EXPECT_EQ(43, byte);
4141}
4142
Adam Langley826ce152018-08-03 10:31:21 -07004143static std::string SigAlgsToString(Span<const uint16_t> sigalgs) {
4144 std::string ret = "{";
4145
4146 for (uint16_t v : sigalgs) {
4147 if (ret.size() > 1) {
4148 ret += ", ";
4149 }
4150
4151 char buf[8];
4152 snprintf(buf, sizeof(buf) - 1, "0x%02x", v);
4153 buf[sizeof(buf)-1] = 0;
4154 ret += std::string(buf);
4155 }
4156
4157 ret += "}";
4158 return ret;
4159}
4160
4161void ExpectSigAlgsEqual(Span<const uint16_t> expected,
4162 Span<const uint16_t> actual) {
4163 bool matches = false;
4164 if (expected.size() == actual.size()) {
4165 matches = true;
4166
4167 for (size_t i = 0; i < expected.size(); i++) {
4168 if (expected[i] != actual[i]) {
4169 matches = false;
4170 break;
4171 }
4172 }
4173 }
4174
4175 if (!matches) {
4176 ADD_FAILURE() << "expected: " << SigAlgsToString(expected)
4177 << " got: " << SigAlgsToString(actual);
4178 }
4179}
4180
4181TEST(SSLTest, SigAlgs) {
4182 static const struct {
4183 std::vector<int> input;
4184 bool ok;
4185 std::vector<uint16_t> expected;
4186 } kTests[] = {
4187 {{}, true, {}},
4188 {{1}, false, {}},
4189 {{1, 2, 3}, false, {}},
4190 {{NID_sha256, EVP_PKEY_ED25519}, false, {}},
4191 {{NID_sha256, EVP_PKEY_RSA, NID_sha256, EVP_PKEY_RSA}, false, {}},
4192
4193 {{NID_sha256, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA256}},
4194 {{NID_sha512, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA512}},
4195 {{NID_sha256, EVP_PKEY_RSA_PSS}, true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4196 {{NID_undef, EVP_PKEY_ED25519}, true, {SSL_SIGN_ED25519}},
4197 {{NID_undef, EVP_PKEY_ED25519, NID_sha384, EVP_PKEY_EC},
4198 true,
4199 {SSL_SIGN_ED25519, SSL_SIGN_ECDSA_SECP384R1_SHA384}},
4200 };
4201
4202 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4203
4204 unsigned n = 1;
4205 for (const auto &test : kTests) {
4206 SCOPED_TRACE(n++);
4207
4208 const bool ok =
4209 SSL_CTX_set1_sigalgs(ctx.get(), test.input.data(), test.input.size());
4210 EXPECT_EQ(ok, test.ok);
4211
4212 if (!ok) {
4213 ERR_clear_error();
4214 }
4215
4216 if (!test.ok) {
4217 continue;
4218 }
4219
4220 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
4221 }
4222}
4223
4224TEST(SSLTest, SigAlgsList) {
4225 static const struct {
4226 const char *input;
4227 bool ok;
4228 std::vector<uint16_t> expected;
4229 } kTests[] = {
4230 {"", false, {}},
4231 {":", false, {}},
4232 {"+", false, {}},
4233 {"RSA", false, {}},
4234 {"RSA+", false, {}},
4235 {"RSA+SHA256:", false, {}},
4236 {":RSA+SHA256:", false, {}},
4237 {":RSA+SHA256+:", false, {}},
4238 {"!", false, {}},
4239 {"\x01", false, {}},
4240 {"RSA+SHA256:RSA+SHA384:RSA+SHA256", false, {}},
4241 {"RSA-PSS+SHA256:rsa_pss_rsae_sha256", false, {}},
4242
4243 {"RSA+SHA256", true, {SSL_SIGN_RSA_PKCS1_SHA256}},
4244 {"RSA+SHA256:ed25519",
4245 true,
4246 {SSL_SIGN_RSA_PKCS1_SHA256, SSL_SIGN_ED25519}},
4247 {"ECDSA+SHA256:RSA+SHA512",
4248 true,
4249 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PKCS1_SHA512}},
4250 {"ecdsa_secp256r1_sha256:rsa_pss_rsae_sha256",
4251 true,
4252 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4253 {"RSA-PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4254 {"PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4255 };
4256
4257 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4258
4259 unsigned n = 1;
4260 for (const auto &test : kTests) {
4261 SCOPED_TRACE(n++);
4262
4263 const bool ok = SSL_CTX_set1_sigalgs_list(ctx.get(), test.input);
4264 EXPECT_EQ(ok, test.ok);
4265
4266 if (!ok) {
4267 if (test.ok) {
4268 ERR_print_errors_fp(stderr);
4269 }
4270 ERR_clear_error();
4271 }
4272
4273 if (!test.ok) {
4274 continue;
4275 }
4276
4277 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
4278 }
4279}
4280
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004281TEST(SSLTest, ApplyHandoffRemovesUnsupportedCiphers) {
4282 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4283 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
4284
4285 // handoff is a handoff message that has been artificially modified to pretend
4286 // that only cipher 0x0A is supported. When it is applied to |server|, all
4287 // ciphers but that one should be removed.
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004288 //
4289 // To make a new one of these, try sticking this in the |Handoff| test above:
4290 //
4291 // hexdump(stderr, "", handoff.data(), handoff.size());
4292 // sed -e 's/\(..\)/0x\1, /g'
4293 //
4294 // and modify serialize_features() to emit only cipher 0x0A.
4295
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004296 uint8_t handoff[] = {
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004297 0x30, 0x81, 0x9a, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
4298 0x00, 0x00, 0x7e, 0x03, 0x03, 0x30, 0x8e, 0x8f, 0x79, 0xd2, 0x87, 0x39,
4299 0xc2, 0x23, 0x23, 0x13, 0xca, 0x3c, 0x80, 0x44, 0xfd, 0x80, 0x83, 0x62,
4300 0x3c, 0xcc, 0xf8, 0x76, 0xd3, 0x62, 0xbb, 0x54, 0xe3, 0xc4, 0x39, 0x24,
4301 0xa5, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004302 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
4303 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004304 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
4305 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
4306 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
4307 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
4308 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x02, 0x00,
4309 0x0a, 0x04, 0x0a, 0x00, 0x15, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00,
4310 0x1d,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004311 };
4312
4313 EXPECT_EQ(20u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
4314 ASSERT_TRUE(
4315 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
4316 EXPECT_EQ(1u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
4317}
4318
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004319TEST(SSLTest, ApplyHandoffRemovesUnsupportedCurves) {
4320 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4321 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
4322
4323 // handoff is a handoff message that has been artificially modified to pretend
4324 // that only one curve is supported. When it is applied to |server|, all
4325 // curves but that one should be removed.
4326 //
4327 // See |ApplyHandoffRemovesUnsupportedCiphers| for how to make a new one of
4328 // these.
4329 uint8_t handoff[] = {
4330 0x30, 0x81, 0xc0, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
4331 0x00, 0x00, 0x7e, 0x03, 0x03, 0x98, 0x30, 0xce, 0xd9, 0xb0, 0xdf, 0x5f,
4332 0x82, 0x05, 0x4a, 0x43, 0x67, 0x7e, 0xdb, 0x6a, 0x4f, 0x21, 0x18, 0x4e,
4333 0x0d, 0x94, 0x63, 0x18, 0x8b, 0x54, 0x89, 0xdb, 0x8b, 0x1d, 0x84, 0xbc,
4334 0x09, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
4335 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
4336 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
4337 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
4338 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
4339 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
4340 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
4341 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x30, 0x00,
4342 0x02, 0x00, 0x0a, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x8c, 0x00, 0x8d, 0x00,
4343 0x9c, 0x00, 0x9d, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xc0, 0x09, 0xc0,
4344 0x0a, 0xc0, 0x13, 0xc0, 0x14, 0xc0, 0x2b, 0xc0, 0x2c, 0xc0, 0x2f, 0xc0,
4345 0x30, 0xc0, 0x35, 0xc0, 0x36, 0xcc, 0xa8, 0xcc, 0xa9, 0xcc, 0xac, 0x04,
4346 0x02, 0x00, 0x17,
4347 };
4348
4349 // The zero length means that the default list of groups is used.
4350 EXPECT_EQ(0u, server->config->supported_group_list.size());
4351 ASSERT_TRUE(
4352 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
4353 EXPECT_EQ(1u, server->config->supported_group_list.size());
4354}
4355
Adam Langleyba9ad662018-12-17 13:59:38 -08004356TEST(SSLTest, ZeroSizedWiteFlushesHandshakeMessages) {
4357 // If there are pending handshake mesages, an |SSL_write| of zero bytes should
4358 // flush them.
4359 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4360 EXPECT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
4361 EXPECT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
4362 bssl::UniquePtr<X509> cert = GetTestCertificate();
4363 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4364 ASSERT_TRUE(cert);
4365 ASSERT_TRUE(key);
4366 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
4367 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
4368
4369 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4370 EXPECT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
4371 EXPECT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
4372
4373 bssl::UniquePtr<SSL> client, server;
4374 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4375 server_ctx.get()));
4376
4377 BIO *client_wbio = SSL_get_wbio(client.get());
4378 EXPECT_EQ(0u, BIO_wpending(client_wbio));
4379 EXPECT_TRUE(SSL_key_update(client.get(), SSL_KEY_UPDATE_NOT_REQUESTED));
4380 EXPECT_EQ(0u, BIO_wpending(client_wbio));
4381 EXPECT_EQ(0, SSL_write(client.get(), nullptr, 0));
4382 EXPECT_NE(0u, BIO_wpending(client_wbio));
4383}
4384
David Benjamin5869eb32018-07-17 00:59:45 -04004385TEST_P(SSLVersionTest, VerifyBeforeCertRequest) {
4386 // Configure the server to request client certificates.
4387 SSL_CTX_set_custom_verify(
4388 server_ctx_.get(), SSL_VERIFY_PEER,
4389 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
4390
4391 // Configure the client to reject the server certificate.
4392 SSL_CTX_set_custom_verify(
4393 client_ctx_.get(), SSL_VERIFY_PEER,
4394 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_invalid; });
4395
4396 // cert_cb should not be called. Verification should fail first.
4397 SSL_CTX_set_cert_cb(client_ctx_.get(),
4398 [](SSL *ssl, void *arg) {
4399 ADD_FAILURE() << "cert_cb unexpectedly called";
4400 return 0;
4401 },
4402 nullptr);
4403
4404 bssl::UniquePtr<SSL> client, server;
4405 EXPECT_FALSE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
4406 server_ctx_.get()));
4407}
4408
David Benjamin492c9aa2018-08-31 16:35:22 -05004409// Test that ticket-based sessions on the client get fake session IDs.
4410TEST_P(SSLVersionTest, FakeIDsForTickets) {
4411 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4412 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4413
4414 bssl::UniquePtr<SSL_SESSION> session =
4415 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4416 ASSERT_TRUE(session);
4417
4418 EXPECT_TRUE(SSL_SESSION_has_ticket(session.get()));
4419 unsigned session_id_length;
4420 SSL_SESSION_get_id(session.get(), &session_id_length);
4421 EXPECT_NE(session_id_length, 0u);
4422}
4423
David Benjamin6c04bd12018-07-19 18:13:09 -04004424// These tests test multi-threaded behavior. They are intended to run with
4425// ThreadSanitizer.
David Benjamin5b33eff2018-09-22 16:52:48 -07004426#if defined(OPENSSL_THREADS)
David Benjamin6c04bd12018-07-19 18:13:09 -04004427TEST_P(SSLVersionTest, SessionCacheThreads) {
4428 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
4429 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4430 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4431
4432 if (version() == TLS1_3_VERSION) {
4433 // Our TLS 1.3 implementation does not support stateful resumption.
4434 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
4435 return;
4436 }
4437
4438 // Establish two client sessions to test with.
4439 bssl::UniquePtr<SSL_SESSION> session1 =
4440 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4441 ASSERT_TRUE(session1);
4442 bssl::UniquePtr<SSL_SESSION> session2 =
4443 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4444 ASSERT_TRUE(session2);
4445
4446 auto connect_with_session = [&](SSL_SESSION *session) {
4447 ClientConfig config;
4448 config.session = session;
4449 UniquePtr<SSL> client, server;
4450 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
4451 server_ctx_.get(), config));
4452 };
4453
4454 // Resume sessions in parallel with establishing new ones.
4455 {
4456 std::vector<std::thread> threads;
4457 threads.emplace_back([&] { connect_with_session(nullptr); });
4458 threads.emplace_back([&] { connect_with_session(nullptr); });
4459 threads.emplace_back([&] { connect_with_session(session1.get()); });
4460 threads.emplace_back([&] { connect_with_session(session1.get()); });
4461 threads.emplace_back([&] { connect_with_session(session2.get()); });
4462 threads.emplace_back([&] { connect_with_session(session2.get()); });
4463 for (auto &thread : threads) {
4464 thread.join();
4465 }
4466 }
4467
4468 // Hit the maximum session cache size across multiple threads
4469 size_t limit = SSL_CTX_sess_number(server_ctx_.get()) + 2;
4470 SSL_CTX_sess_set_cache_size(server_ctx_.get(), limit);
4471 {
4472 std::vector<std::thread> threads;
4473 for (int i = 0; i < 4; i++) {
4474 threads.emplace_back([&]() {
4475 connect_with_session(nullptr);
4476 EXPECT_LE(SSL_CTX_sess_number(server_ctx_.get()), limit);
4477 });
4478 }
4479 for (auto &thread : threads) {
4480 thread.join();
4481 }
4482 EXPECT_EQ(SSL_CTX_sess_number(server_ctx_.get()), limit);
4483 }
4484}
4485
4486TEST_P(SSLVersionTest, SessionTicketThreads) {
4487 for (bool renew_ticket : {false, true}) {
4488 SCOPED_TRACE(renew_ticket);
4489 ResetContexts();
4490 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4491 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4492 if (renew_ticket) {
4493 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
4494 }
4495
4496 // Establish two client sessions to test with.
4497 bssl::UniquePtr<SSL_SESSION> session1 =
4498 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4499 ASSERT_TRUE(session1);
4500 bssl::UniquePtr<SSL_SESSION> session2 =
4501 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4502 ASSERT_TRUE(session2);
4503
4504 auto connect_with_session = [&](SSL_SESSION *session) {
4505 ClientConfig config;
4506 config.session = session;
4507 UniquePtr<SSL> client, server;
4508 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
4509 server_ctx_.get(), config));
4510 };
4511
4512 // Resume sessions in parallel with establishing new ones.
4513 {
4514 std::vector<std::thread> threads;
4515 threads.emplace_back([&] { connect_with_session(nullptr); });
4516 threads.emplace_back([&] { connect_with_session(nullptr); });
4517 threads.emplace_back([&] { connect_with_session(session1.get()); });
4518 threads.emplace_back([&] { connect_with_session(session1.get()); });
4519 threads.emplace_back([&] { connect_with_session(session2.get()); });
4520 threads.emplace_back([&] { connect_with_session(session2.get()); });
4521 for (auto &thread : threads) {
4522 thread.join();
4523 }
4524 }
4525 }
4526}
4527
4528// SSL_CTX_get0_certificate needs to lock internally. Test this works.
4529TEST(SSLTest, GetCertificateThreads) {
4530 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4531 ASSERT_TRUE(ctx);
4532 bssl::UniquePtr<X509> cert = GetTestCertificate();
4533 ASSERT_TRUE(cert);
4534 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
4535
4536 // Existing code expects |SSL_CTX_get0_certificate| to be callable from two
4537 // threads concurrently. It originally was an immutable operation. Now we
4538 // implement it with a thread-safe cache, so it is worth testing.
4539 X509 *cert2_thread;
4540 std::thread thread(
4541 [&] { cert2_thread = SSL_CTX_get0_certificate(ctx.get()); });
4542 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
4543 thread.join();
4544
4545 EXPECT_EQ(cert2, cert2_thread);
4546 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
4547}
David Benjamin4cce9552018-12-13 12:20:54 -06004548
4549// Functions which access properties on the negotiated session are thread-safe
4550// where needed. Prior to TLS 1.3, clients resuming sessions and servers
4551// performing stateful resumption will share an underlying SSL_SESSION object,
4552// potentially across threads.
4553TEST_P(SSLVersionTest, SessionPropertiesThreads) {
4554 if (version() == TLS1_3_VERSION) {
4555 // Our TLS 1.3 implementation does not support stateful resumption.
4556 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
4557 return;
4558 }
4559
4560 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
4561 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4562 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4563
4564 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
4565 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
4566
4567 // Configure mutual authentication, so we have more session state.
4568 SSL_CTX_set_custom_verify(
4569 client_ctx_.get(), SSL_VERIFY_PEER,
4570 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
4571 SSL_CTX_set_custom_verify(
4572 server_ctx_.get(), SSL_VERIFY_PEER,
4573 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
4574
4575 // Establish a client session to test with.
4576 bssl::UniquePtr<SSL_SESSION> session =
4577 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4578 ASSERT_TRUE(session);
4579
4580 // Resume with it twice.
4581 UniquePtr<SSL> ssls[4];
4582 ClientConfig config;
4583 config.session = session.get();
4584 ASSERT_TRUE(ConnectClientAndServer(&ssls[0], &ssls[1], client_ctx_.get(),
4585 server_ctx_.get(), config));
4586 ASSERT_TRUE(ConnectClientAndServer(&ssls[2], &ssls[3], client_ctx_.get(),
4587 server_ctx_.get(), config));
4588
4589 // Read properties in parallel.
4590 auto read_properties = [](const SSL *ssl) {
4591 EXPECT_TRUE(SSL_get_peer_cert_chain(ssl));
4592 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(ssl));
4593 EXPECT_TRUE(peer);
4594 EXPECT_TRUE(SSL_get_current_cipher(ssl));
4595 EXPECT_TRUE(SSL_get_curve_id(ssl));
4596 };
4597
4598 std::vector<std::thread> threads;
4599 for (const auto &ssl_ptr : ssls) {
4600 const SSL *ssl = ssl_ptr.get();
4601 threads.emplace_back([=] { read_properties(ssl); });
4602 }
4603 for (auto &thread : threads) {
4604 thread.join();
4605 }
4606}
David Benjamin6c04bd12018-07-19 18:13:09 -04004607#endif
4608
Steven Valdezc8e0f902018-07-14 11:23:01 -04004609constexpr size_t kNumQUICLevels = 4;
4610static_assert(ssl_encryption_initial < kNumQUICLevels,
4611 "kNumQUICLevels is wrong");
4612static_assert(ssl_encryption_early_data < kNumQUICLevels,
4613 "kNumQUICLevels is wrong");
4614static_assert(ssl_encryption_handshake < kNumQUICLevels,
4615 "kNumQUICLevels is wrong");
4616static_assert(ssl_encryption_application < kNumQUICLevels,
4617 "kNumQUICLevels is wrong");
4618
4619class MockQUICTransport {
4620 public:
4621 MockQUICTransport() {
4622 // The caller is expected to configure initial secrets.
4623 levels_[ssl_encryption_initial].write_secret = {1};
4624 levels_[ssl_encryption_initial].read_secret = {1};
4625 }
4626
4627 void set_peer(MockQUICTransport *peer) { peer_ = peer; }
4628
4629 bool has_alert() const { return has_alert_; }
4630 ssl_encryption_level_t alert_level() const { return alert_level_; }
4631 uint8_t alert() const { return alert_; }
4632
4633 bool PeerSecretsMatch(ssl_encryption_level_t level) const {
4634 return levels_[level].write_secret == peer_->levels_[level].read_secret &&
Steven Valdez384d0ea2018-11-06 10:45:36 -05004635 levels_[level].read_secret == peer_->levels_[level].write_secret &&
4636 levels_[level].cipher == peer_->levels_[level].cipher;
Steven Valdezc8e0f902018-07-14 11:23:01 -04004637 }
4638
4639 bool HasSecrets(ssl_encryption_level_t level) const {
4640 return !levels_[level].write_secret.empty() ||
4641 !levels_[level].read_secret.empty();
4642 }
4643
4644 bool SetEncryptionSecrets(ssl_encryption_level_t level,
4645 const uint8_t *read_secret,
Steven Valdez384d0ea2018-11-06 10:45:36 -05004646 const uint8_t *write_secret, size_t secret_len,
4647 const SSL_CIPHER *cipher) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04004648 if (HasSecrets(level)) {
4649 ADD_FAILURE() << "duplicate keys configured";
4650 return false;
4651 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05004652
4653 if (cipher == nullptr) {
4654 ADD_FAILURE() << "current cipher unavailable";
4655 return false;
4656 }
4657
Steven Valdezc8e0f902018-07-14 11:23:01 -04004658 if (level != ssl_encryption_early_data &&
4659 (read_secret == nullptr || write_secret == nullptr)) {
4660 ADD_FAILURE() << "key was unexpectedly null";
4661 return false;
4662 }
4663 if (read_secret != nullptr) {
4664 levels_[level].read_secret.assign(read_secret, read_secret + secret_len);
4665 }
4666 if (write_secret != nullptr) {
4667 levels_[level].write_secret.assign(write_secret,
4668 write_secret + secret_len);
4669 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05004670 levels_[level].cipher = SSL_CIPHER_get_id(cipher);
Steven Valdezc8e0f902018-07-14 11:23:01 -04004671 return true;
4672 }
4673
4674 bool WriteHandshakeData(ssl_encryption_level_t level,
4675 Span<const uint8_t> data) {
4676 if (levels_[level].write_secret.empty()) {
4677 ADD_FAILURE() << "data written before keys configured";
4678 return false;
4679 }
4680 levels_[level].write_data.insert(levels_[level].write_data.end(),
4681 data.begin(), data.end());
4682 return true;
4683 }
4684
4685 bool SendAlert(ssl_encryption_level_t level, uint8_t alert_value) {
4686 if (has_alert_) {
4687 ADD_FAILURE() << "duplicate alert sent";
4688 return false;
4689 }
4690
4691 if (levels_[level].write_secret.empty()) {
4692 ADD_FAILURE() << "alert sent before keys configured";
4693 return false;
4694 }
4695
4696 has_alert_ = true;
4697 alert_level_ = level;
4698 alert_ = alert_value;
4699 return true;
4700 }
4701
4702 bool ReadHandshakeData(std::vector<uint8_t> *out,
4703 ssl_encryption_level_t level,
4704 size_t num = std::numeric_limits<size_t>::max()) {
4705 if (levels_[level].read_secret.empty()) {
4706 ADD_FAILURE() << "data read before keys configured";
4707 return false;
4708 }
4709 // The peer may not have configured any keys yet.
4710 if (peer_->levels_[level].write_secret.empty()) {
4711 return true;
4712 }
4713 // Check the peer computed the same key.
4714 if (peer_->levels_[level].write_secret != levels_[level].read_secret) {
4715 ADD_FAILURE() << "peer write key does not match read key";
4716 return false;
4717 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05004718 if (peer_->levels_[level].cipher != levels_[level].cipher) {
4719 ADD_FAILURE() << "peer cipher does not match";
4720 return false;
4721 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04004722 std::vector<uint8_t> *peer_data = &peer_->levels_[level].write_data;
4723 num = std::min(num, peer_data->size());
4724 out->assign(peer_data->begin(), peer_data->begin() + num);
4725 peer_data->erase(peer_data->begin(), peer_data->begin() + num);
4726 return true;
4727 }
4728
4729 private:
4730 MockQUICTransport *peer_ = nullptr;
4731
4732 bool has_alert_ = false;
4733 ssl_encryption_level_t alert_level_ = ssl_encryption_initial;
4734 uint8_t alert_ = 0;
4735
4736 struct Level {
4737 std::vector<uint8_t> write_data;
4738 std::vector<uint8_t> write_secret;
4739 std::vector<uint8_t> read_secret;
Steven Valdez384d0ea2018-11-06 10:45:36 -05004740 uint32_t cipher = 0;
Steven Valdezc8e0f902018-07-14 11:23:01 -04004741 };
4742 Level levels_[kNumQUICLevels];
4743};
4744
4745class MockQUICTransportPair {
4746 public:
4747 MockQUICTransportPair() {
4748 server_.set_peer(&client_);
4749 client_.set_peer(&server_);
4750 }
4751
4752 ~MockQUICTransportPair() {
4753 server_.set_peer(nullptr);
4754 client_.set_peer(nullptr);
4755 }
4756
4757 MockQUICTransport *client() { return &client_; }
4758 MockQUICTransport *server() { return &server_; }
4759
4760 bool SecretsMatch(ssl_encryption_level_t level) const {
4761 return client_.PeerSecretsMatch(level);
4762 }
4763
4764 private:
4765 MockQUICTransport client_;
4766 MockQUICTransport server_;
4767};
4768
4769class QUICMethodTest : public testing::Test {
4770 protected:
4771 void SetUp() override {
4772 client_ctx_.reset(SSL_CTX_new(TLS_method()));
4773 server_ctx_.reset(SSL_CTX_new(TLS_method()));
4774 ASSERT_TRUE(client_ctx_);
4775 ASSERT_TRUE(server_ctx_);
4776
4777 bssl::UniquePtr<X509> cert = GetTestCertificate();
4778 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4779 ASSERT_TRUE(cert);
4780 ASSERT_TRUE(key);
4781 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx_.get(), cert.get()));
4782 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx_.get(), key.get()));
4783
4784 SSL_CTX_set_min_proto_version(server_ctx_.get(), TLS1_3_VERSION);
4785 SSL_CTX_set_max_proto_version(server_ctx_.get(), TLS1_3_VERSION);
4786 SSL_CTX_set_min_proto_version(client_ctx_.get(), TLS1_3_VERSION);
4787 SSL_CTX_set_max_proto_version(client_ctx_.get(), TLS1_3_VERSION);
4788 }
4789
4790 static MockQUICTransport *TransportFromSSL(const SSL *ssl) {
4791 return ex_data_.Get(ssl);
4792 }
4793
4794 static bool ProvideHandshakeData(
4795 SSL *ssl, size_t num = std::numeric_limits<size_t>::max()) {
4796 MockQUICTransport *transport = TransportFromSSL(ssl);
4797 ssl_encryption_level_t level = SSL_quic_read_level(ssl);
4798 std::vector<uint8_t> data;
4799 return transport->ReadHandshakeData(&data, level, num) &&
4800 SSL_provide_quic_data(ssl, level, data.data(), data.size());
4801 }
4802
4803 bool CreateClientAndServer() {
4804 client_.reset(SSL_new(client_ctx_.get()));
4805 server_.reset(SSL_new(server_ctx_.get()));
4806 if (!client_ || !server_) {
4807 return false;
4808 }
4809
4810 SSL_set_connect_state(client_.get());
4811 SSL_set_accept_state(server_.get());
4812
4813 ex_data_.Set(client_.get(), transport_.client());
4814 ex_data_.Set(server_.get(), transport_.server());
4815 return true;
4816 }
4817
Steven Valdeze6eef1c2018-11-09 13:32:34 -05004818 bool CreateSecondClientAndServer() {
4819 client_.reset(SSL_new(client_ctx_.get()));
4820 server_.reset(SSL_new(server_ctx_.get()));
4821 if (!client_ || !server_) {
4822 return false;
4823 }
4824
4825 SSL_set_connect_state(client_.get());
4826 SSL_set_accept_state(server_.get());
4827
4828 ex_data_.Set(client_.get(), second_transport_.client());
4829 ex_data_.Set(server_.get(), second_transport_.server());
4830 return true;
4831 }
4832
Steven Valdezc8e0f902018-07-14 11:23:01 -04004833 // The following functions may be configured on an |SSL_QUIC_METHOD| as
4834 // default implementations.
4835
4836 static int SetEncryptionSecretsCallback(SSL *ssl,
4837 ssl_encryption_level_t level,
4838 const uint8_t *read_key,
4839 const uint8_t *write_key,
4840 size_t key_len) {
Steven Valdez384d0ea2018-11-06 10:45:36 -05004841 return TransportFromSSL(ssl)->SetEncryptionSecrets(
4842 level, read_key, write_key, key_len, SSL_get_current_cipher(ssl));
Steven Valdezc8e0f902018-07-14 11:23:01 -04004843 }
4844
David Benjamincc9d9352018-10-30 19:45:22 -05004845 static int AddHandshakeDataCallback(SSL *ssl,
4846 enum ssl_encryption_level_t level,
4847 const uint8_t *data, size_t len) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04004848 EXPECT_EQ(level, SSL_quic_write_level(ssl));
4849 return TransportFromSSL(ssl)->WriteHandshakeData(level,
4850 MakeConstSpan(data, len));
4851 }
4852
4853 static int FlushFlightCallback(SSL *ssl) { return 1; }
4854
4855 static int SendAlertCallback(SSL *ssl, ssl_encryption_level_t level,
4856 uint8_t alert) {
4857 EXPECT_EQ(level, SSL_quic_write_level(ssl));
4858 return TransportFromSSL(ssl)->SendAlert(level, alert);
4859 }
4860
4861 bssl::UniquePtr<SSL_CTX> client_ctx_;
4862 bssl::UniquePtr<SSL_CTX> server_ctx_;
4863
4864 static UnownedSSLExData<MockQUICTransport> ex_data_;
4865 MockQUICTransportPair transport_;
Steven Valdeze6eef1c2018-11-09 13:32:34 -05004866 MockQUICTransportPair second_transport_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04004867
4868 bssl::UniquePtr<SSL> client_;
4869 bssl::UniquePtr<SSL> server_;
4870};
4871
4872UnownedSSLExData<MockQUICTransport> QUICMethodTest::ex_data_;
4873
4874// Test a full handshake works.
4875TEST_F(QUICMethodTest, Basic) {
4876 const SSL_QUIC_METHOD quic_method = {
4877 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05004878 AddHandshakeDataCallback,
Steven Valdezc8e0f902018-07-14 11:23:01 -04004879 FlushFlightCallback,
4880 SendAlertCallback,
4881 };
4882
Steven Valdeze6eef1c2018-11-09 13:32:34 -05004883 g_last_session = nullptr;
4884
4885 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4886 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
Steven Valdezc8e0f902018-07-14 11:23:01 -04004887 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
4888 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
4889 ASSERT_TRUE(CreateClientAndServer());
4890
4891 for (;;) {
4892 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
4893 int client_ret = SSL_do_handshake(client_.get());
4894 if (client_ret != 1) {
4895 ASSERT_EQ(client_ret, -1);
4896 ASSERT_EQ(SSL_get_error(client_.get(), client_ret), SSL_ERROR_WANT_READ);
4897 }
4898
4899 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
4900 int server_ret = SSL_do_handshake(server_.get());
4901 if (server_ret != 1) {
4902 ASSERT_EQ(server_ret, -1);
4903 ASSERT_EQ(SSL_get_error(server_.get(), server_ret), SSL_ERROR_WANT_READ);
4904 }
4905
4906 if (client_ret == 1 && server_ret == 1) {
4907 break;
4908 }
4909 }
4910
4911 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
4912 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
4913 EXPECT_TRUE(transport_.SecretsMatch(ssl_encryption_application));
4914 EXPECT_FALSE(transport_.client()->has_alert());
4915 EXPECT_FALSE(transport_.server()->has_alert());
4916
4917 // The server sent NewSessionTicket messages in the handshake.
Steven Valdeze6eef1c2018-11-09 13:32:34 -05004918 EXPECT_FALSE(g_last_session);
4919 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
4920 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
4921 EXPECT_TRUE(g_last_session);
4922
4923 // Create a second connection to verify resumption works.
4924 ASSERT_TRUE(CreateSecondClientAndServer());
4925 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
4926 SSL_set_session(client_.get(), session.get());
4927
4928 for (;;) {
4929 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
4930 int client_ret = SSL_do_handshake(client_.get());
4931 if (client_ret != 1) {
4932 ASSERT_EQ(client_ret, -1);
4933 ASSERT_EQ(SSL_get_error(client_.get(), client_ret), SSL_ERROR_WANT_READ);
4934 }
4935
4936 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
4937 int server_ret = SSL_do_handshake(server_.get());
4938 if (server_ret != 1) {
4939 ASSERT_EQ(server_ret, -1);
4940 ASSERT_EQ(SSL_get_error(server_.get(), server_ret), SSL_ERROR_WANT_READ);
4941 }
4942
4943 if (client_ret == 1 && server_ret == 1) {
4944 break;
4945 }
4946 }
4947
4948 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
4949 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
4950 EXPECT_TRUE(transport_.SecretsMatch(ssl_encryption_application));
4951 EXPECT_FALSE(transport_.client()->has_alert());
4952 EXPECT_FALSE(transport_.server()->has_alert());
4953 EXPECT_TRUE(SSL_session_reused(client_.get()));
4954 EXPECT_TRUE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04004955}
4956
4957// Test only releasing data to QUIC one byte at a time on request, to maximize
4958// state machine pauses. Additionally, test that existing asynchronous callbacks
4959// still work.
4960TEST_F(QUICMethodTest, Async) {
4961 const SSL_QUIC_METHOD quic_method = {
4962 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05004963 AddHandshakeDataCallback,
Steven Valdezc8e0f902018-07-14 11:23:01 -04004964 FlushFlightCallback,
4965 SendAlertCallback,
4966 };
4967
4968 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
4969 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
4970 ASSERT_TRUE(CreateClientAndServer());
4971
4972 // Install an asynchronous certificate callback.
4973 bool cert_cb_ok = false;
4974 SSL_set_cert_cb(server_.get(),
4975 [](SSL *, void *arg) -> int {
4976 return *static_cast<bool *>(arg) ? 1 : -1;
4977 },
4978 &cert_cb_ok);
4979
4980 for (;;) {
4981 int client_ret = SSL_do_handshake(client_.get());
4982 if (client_ret != 1) {
4983 ASSERT_EQ(client_ret, -1);
4984 ASSERT_EQ(SSL_get_error(client_.get(), client_ret), SSL_ERROR_WANT_READ);
4985 ASSERT_TRUE(ProvideHandshakeData(client_.get(), 1));
4986 }
4987
4988 int server_ret = SSL_do_handshake(server_.get());
4989 if (server_ret != 1) {
4990 ASSERT_EQ(server_ret, -1);
4991 int ssl_err = SSL_get_error(server_.get(), server_ret);
4992 switch (ssl_err) {
4993 case SSL_ERROR_WANT_READ:
4994 ASSERT_TRUE(ProvideHandshakeData(server_.get(), 1));
4995 break;
4996 case SSL_ERROR_WANT_X509_LOOKUP:
4997 ASSERT_FALSE(cert_cb_ok);
4998 cert_cb_ok = true;
4999 break;
5000 default:
5001 FAIL() << "Unexpected SSL_get_error result: " << ssl_err;
5002 }
5003 }
5004
5005 if (client_ret == 1 && server_ret == 1) {
5006 break;
5007 }
5008 }
5009
5010 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
5011 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
5012 EXPECT_TRUE(transport_.SecretsMatch(ssl_encryption_application));
5013 EXPECT_FALSE(transport_.client()->has_alert());
5014 EXPECT_FALSE(transport_.server()->has_alert());
5015}
5016
5017// Test buffering write data until explicit flushes.
5018TEST_F(QUICMethodTest, Buffered) {
5019 struct BufferedFlight {
5020 std::vector<uint8_t> data[kNumQUICLevels];
5021 };
5022 static UnownedSSLExData<BufferedFlight> buffered_flights;
5023
David Benjamincc9d9352018-10-30 19:45:22 -05005024 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
5025 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005026 BufferedFlight *flight = buffered_flights.Get(ssl);
5027 flight->data[level].insert(flight->data[level].end(), data, data + len);
5028 return 1;
5029 };
5030
5031 auto flush_flight = [](SSL *ssl) -> int {
5032 BufferedFlight *flight = buffered_flights.Get(ssl);
5033 for (size_t level = 0; level < kNumQUICLevels; level++) {
5034 if (!flight->data[level].empty()) {
5035 if (!TransportFromSSL(ssl)->WriteHandshakeData(
5036 static_cast<ssl_encryption_level_t>(level),
5037 flight->data[level])) {
5038 return 0;
5039 }
5040 flight->data[level].clear();
5041 }
5042 }
5043 return 1;
5044 };
5045
5046 const SSL_QUIC_METHOD quic_method = {
5047 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05005048 add_handshake_data,
Steven Valdezc8e0f902018-07-14 11:23:01 -04005049 flush_flight,
5050 SendAlertCallback,
5051 };
5052
5053 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5054 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5055 ASSERT_TRUE(CreateClientAndServer());
5056
5057 BufferedFlight client_flight, server_flight;
5058 buffered_flights.Set(client_.get(), &client_flight);
5059 buffered_flights.Set(server_.get(), &server_flight);
5060
5061 for (;;) {
5062 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5063 int client_ret = SSL_do_handshake(client_.get());
5064 if (client_ret != 1) {
5065 ASSERT_EQ(client_ret, -1);
5066 ASSERT_EQ(SSL_get_error(client_.get(), client_ret), SSL_ERROR_WANT_READ);
5067 }
5068
5069 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5070 int server_ret = SSL_do_handshake(server_.get());
5071 if (server_ret != 1) {
5072 ASSERT_EQ(server_ret, -1);
5073 ASSERT_EQ(SSL_get_error(server_.get(), server_ret), SSL_ERROR_WANT_READ);
5074 }
5075
5076 if (client_ret == 1 && server_ret == 1) {
5077 break;
5078 }
5079 }
5080
5081 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
5082 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
5083 EXPECT_TRUE(transport_.SecretsMatch(ssl_encryption_application));
5084 EXPECT_FALSE(transport_.client()->has_alert());
5085 EXPECT_FALSE(transport_.server()->has_alert());
5086}
5087
5088// Test that excess data at one level is rejected. That is, if a single
5089// |SSL_provide_quic_data| call included both ServerHello and
5090// EncryptedExtensions in a single chunk, BoringSSL notices and rejects this on
5091// key change.
5092TEST_F(QUICMethodTest, ExcessProvidedData) {
David Benjamincc9d9352018-10-30 19:45:22 -05005093 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
5094 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005095 // Switch everything to the initial level.
5096 return TransportFromSSL(ssl)->WriteHandshakeData(ssl_encryption_initial,
5097 MakeConstSpan(data, len));
5098 };
5099
5100 const SSL_QUIC_METHOD quic_method = {
5101 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05005102 add_handshake_data,
Steven Valdezc8e0f902018-07-14 11:23:01 -04005103 FlushFlightCallback,
5104 SendAlertCallback,
5105 };
5106
5107 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5108 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5109 ASSERT_TRUE(CreateClientAndServer());
5110
5111 // Send the ClientHello and ServerHello through Finished.
5112 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5113 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
5114 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5115 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
5116 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
5117
5118 // The client is still waiting for the ServerHello at initial
5119 // encryption.
5120 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
5121
David Benjamincc9d9352018-10-30 19:45:22 -05005122 // |add_handshake_data| incorrectly wrote everything at the initial level, so
5123 // this queues up ServerHello through Finished in one chunk.
Steven Valdezc8e0f902018-07-14 11:23:01 -04005124 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5125
5126 // The client reads ServerHello successfully, but then rejects the buffered
5127 // EncryptedExtensions on key change.
5128 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5129 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_SSL);
5130 uint32_t err = ERR_get_error();
5131 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
5132 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_BUFFERED_MESSAGES_ON_CIPHER_CHANGE);
5133
5134 // The client sends an alert in response to this.
5135 ASSERT_TRUE(transport_.client()->has_alert());
5136 EXPECT_EQ(transport_.client()->alert_level(), ssl_encryption_initial);
5137 EXPECT_EQ(transport_.client()->alert(), SSL_AD_UNEXPECTED_MESSAGE);
5138
5139 // Sanity-check client did get far enough to process the ServerHello and
5140 // install keys.
5141 EXPECT_TRUE(transport_.client()->HasSecrets(ssl_encryption_handshake));
5142}
5143
5144// Test that |SSL_provide_quic_data| will reject data at the wrong level.
5145TEST_F(QUICMethodTest, ProvideWrongLevel) {
5146 const SSL_QUIC_METHOD quic_method = {
5147 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05005148 AddHandshakeDataCallback,
Steven Valdezc8e0f902018-07-14 11:23:01 -04005149 FlushFlightCallback,
5150 SendAlertCallback,
5151 };
5152
5153 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5154 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5155 ASSERT_TRUE(CreateClientAndServer());
5156
5157 // Send the ClientHello and ServerHello through Finished.
5158 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5159 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
5160 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5161 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
5162 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
5163
5164 // The client is still waiting for the ServerHello at initial
5165 // encryption.
5166 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
5167
5168 // Data cannot be provided at the next level.
5169 std::vector<uint8_t> data;
5170 ASSERT_TRUE(
5171 transport_.client()->ReadHandshakeData(&data, ssl_encryption_initial));
5172 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_handshake,
5173 data.data(), data.size()));
5174 ERR_clear_error();
5175
5176 // Progress to EncryptedExtensions.
5177 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
5178 data.data(), data.size()));
5179 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5180 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
5181 ASSERT_EQ(ssl_encryption_handshake, SSL_quic_read_level(client_.get()));
5182
5183 // Data cannot be provided at the previous level.
5184 ASSERT_TRUE(
5185 transport_.client()->ReadHandshakeData(&data, ssl_encryption_handshake));
5186 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
5187 data.data(), data.size()));
5188}
5189
5190TEST_F(QUICMethodTest, TooMuchData) {
5191 const SSL_QUIC_METHOD quic_method = {
5192 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05005193 AddHandshakeDataCallback,
Steven Valdezc8e0f902018-07-14 11:23:01 -04005194 FlushFlightCallback,
5195 SendAlertCallback,
5196 };
5197
5198 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5199 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5200 ASSERT_TRUE(CreateClientAndServer());
5201
5202 size_t limit =
5203 SSL_quic_max_handshake_flight_len(client_.get(), ssl_encryption_initial);
5204 uint8_t b = 0;
5205 for (size_t i = 0; i < limit; i++) {
5206 ASSERT_TRUE(
5207 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
5208 }
5209
5210 EXPECT_FALSE(
5211 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
5212}
5213
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005214// Provide invalid post-handshake data.
5215TEST_F(QUICMethodTest, BadPostHandshake) {
5216 const SSL_QUIC_METHOD quic_method = {
5217 SetEncryptionSecretsCallback,
5218 AddHandshakeDataCallback,
5219 FlushFlightCallback,
5220 SendAlertCallback,
5221 };
5222
5223 g_last_session = nullptr;
5224
5225 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5226 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
5227 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5228 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5229 ASSERT_TRUE(CreateClientAndServer());
5230
5231 for (;;) {
5232 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5233 int client_ret = SSL_do_handshake(client_.get());
5234 if (client_ret != 1) {
5235 ASSERT_EQ(client_ret, -1);
5236 ASSERT_EQ(SSL_get_error(client_.get(), client_ret), SSL_ERROR_WANT_READ);
5237 }
5238
5239 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5240 int server_ret = SSL_do_handshake(server_.get());
5241 if (server_ret != 1) {
5242 ASSERT_EQ(server_ret, -1);
5243 ASSERT_EQ(SSL_get_error(server_.get(), server_ret), SSL_ERROR_WANT_READ);
5244 }
5245
5246 if (client_ret == 1 && server_ret == 1) {
5247 break;
5248 }
5249 }
5250
5251 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
5252 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
5253 EXPECT_TRUE(transport_.SecretsMatch(ssl_encryption_application));
5254 EXPECT_FALSE(transport_.client()->has_alert());
5255 EXPECT_FALSE(transport_.server()->has_alert());
5256
5257 // Junk sent as part of post-handshake data should cause an error.
5258 uint8_t kJunk[] = {0x17, 0x0, 0x0, 0x4, 0xB, 0xE, 0xE, 0xF};
5259 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_application,
5260 kJunk, sizeof(kJunk)));
5261 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 0);
5262}
5263
David Benjamin96628432017-01-19 19:05:47 -05005264// TODO(davidben): Convert this file to GTest properly.
5265TEST(SSLTest, AllTests) {
David Benjamine11726a2017-04-23 12:14:28 -04005266 if (!TestSSL_SESSIONEncoding(kOpenSSLSession) ||
Adam Langley10f97f32016-07-12 08:09:33 -07005267 !TestSSL_SESSIONEncoding(kCustomSession) ||
5268 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
5269 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
5270 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
5271 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
Steven Valdeza833c352016-11-01 13:39:36 -04005272 // Test the padding extension at TLS 1.2.
5273 !TestPaddingExtension(TLS1_2_VERSION, TLS1_2_VERSION) ||
5274 // Test the padding extension at TLS 1.3 with a TLS 1.2 session, so there
5275 // will be no PSK binder after the padding extension.
5276 !TestPaddingExtension(TLS1_3_VERSION, TLS1_2_VERSION) ||
5277 // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
5278 // will be a PSK binder after the padding extension.
David Benjaminaaef8332018-06-29 16:45:49 -04005279 !TestPaddingExtension(TLS1_3_VERSION, TLS1_3_VERSION)) {
David Benjamin96628432017-01-19 19:05:47 -05005280 ADD_FAILURE() << "Tests failed";
David Benjaminbb0a17c2014-09-20 15:35:39 -04005281 }
David Benjamin2e521212014-07-16 14:37:51 -04005282}
Martin Kreichgauer72912d22017-08-04 12:06:43 -07005283
5284} // namespace
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -07005285BSSL_NAMESPACE_END