blob: 470379c0f4d6edf634d5bf8e75a8db9342843320 [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 {
398 "P-256:P-384:P-521:X25519",
399 {
400 SSL_CURVE_SECP256R1,
401 SSL_CURVE_SECP384R1,
402 SSL_CURVE_SECP521R1,
403 SSL_CURVE_X25519,
404 },
405 },
David Benjamin6dda1662017-11-02 20:44:26 -0400406 {
407 "prime256v1:secp384r1:secp521r1:x25519",
408 {
409 SSL_CURVE_SECP256R1,
410 SSL_CURVE_SECP384R1,
411 SSL_CURVE_SECP521R1,
412 SSL_CURVE_X25519,
413 },
414 },
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100415};
416
417static const char *kBadCurvesLists[] = {
418 "",
419 ":",
420 "::",
421 "P-256::X25519",
422 "RSA:P-256",
423 "P-256:RSA",
424 "X25519:P-256:",
425 ":X25519:P-256",
426};
427
David Benjamin70dbf042017-08-08 18:51:37 -0400428static std::string CipherListToString(SSL_CTX *ctx) {
David Benjamin1d77e562015-03-22 17:22:08 -0400429 bool in_group = false;
David Benjamine11726a2017-04-23 12:14:28 -0400430 std::string ret;
David Benjamin70dbf042017-08-08 18:51:37 -0400431 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
432 for (size_t i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
433 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
434 if (!in_group && SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400435 ret += "\t[\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400436 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400437 }
David Benjamine11726a2017-04-23 12:14:28 -0400438 ret += "\t";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400439 if (in_group) {
David Benjamine11726a2017-04-23 12:14:28 -0400440 ret += " ";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400441 }
David Benjamine11726a2017-04-23 12:14:28 -0400442 ret += SSL_CIPHER_get_name(cipher);
443 ret += "\n";
David Benjamin70dbf042017-08-08 18:51:37 -0400444 if (in_group && !SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400445 ret += "\t]\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400446 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400447 }
448 }
David Benjamine11726a2017-04-23 12:14:28 -0400449 return ret;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400450}
451
David Benjamin70dbf042017-08-08 18:51:37 -0400452static bool CipherListsEqual(SSL_CTX *ctx,
David Benjamine11726a2017-04-23 12:14:28 -0400453 const std::vector<ExpectedCipher> &expected) {
David Benjamin70dbf042017-08-08 18:51:37 -0400454 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
455 if (sk_SSL_CIPHER_num(ciphers) != expected.size()) {
David Benjamin1d77e562015-03-22 17:22:08 -0400456 return false;
David Benjamin65226252015-02-05 16:49:47 -0500457 }
458
David Benjamine11726a2017-04-23 12:14:28 -0400459 for (size_t i = 0; i < expected.size(); i++) {
David Benjamin70dbf042017-08-08 18:51:37 -0400460 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
David Benjamine11726a2017-04-23 12:14:28 -0400461 if (expected[i].id != SSL_CIPHER_get_id(cipher) ||
David Benjamin70dbf042017-08-08 18:51:37 -0400462 expected[i].in_group_flag != !!SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400463 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400464 }
465 }
466
David Benjamin1d77e562015-03-22 17:22:08 -0400467 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400468}
469
David Benjamine11726a2017-04-23 12:14:28 -0400470TEST(SSLTest, CipherRules) {
471 for (const CipherTest &t : kCipherTests) {
472 SCOPED_TRACE(t.rule);
473 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
474 ASSERT_TRUE(ctx);
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700475
David Benjamine11726a2017-04-23 12:14:28 -0400476 // Test lax mode.
477 ASSERT_TRUE(SSL_CTX_set_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400478 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400479 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400480 << CipherListToString(ctx.get());
David Benjamine11726a2017-04-23 12:14:28 -0400481
482 // Test strict mode.
483 if (t.strict_fail) {
484 EXPECT_FALSE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
485 } else {
486 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400487 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400488 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400489 << CipherListToString(ctx.get());
David Benjaminbb0a17c2014-09-20 15:35:39 -0400490 }
491 }
492
David Benjaminfb974e62015-12-16 19:34:22 -0500493 for (const char *rule : kBadRules) {
David Benjamine11726a2017-04-23 12:14:28 -0400494 SCOPED_TRACE(rule);
495 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
496 ASSERT_TRUE(ctx);
497
498 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), rule));
David Benjaminbb0a17c2014-09-20 15:35:39 -0400499 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400500 }
501
David Benjaminfb974e62015-12-16 19:34:22 -0500502 for (const char *rule : kMustNotIncludeNull) {
David Benjamine11726a2017-04-23 12:14:28 -0400503 SCOPED_TRACE(rule);
504 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
505 ASSERT_TRUE(ctx);
506
507 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400508 for (const SSL_CIPHER *cipher : SSL_CTX_get_ciphers(ctx.get())) {
David Benjamine3bb51c2017-08-22 23:16:02 -0700509 EXPECT_NE(NID_undef, SSL_CIPHER_get_cipher_nid(cipher));
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700510 }
511 }
David Benjaminbb0a17c2014-09-20 15:35:39 -0400512}
David Benjamin2e521212014-07-16 14:37:51 -0400513
David Benjamine11726a2017-04-23 12:14:28 -0400514TEST(SSLTest, CurveRules) {
515 for (const CurveTest &t : kCurveTests) {
516 SCOPED_TRACE(t.rule);
517 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
518 ASSERT_TRUE(ctx);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100519
David Benjamine11726a2017-04-23 12:14:28 -0400520 ASSERT_TRUE(SSL_CTX_set1_curves_list(ctx.get(), t.rule));
David Benjamin0ce090a2018-07-02 20:24:40 -0400521 ASSERT_EQ(t.expected.size(), ctx->supported_group_list.size());
David Benjamine11726a2017-04-23 12:14:28 -0400522 for (size_t i = 0; i < t.expected.size(); i++) {
523 EXPECT_EQ(t.expected[i], ctx->supported_group_list[i]);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100524 }
525 }
526
527 for (const char *rule : kBadCurvesLists) {
David Benjamine11726a2017-04-23 12:14:28 -0400528 SCOPED_TRACE(rule);
529 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
530 ASSERT_TRUE(ctx);
531
532 EXPECT_FALSE(SSL_CTX_set1_curves_list(ctx.get(), rule));
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100533 ERR_clear_error();
534 }
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100535}
536
Adam Langley364f7a62016-12-12 10:51:00 -0800537// kOpenSSLSession is a serialized SSL_SESSION.
Adam Langley10f97f32016-07-12 08:09:33 -0700538static const char kOpenSSLSession[] =
Adam Langley364f7a62016-12-12 10:51:00 -0800539 "MIIFqgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700540 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
541 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
542 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
543 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
544 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
545 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
546 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
547 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
548 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
549 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
550 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
551 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
552 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
553 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
554 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
555 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
556 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
557 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
558 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
559 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
560 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
561 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
562 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
563 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
564 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
565 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
566 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
567 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
568 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
Adam Langley364f7a62016-12-12 10:51:00 -0800569 "i4gv7Y5oliyntgMBAQA=";
Adam Langley10f97f32016-07-12 08:09:33 -0700570
571// kCustomSession is a custom serialized SSL_SESSION generated by
572// filling in missing fields from |kOpenSSLSession|. This includes
573// providing |peer_sha256|, so |peer| is not serialized.
574static const char kCustomSession[] =
David Benjamina8614602017-09-06 15:40:19 -0400575 "MIIBZAIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700576 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
David Benjamina8614602017-09-06 15:40:19 -0400577 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUqAcEBXdvcmxkqQUCAwGJwKqBpwSB"
578 "pBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38"
579 "VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd"
580 "3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hg"
581 "b+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYGBgYGBgYGBgYGBgYGBgYGBgYG"
582 "BgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
Adam Langley10f97f32016-07-12 08:09:33 -0700583
584// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
585static const char kBoringSSLSession[] =
586 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
587 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
588 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
589 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
590 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
591 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
592 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
593 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
594 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
595 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
596 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
597 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
598 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
599 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
600 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
601 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
602 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
603 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
604 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
605 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
606 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
607 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
608 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
609 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
610 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
611 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
612 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
613 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
614 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
615 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
616 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
617 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
618 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
619 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
620 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
621 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
622 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
623 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
624 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
625 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
626 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
627 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
628 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
629 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
630 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
631 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
632 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
633 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
634 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
635 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
636 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
637 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
638 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
639 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
640 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
641 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
642 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
643 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
644 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
645 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
646 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
647 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
648 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
649 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
650 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
651 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
652 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
653 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
654 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
655 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
656 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
657 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
658 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
659 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
660 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
661 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
662 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
663 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
664 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
665 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
666 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
667 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
668 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
669 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
670 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
671 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
672 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
673 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
674 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
675 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
676 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
677 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
678 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
679 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
680 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
681
682// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
683// the final (optional) element of |kCustomSession| with tag number 30.
684static const char kBadSessionExtraField[] =
685 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
686 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
687 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
688 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
689 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
690 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
691 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
692 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
693
694// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
695// the version of |kCustomSession| with 2.
696static const char kBadSessionVersion[] =
697 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
698 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
699 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
700 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
701 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
702 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
703 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
704 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
705
706// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
707// appended.
708static const char kBadSessionTrailingData[] =
709 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
710 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
711 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
712 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
713 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
714 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
715 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
716 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
717
David Benjamin1d77e562015-03-22 17:22:08 -0400718static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400719 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400720 if (!EVP_DecodedLength(&len, strlen(in))) {
721 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400722 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400723 }
724
David Benjamin1d77e562015-03-22 17:22:08 -0400725 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800726 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400727 strlen(in))) {
728 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400729 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400730 }
David Benjamin1d77e562015-03-22 17:22:08 -0400731 out->resize(len);
732 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400733}
734
David Benjamin1d77e562015-03-22 17:22:08 -0400735static bool TestSSL_SESSIONEncoding(const char *input_b64) {
David Benjamin751e8892014-10-19 00:59:36 -0400736 const uint8_t *cptr;
737 uint8_t *ptr;
David Benjamin751e8892014-10-19 00:59:36 -0400738
David Benjamin1d77e562015-03-22 17:22:08 -0400739 // Decode the input.
740 std::vector<uint8_t> input;
741 if (!DecodeBase64(&input, input_b64)) {
742 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400743 }
744
David Benjamin1d77e562015-03-22 17:22:08 -0400745 // Verify the SSL_SESSION decodes.
Adam Langley46db7af2017-02-01 15:49:37 -0800746 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
747 if (!ssl_ctx) {
748 return false;
749 }
750 bssl::UniquePtr<SSL_SESSION> session(
751 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
David Benjaminfd67aa82015-06-15 19:41:48 -0400752 if (!session) {
753 fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400754 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400755 }
756
David Benjamin1d77e562015-03-22 17:22:08 -0400757 // Verify the SSL_SESSION encoding round-trips.
758 size_t encoded_len;
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700759 bssl::UniquePtr<uint8_t> encoded;
David Benjamin1d77e562015-03-22 17:22:08 -0400760 uint8_t *encoded_raw;
761 if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
David Benjamin3cac4502014-10-21 01:46:30 -0400762 fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400763 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400764 }
David Benjamin1d77e562015-03-22 17:22:08 -0400765 encoded.reset(encoded_raw);
766 if (encoded_len != input.size() ||
David Benjamin17cf2cb2016-12-13 01:07:13 -0500767 OPENSSL_memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin3cac4502014-10-21 01:46:30 -0400768 fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
Sigbjorn Vik2b23d242015-06-29 15:07:26 +0200769 hexdump(stderr, "Before: ", input.data(), input.size());
770 hexdump(stderr, "After: ", encoded_raw, encoded_len);
David Benjamin1d77e562015-03-22 17:22:08 -0400771 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400772 }
David Benjamin3cac4502014-10-21 01:46:30 -0400773
David Benjaminfd67aa82015-06-15 19:41:48 -0400774 // Verify the SSL_SESSION also decodes with the legacy API.
David Benjaminef14b2d2015-11-11 14:01:27 -0800775 cptr = input.data();
David Benjaminfd67aa82015-06-15 19:41:48 -0400776 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
David Benjaminef14b2d2015-11-11 14:01:27 -0800777 if (!session || cptr != input.data() + input.size()) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400778 fprintf(stderr, "d2i_SSL_SESSION failed\n");
779 return false;
780 }
781
David Benjamin1d77e562015-03-22 17:22:08 -0400782 // Verify the SSL_SESSION encoding round-trips via the legacy API.
783 int len = i2d_SSL_SESSION(session.get(), NULL);
784 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400785 fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400786 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400787 }
788
David Benjamin1d77e562015-03-22 17:22:08 -0400789 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
790 if (!encoded) {
David Benjamin751e8892014-10-19 00:59:36 -0400791 fprintf(stderr, "malloc failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400792 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400793 }
David Benjamin1d77e562015-03-22 17:22:08 -0400794
795 ptr = encoded.get();
796 len = i2d_SSL_SESSION(session.get(), &ptr);
797 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400798 fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400799 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400800 }
David Benjamin1d77e562015-03-22 17:22:08 -0400801 if (ptr != encoded.get() + input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400802 fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400803 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400804 }
David Benjamin17cf2cb2016-12-13 01:07:13 -0500805 if (OPENSSL_memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin751e8892014-10-19 00:59:36 -0400806 fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400807 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400808 }
809
David Benjamin1d77e562015-03-22 17:22:08 -0400810 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400811}
812
David Benjaminf297e022015-05-28 19:55:29 -0400813static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
814 std::vector<uint8_t> input;
815 if (!DecodeBase64(&input, input_b64)) {
816 return false;
817 }
818
819 // Verify that the SSL_SESSION fails to decode.
Adam Langley46db7af2017-02-01 15:49:37 -0800820 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
821 if (!ssl_ctx) {
822 return false;
823 }
824 bssl::UniquePtr<SSL_SESSION> session(
825 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
David Benjaminf297e022015-05-28 19:55:29 -0400826 if (session) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400827 fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
David Benjaminf297e022015-05-28 19:55:29 -0400828 return false;
829 }
830 ERR_clear_error();
831 return true;
832}
833
David Benjamin321fcdc2017-04-24 11:42:42 -0400834static void ExpectDefaultVersion(uint16_t min_version, uint16_t max_version,
835 const SSL_METHOD *(*method)(void)) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700836 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
David Benjamin321fcdc2017-04-24 11:42:42 -0400837 ASSERT_TRUE(ctx);
David Benjaminfc08dfc2017-06-20 14:39:32 -0400838 EXPECT_EQ(min_version, ctx->conf_min_version);
839 EXPECT_EQ(max_version, ctx->conf_max_version);
David Benjamin321fcdc2017-04-24 11:42:42 -0400840}
841
842TEST(SSLTest, DefaultVersion) {
843 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
844 ExpectDefaultVersion(TLS1_VERSION, TLS1_2_VERSION, &TLS_method);
845 ExpectDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method);
846 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method);
847 ExpectDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method);
848 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method);
849 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method);
850 ExpectDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method);
David Benjamin82c9e902014-12-12 15:55:27 -0500851}
852
David Benjamin348f0d82017-08-10 16:06:27 -0400853TEST(SSLTest, CipherProperties) {
David Benjamin6fff3862017-06-21 21:07:04 -0400854 static const struct {
855 int id;
856 const char *standard_name;
David Benjamin348f0d82017-08-10 16:06:27 -0400857 int cipher_nid;
858 int digest_nid;
859 int kx_nid;
860 int auth_nid;
David Benjaminb1b76ae2017-09-21 17:03:34 -0400861 int prf_nid;
David Benjamin6fff3862017-06-21 21:07:04 -0400862 } kTests[] = {
David Benjamin348f0d82017-08-10 16:06:27 -0400863 {
864 SSL3_CK_RSA_DES_192_CBC3_SHA,
865 "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
866 NID_des_ede3_cbc,
867 NID_sha1,
868 NID_kx_rsa,
869 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400870 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400871 },
872 {
873 TLS1_CK_RSA_WITH_AES_128_SHA,
874 "TLS_RSA_WITH_AES_128_CBC_SHA",
875 NID_aes_128_cbc,
876 NID_sha1,
877 NID_kx_rsa,
878 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400879 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400880 },
881 {
882 TLS1_CK_PSK_WITH_AES_256_CBC_SHA,
883 "TLS_PSK_WITH_AES_256_CBC_SHA",
884 NID_aes_256_cbc,
885 NID_sha1,
886 NID_kx_psk,
887 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400888 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400889 },
890 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400891 TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA,
892 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
David Benjamin348f0d82017-08-10 16:06:27 -0400893 NID_aes_128_cbc,
David Benjamin6e678ee2018-04-16 19:54:42 -0400894 NID_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400895 NID_kx_ecdhe,
896 NID_auth_rsa,
David Benjamin6e678ee2018-04-16 19:54:42 -0400897 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400898 },
899 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400900 TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA,
901 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
David Benjamin348f0d82017-08-10 16:06:27 -0400902 NID_aes_256_cbc,
David Benjamin6e678ee2018-04-16 19:54:42 -0400903 NID_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400904 NID_kx_ecdhe,
905 NID_auth_rsa,
David Benjamin6e678ee2018-04-16 19:54:42 -0400906 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400907 },
908 {
909 TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
910 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
911 NID_aes_128_gcm,
912 NID_undef,
913 NID_kx_ecdhe,
914 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400915 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400916 },
917 {
918 TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
919 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
920 NID_aes_128_gcm,
921 NID_undef,
922 NID_kx_ecdhe,
923 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400924 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400925 },
926 {
927 TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
928 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
929 NID_aes_256_gcm,
930 NID_undef,
931 NID_kx_ecdhe,
932 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400933 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -0400934 },
935 {
936 TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
937 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
938 NID_aes_128_cbc,
939 NID_sha1,
940 NID_kx_ecdhe,
941 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400942 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400943 },
944 {
945 TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
946 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
947 NID_chacha20_poly1305,
948 NID_undef,
949 NID_kx_ecdhe,
950 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400951 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400952 },
953 {
954 TLS1_CK_AES_256_GCM_SHA384,
955 "TLS_AES_256_GCM_SHA384",
956 NID_aes_256_gcm,
957 NID_undef,
958 NID_kx_any,
959 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400960 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -0400961 },
962 {
963 TLS1_CK_AES_128_GCM_SHA256,
964 "TLS_AES_128_GCM_SHA256",
965 NID_aes_128_gcm,
966 NID_undef,
967 NID_kx_any,
968 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400969 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400970 },
971 {
972 TLS1_CK_CHACHA20_POLY1305_SHA256,
973 "TLS_CHACHA20_POLY1305_SHA256",
974 NID_chacha20_poly1305,
975 NID_undef,
976 NID_kx_any,
977 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400978 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400979 },
David Benjamin6fff3862017-06-21 21:07:04 -0400980 };
David Benjamin65226252015-02-05 16:49:47 -0500981
David Benjamin6fff3862017-06-21 21:07:04 -0400982 for (const auto &t : kTests) {
983 SCOPED_TRACE(t.standard_name);
David Benjamine11726a2017-04-23 12:14:28 -0400984
985 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(t.id & 0xffff);
986 ASSERT_TRUE(cipher);
David Benjamin6fff3862017-06-21 21:07:04 -0400987 EXPECT_STREQ(t.standard_name, SSL_CIPHER_standard_name(cipher));
988
David Benjamine11726a2017-04-23 12:14:28 -0400989 bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
990 ASSERT_TRUE(rfc_name);
David Benjamin6fff3862017-06-21 21:07:04 -0400991 EXPECT_STREQ(t.standard_name, rfc_name.get());
David Benjamin348f0d82017-08-10 16:06:27 -0400992
993 EXPECT_EQ(t.cipher_nid, SSL_CIPHER_get_cipher_nid(cipher));
994 EXPECT_EQ(t.digest_nid, SSL_CIPHER_get_digest_nid(cipher));
995 EXPECT_EQ(t.kx_nid, SSL_CIPHER_get_kx_nid(cipher));
996 EXPECT_EQ(t.auth_nid, SSL_CIPHER_get_auth_nid(cipher));
David Benjaminb1b76ae2017-09-21 17:03:34 -0400997 EXPECT_EQ(t.prf_nid, SSL_CIPHER_get_prf_nid(cipher));
David Benjamin65226252015-02-05 16:49:47 -0500998 }
David Benjamin65226252015-02-05 16:49:47 -0500999}
1000
Steven Valdeza833c352016-11-01 13:39:36 -04001001// CreateSessionWithTicket returns a sample |SSL_SESSION| with the specified
1002// version and ticket length or nullptr on failure.
1003static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(uint16_t version,
1004 size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -04001005 std::vector<uint8_t> der;
1006 if (!DecodeBase64(&der, kOpenSSLSession)) {
1007 return nullptr;
1008 }
Adam Langley46db7af2017-02-01 15:49:37 -08001009
1010 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
1011 if (!ssl_ctx) {
1012 return nullptr;
1013 }
David Benjaminaaef8332018-06-29 16:45:49 -04001014 // Use a garbage ticket.
1015 std::vector<uint8_t> ticket(ticket_len, 'a');
Steven Valdeza833c352016-11-01 13:39:36 -04001016 bssl::UniquePtr<SSL_SESSION> session(
Adam Langley46db7af2017-02-01 15:49:37 -08001017 SSL_SESSION_from_bytes(der.data(), der.size(), ssl_ctx.get()));
David Benjaminaaef8332018-06-29 16:45:49 -04001018 if (!session ||
1019 !SSL_SESSION_set_protocol_version(session.get(), version) ||
1020 !SSL_SESSION_set_ticket(session.get(), ticket.data(), ticket.size())) {
David Benjamin422fe082015-07-21 22:03:43 -04001021 return nullptr;
1022 }
David Benjamin1269ddd2015-10-18 15:18:55 -04001023 // Fix up the timeout.
David Benjamin9b63f292016-11-15 00:44:05 -05001024#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
David Benjaminaaef8332018-06-29 16:45:49 -04001025 SSL_SESSION_set_time(session.get(), 1234);
David Benjamin9b63f292016-11-15 00:44:05 -05001026#else
David Benjaminaaef8332018-06-29 16:45:49 -04001027 SSL_SESSION_set_time(session.get(), time(nullptr));
David Benjamin9b63f292016-11-15 00:44:05 -05001028#endif
David Benjamin422fe082015-07-21 22:03:43 -04001029 return session;
1030}
1031
David Benjaminafc64de2016-07-19 17:12:41 +02001032static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001033 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +02001034 if (!bio) {
1035 return false;
1036 }
1037 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -04001038 BIO_up_ref(bio.get());
1039 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +02001040 int ret = SSL_connect(ssl);
1041 if (ret > 0) {
1042 // SSL_connect should fail without a BIO to write to.
1043 return false;
1044 }
1045 ERR_clear_error();
1046
1047 const uint8_t *client_hello;
1048 size_t client_hello_len;
1049 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
1050 return false;
1051 }
1052 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
1053 return true;
1054}
1055
Steven Valdeza833c352016-11-01 13:39:36 -04001056// GetClientHelloLen creates a client SSL connection with the specified version
1057// and ticket length. It returns the length of the ClientHello, not including
1058// the record header, on success and zero on error.
1059static size_t GetClientHelloLen(uint16_t max_version, uint16_t session_version,
1060 size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001061 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Steven Valdeza833c352016-11-01 13:39:36 -04001062 bssl::UniquePtr<SSL_SESSION> session =
1063 CreateSessionWithTicket(session_version, ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -04001064 if (!ctx || !session) {
1065 return 0;
1066 }
Steven Valdeza833c352016-11-01 13:39:36 -04001067
1068 // Set a one-element cipher list so the baseline ClientHello is unpadded.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001069 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
Steven Valdez2c62fe92016-10-14 12:08:12 -04001070 if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -08001071 !SSL_set_strict_cipher_list(ssl.get(), "ECDHE-RSA-AES128-GCM-SHA256") ||
Steven Valdeza833c352016-11-01 13:39:36 -04001072 !SSL_set_max_proto_version(ssl.get(), max_version)) {
David Benjamin422fe082015-07-21 22:03:43 -04001073 return 0;
1074 }
Steven Valdeza833c352016-11-01 13:39:36 -04001075
David Benjaminafc64de2016-07-19 17:12:41 +02001076 std::vector<uint8_t> client_hello;
1077 if (!GetClientHello(ssl.get(), &client_hello) ||
1078 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -04001079 return 0;
1080 }
Steven Valdeza833c352016-11-01 13:39:36 -04001081
David Benjaminafc64de2016-07-19 17:12:41 +02001082 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -04001083}
1084
1085struct PaddingTest {
1086 size_t input_len, padded_len;
1087};
1088
1089static const PaddingTest kPaddingTests[] = {
1090 // ClientHellos of length below 0x100 do not require padding.
1091 {0xfe, 0xfe},
1092 {0xff, 0xff},
1093 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
1094 {0x100, 0x200},
1095 {0x123, 0x200},
1096 {0x1fb, 0x200},
1097 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
1098 // padding extension takes a minimum of four bytes plus one required content
1099 // byte. (To work around yet more server bugs, we avoid empty final
1100 // extensions.)
1101 {0x1fc, 0x201},
1102 {0x1fd, 0x202},
1103 {0x1fe, 0x203},
1104 {0x1ff, 0x204},
1105 // Finally, larger ClientHellos need no padding.
1106 {0x200, 0x200},
1107 {0x201, 0x201},
1108};
1109
Steven Valdeza833c352016-11-01 13:39:36 -04001110static bool TestPaddingExtension(uint16_t max_version,
1111 uint16_t session_version) {
David Benjamin422fe082015-07-21 22:03:43 -04001112 // Sample a baseline length.
Steven Valdeza833c352016-11-01 13:39:36 -04001113 size_t base_len = GetClientHelloLen(max_version, session_version, 1);
David Benjamin422fe082015-07-21 22:03:43 -04001114 if (base_len == 0) {
1115 return false;
1116 }
1117
1118 for (const PaddingTest &test : kPaddingTests) {
1119 if (base_len > test.input_len) {
Steven Valdeza833c352016-11-01 13:39:36 -04001120 fprintf(stderr,
1121 "Baseline ClientHello too long (max_version = %04x, "
1122 "session_version = %04x).\n",
1123 max_version, session_version);
David Benjamin422fe082015-07-21 22:03:43 -04001124 return false;
1125 }
1126
Steven Valdeza833c352016-11-01 13:39:36 -04001127 size_t padded_len = GetClientHelloLen(max_version, session_version,
1128 1 + test.input_len - base_len);
David Benjamin422fe082015-07-21 22:03:43 -04001129 if (padded_len != test.padded_len) {
Steven Valdeza833c352016-11-01 13:39:36 -04001130 fprintf(stderr,
1131 "%u-byte ClientHello padded to %u bytes, not %u (max_version = "
1132 "%04x, session_version = %04x).\n",
David Benjamin422fe082015-07-21 22:03:43 -04001133 static_cast<unsigned>(test.input_len),
1134 static_cast<unsigned>(padded_len),
Steven Valdeza833c352016-11-01 13:39:36 -04001135 static_cast<unsigned>(test.padded_len), max_version,
1136 session_version);
David Benjamin422fe082015-07-21 22:03:43 -04001137 return false;
1138 }
1139 }
Steven Valdeza833c352016-11-01 13:39:36 -04001140
David Benjamin422fe082015-07-21 22:03:43 -04001141 return true;
1142}
1143
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001144static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001145 static const char kCertPEM[] =
1146 "-----BEGIN CERTIFICATE-----\n"
1147 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1148 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1149 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1150 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1151 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1152 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1153 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1154 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1155 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1156 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1157 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1158 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1159 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1160 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001161 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
David Benjamin1444c3a2016-12-20 17:23:11 -05001162 return bssl::UniquePtr<X509>(
1163 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjaminde942382016-02-11 12:02:01 -05001164}
1165
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001166static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001167 static const char kKeyPEM[] =
1168 "-----BEGIN RSA PRIVATE KEY-----\n"
1169 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1170 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1171 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1172 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1173 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1174 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1175 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1176 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1177 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1178 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1179 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1180 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1181 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1182 "-----END RSA PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001183 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1184 return bssl::UniquePtr<EVP_PKEY>(
David Benjaminde942382016-02-11 12:02:01 -05001185 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1186}
1187
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001188static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001189 static const char kCertPEM[] =
1190 "-----BEGIN CERTIFICATE-----\n"
1191 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1192 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1193 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1194 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1195 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1196 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1197 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1198 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1199 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1200 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1201 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001202 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1203 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjamin0fc37ef2016-08-17 15:29:46 -04001204}
1205
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001206static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001207 static const char kKeyPEM[] =
1208 "-----BEGIN PRIVATE KEY-----\n"
1209 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1210 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1211 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1212 "-----END PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001213 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1214 return bssl::UniquePtr<EVP_PKEY>(
David Benjamin0fc37ef2016-08-17 15:29:46 -04001215 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1216}
1217
Adam Langleyd04ca952017-02-28 11:26:51 -08001218static bssl::UniquePtr<CRYPTO_BUFFER> BufferFromPEM(const char *pem) {
1219 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1220 char *name, *header;
1221 uint8_t *data;
1222 long data_len;
1223 if (!PEM_read_bio(bio.get(), &name, &header, &data,
1224 &data_len)) {
1225 return nullptr;
1226 }
1227 OPENSSL_free(name);
1228 OPENSSL_free(header);
1229
1230 auto ret = bssl::UniquePtr<CRYPTO_BUFFER>(
1231 CRYPTO_BUFFER_new(data, data_len, nullptr));
1232 OPENSSL_free(data);
1233 return ret;
1234}
1235
1236static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestCertificateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001237 static const char kCertPEM[] =
1238 "-----BEGIN CERTIFICATE-----\n"
1239 "MIIC0jCCAbqgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQiBD\n"
1240 "QTAeFw0xNjAyMjgyMDI3MDNaFw0yNjAyMjUyMDI3MDNaMBgxFjAUBgNVBAMMDUNs\n"
1241 "aWVudCBDZXJ0IEEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRvaz8\n"
1242 "CC/cshpCafJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/\n"
1243 "kLRcH89M/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3\n"
1244 "tHb+xs2PSs8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+c\n"
1245 "IDs2rQ+lP7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1\n"
1246 "z7C8jU50Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9V\n"
1247 "iLeXANgZi+Xx9KgfAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI\n"
1248 "KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBFEVbmYl+2RtNw\n"
1249 "rDftRDF1v2QUbcN2ouSnQDHxeDQdSgasLzT3ui8iYu0Rw2WWcZ0DV5e0ztGPhWq7\n"
1250 "AO0B120aFRMOY+4+bzu9Q2FFkQqc7/fKTvTDzIJI5wrMnFvUfzzvxh3OHWMYSs/w\n"
1251 "giq33hTKeHEq6Jyk3btCny0Ycecyc3yGXH10sizUfiHlhviCkDuESk8mFDwDDzqW\n"
1252 "ZF0IipzFbEDHoIxLlm3GQxpiLoEV4k8KYJp3R5KBLFyxM6UGPz8h72mIPCJp2RuK\n"
1253 "MYgF91UDvVzvnYm6TfseM2+ewKirC00GOrZ7rEcFvtxnKSqYf4ckqfNdSU1Y+RRC\n"
1254 "1ngWZ7Ih\n"
1255 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001256 return BufferFromPEM(kCertPEM);
David Benjamin1444c3a2016-12-20 17:23:11 -05001257}
1258
Adam Langleyd04ca952017-02-28 11:26:51 -08001259static bssl::UniquePtr<X509> X509FromBuffer(
1260 bssl::UniquePtr<CRYPTO_BUFFER> buffer) {
1261 if (!buffer) {
1262 return nullptr;
1263 }
1264 const uint8_t *derp = CRYPTO_BUFFER_data(buffer.get());
1265 return bssl::UniquePtr<X509>(
1266 d2i_X509(NULL, &derp, CRYPTO_BUFFER_len(buffer.get())));
1267}
1268
1269static bssl::UniquePtr<X509> GetChainTestCertificate() {
1270 return X509FromBuffer(GetChainTestCertificateBuffer());
1271}
1272
1273static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestIntermediateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001274 static const char kCertPEM[] =
1275 "-----BEGIN CERTIFICATE-----\n"
1276 "MIICwjCCAaqgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS\n"
1277 "b290IENBMB4XDTE2MDIyODIwMjcwM1oXDTI2MDIyNTIwMjcwM1owDzENMAsGA1UE\n"
1278 "AwwEQiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALsSCYmDip2D\n"
1279 "GkjFxw7ykz26JSjELkl6ArlYjFJ3aT/SCh8qbS4gln7RH8CPBd78oFdfhIKQrwtZ\n"
1280 "3/q21ykD9BAS3qHe2YdcJfm8/kWAy5DvXk6NXU4qX334KofBAEpgdA/igEFq1P1l\n"
1281 "HAuIfZCpMRfT+i5WohVsGi8f/NgpRvVaMONLNfgw57mz1lbtFeBEISmX0kbsuJxF\n"
1282 "Qj/Bwhi5/0HAEXG8e7zN4cEx0yPRvmOATRdVb/8dW2pwOHRJq9R5M0NUkIsTSnL7\n"
1283 "6N/z8hRAHMsV3IudC5Yd7GXW1AGu9a+iKU+Q4xcZCoj0DC99tL4VKujrV1kAeqsM\n"
1284 "cz5/dKzi6+cCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
1285 "AQYwDQYJKoZIhvcNAQELBQADggEBAIIeZiEeNhWWQ8Y4D+AGDwqUUeG8NjCbKrXQ\n"
1286 "BlHg5wZ8xftFaiP1Dp/UAezmx2LNazdmuwrYB8lm3FVTyaPDTKEGIPS4wJKHgqH1\n"
1287 "QPDhqNm85ey7TEtI9oYjsNim/Rb+iGkIAMXaxt58SzxbjvP0kMr1JfJIZbic9vye\n"
1288 "NwIspMFIpP3FB8ywyu0T0hWtCQgL4J47nigCHpOu58deP88fS/Nyz/fyGVWOZ76b\n"
1289 "WhWwgM3P3X95fQ3d7oFPR/bVh0YV+Cf861INwplokXgXQ3/TCQ+HNXeAMWn3JLWv\n"
1290 "XFwk8owk9dq/kQGdndGgy3KTEW4ctPX5GNhf3LJ9Q7dLji4ReQ4=\n"
1291 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001292 return BufferFromPEM(kCertPEM);
1293}
1294
1295static bssl::UniquePtr<X509> GetChainTestIntermediate() {
1296 return X509FromBuffer(GetChainTestIntermediateBuffer());
David Benjamin1444c3a2016-12-20 17:23:11 -05001297}
1298
1299static bssl::UniquePtr<EVP_PKEY> GetChainTestKey() {
1300 static const char kKeyPEM[] =
1301 "-----BEGIN PRIVATE KEY-----\n"
1302 "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRvaz8CC/cshpC\n"
1303 "afJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/kLRcH89M\n"
1304 "/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3tHb+xs2P\n"
1305 "Ss8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+cIDs2rQ+l\n"
1306 "P7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1z7C8jU50\n"
1307 "Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9ViLeXANgZ\n"
1308 "i+Xx9KgfAgMBAAECggEBAK0VjSJzkyPaamcyTVSWjo7GdaBGcK60lk657RjR+lK0\n"
1309 "YJ7pkej4oM2hdsVZFsP8Cs4E33nXLa/0pDsRov/qrp0WQm2skwqGMC1I/bZ0WRPk\n"
1310 "wHaDrBBfESWnJDX/AGpVtlyOjPmgmK6J2usMPihQUDkKdAYrVWJePrMIxt1q6BMe\n"
1311 "iczs3qriMmtY3bUc4UyUwJ5fhDLjshHvfuIpYQyI6EXZM6dZksn9LylXJnigY6QJ\n"
1312 "HxOYO0BDwOsZ8yQ8J8afLk88i0GizEkgE1z3REtQUwgWfxr1WV/ud+T6/ZhSAgH9\n"
1313 "042mQvSFZnIUSEsmCvjhWuAunfxHKCTcAoYISWfzWpkCgYEA7gpf3HHU5Tn+CgUn\n"
1314 "1X5uGpG3DmcMgfeGgs2r2f/IIg/5Ac1dfYILiybL1tN9zbyLCJfcbFpWBc9hJL6f\n"
1315 "CPc5hUiwWFJqBJewxQkC1Ae/HakHbip+IZ+Jr0842O4BAArvixk4Lb7/N2Ct9sTE\n"
1316 "NJO6RtK9lbEZ5uK61DglHy8CS2UCgYEA4ZC1o36kPAMQBggajgnucb2yuUEelk0f\n"
1317 "AEr+GI32MGE+93xMr7rAhBoqLg4AITyIfEnOSQ5HwagnIHonBbv1LV/Gf9ursx8Z\n"
1318 "YOGbvT8zzzC+SU1bkDzdjAYnFQVGIjMtKOBJ3K07++ypwX1fr4QsQ8uKL8WSOWwt\n"
1319 "Z3Bym6XiZzMCgYADnhy+2OwHX85AkLt+PyGlPbmuelpyTzS4IDAQbBa6jcuW/2wA\n"
1320 "UE2km75VUXmD+u2R/9zVuLm99NzhFhSMqlUxdV1YukfqMfP5yp1EY6m/5aW7QuIP\n"
1321 "2MDa7TVL9rIFMiVZ09RKvbBbQxjhuzPQKL6X/PPspnhiTefQ+dl2k9xREQKBgHDS\n"
1322 "fMfGNEeAEKezrfSVqxphE9/tXms3L+ZpnCaT+yu/uEr5dTIAawKoQ6i9f/sf1/Sy\n"
1323 "xedsqR+IB+oKrzIDDWMgoJybN4pkZ8E5lzhVQIjFjKgFdWLzzqyW9z1gYfABQPlN\n"
1324 "FiS20WX0vgP1vcKAjdNrHzc9zyHBpgQzDmAj3NZZAoGBAI8vKCKdH7w3aL5CNkZQ\n"
1325 "2buIeWNA2HZazVwAGG5F2TU/LmXfRKnG6dX5bkU+AkBZh56jNZy//hfFSewJB4Kk\n"
1326 "buB7ERSdaNbO21zXt9FEA3+z0RfMd/Zv2vlIWOSB5nzl/7UKti3sribK6s9ZVLfi\n"
1327 "SxpiPQ8d/hmSGwn4ksrWUsJD\n"
1328 "-----END PRIVATE KEY-----\n";
1329 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1330 return bssl::UniquePtr<EVP_PKEY>(
1331 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1332}
1333
David Benjaminc79ae7a2017-08-29 16:09:44 -04001334// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
1335// before configuring as a server.
1336TEST(SSLTest, ClientCAList) {
1337 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1338 ASSERT_TRUE(ctx);
1339 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1340 ASSERT_TRUE(ssl);
1341
1342 bssl::UniquePtr<X509_NAME> name(X509_NAME_new());
1343 ASSERT_TRUE(name);
1344
1345 bssl::UniquePtr<X509_NAME> name_dup(X509_NAME_dup(name.get()));
1346 ASSERT_TRUE(name_dup);
1347
1348 bssl::UniquePtr<STACK_OF(X509_NAME)> stack(sk_X509_NAME_new_null());
1349 ASSERT_TRUE(stack);
David Benjamin2908dd12018-06-29 17:46:42 -04001350 ASSERT_TRUE(PushToStack(stack.get(), std::move(name_dup)));
David Benjaminc79ae7a2017-08-29 16:09:44 -04001351
1352 // |SSL_set_client_CA_list| takes ownership.
1353 SSL_set_client_CA_list(ssl.get(), stack.release());
1354
1355 STACK_OF(X509_NAME) *result = SSL_get_client_CA_list(ssl.get());
1356 ASSERT_TRUE(result);
1357 ASSERT_EQ(1u, sk_X509_NAME_num(result));
1358 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(result, 0), name.get()));
1359}
1360
1361TEST(SSLTest, AddClientCA) {
1362 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1363 ASSERT_TRUE(ctx);
1364 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1365 ASSERT_TRUE(ssl);
1366
1367 bssl::UniquePtr<X509> cert1 = GetTestCertificate();
1368 bssl::UniquePtr<X509> cert2 = GetChainTestCertificate();
1369 ASSERT_TRUE(cert1 && cert2);
1370 X509_NAME *name1 = X509_get_subject_name(cert1.get());
1371 X509_NAME *name2 = X509_get_subject_name(cert2.get());
1372
1373 EXPECT_EQ(0u, sk_X509_NAME_num(SSL_get_client_CA_list(ssl.get())));
1374
1375 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1376 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert2.get()));
1377
1378 STACK_OF(X509_NAME) *list = SSL_get_client_CA_list(ssl.get());
1379 ASSERT_EQ(2u, sk_X509_NAME_num(list));
1380 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1381 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1382
1383 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1384
1385 list = SSL_get_client_CA_list(ssl.get());
1386 ASSERT_EQ(3u, sk_X509_NAME_num(list));
1387 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1388 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1389 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 2), name1));
1390}
1391
1392static void AppendSession(SSL_SESSION *session, void *arg) {
1393 std::vector<SSL_SESSION*> *out =
1394 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
1395 out->push_back(session);
1396}
1397
1398// CacheEquals returns true if |ctx|'s session cache consists of |expected|, in
1399// order.
1400static bool CacheEquals(SSL_CTX *ctx,
1401 const std::vector<SSL_SESSION*> &expected) {
1402 // Check the linked list.
1403 SSL_SESSION *ptr = ctx->session_cache_head;
1404 for (SSL_SESSION *session : expected) {
1405 if (ptr != session) {
1406 return false;
1407 }
1408 // TODO(davidben): This is an absurd way to denote the end of the list.
1409 if (ptr->next ==
1410 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
1411 ptr = nullptr;
1412 } else {
1413 ptr = ptr->next;
1414 }
1415 }
1416 if (ptr != nullptr) {
1417 return false;
1418 }
1419
1420 // Check the hash table.
1421 std::vector<SSL_SESSION*> actual, expected_copy;
David Benjamin9eaa3bd2017-09-27 17:03:54 -04001422 lh_SSL_SESSION_doall_arg(ctx->sessions, AppendSession, &actual);
David Benjaminc79ae7a2017-08-29 16:09:44 -04001423 expected_copy = expected;
1424
1425 std::sort(actual.begin(), actual.end());
1426 std::sort(expected_copy.begin(), expected_copy.end());
1427
1428 return actual == expected_copy;
1429}
1430
1431static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
1432 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
1433 if (!ssl_ctx) {
1434 return nullptr;
1435 }
1436 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new(ssl_ctx.get()));
1437 if (!ret) {
1438 return nullptr;
1439 }
1440
David Benjaminaaef8332018-06-29 16:45:49 -04001441 uint8_t id[SSL3_SSL_SESSION_ID_LENGTH] = {0};
1442 OPENSSL_memcpy(id, &number, sizeof(number));
1443 if (!SSL_SESSION_set1_id(ret.get(), id, sizeof(id))) {
1444 return nullptr;
1445 }
David Benjaminc79ae7a2017-08-29 16:09:44 -04001446 return ret;
1447}
1448
1449// Test that the internal session cache behaves as expected.
1450TEST(SSLTest, InternalSessionCache) {
1451 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1452 ASSERT_TRUE(ctx);
1453
1454 // Prepare 10 test sessions.
1455 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
1456 for (int i = 0; i < 10; i++) {
1457 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
1458 ASSERT_TRUE(session);
1459 sessions.push_back(std::move(session));
1460 }
1461
1462 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1463
1464 // Insert all the test sessions.
1465 for (const auto &session : sessions) {
1466 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), session.get()));
1467 }
1468
1469 // Only the last five should be in the list.
1470 ASSERT_TRUE(CacheEquals(
1471 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
1472 sessions[6].get(), sessions[5].get()}));
1473
1474 // Inserting an element already in the cache should fail and leave the cache
1475 // unchanged.
1476 ASSERT_FALSE(SSL_CTX_add_session(ctx.get(), sessions[7].get()));
1477 ASSERT_TRUE(CacheEquals(
1478 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
1479 sessions[6].get(), sessions[5].get()}));
1480
1481 // Although collisions should be impossible (256-bit session IDs), the cache
1482 // must handle them gracefully.
1483 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
1484 ASSERT_TRUE(collision);
1485 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), collision.get()));
1486 ASSERT_TRUE(CacheEquals(
1487 ctx.get(), {collision.get(), sessions[9].get(), sessions[8].get(),
1488 sessions[6].get(), sessions[5].get()}));
1489
1490 // Removing sessions behaves correctly.
1491 ASSERT_TRUE(SSL_CTX_remove_session(ctx.get(), sessions[6].get()));
1492 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
1493 sessions[8].get(), sessions[5].get()}));
1494
1495 // Removing sessions requires an exact match.
1496 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[0].get()));
1497 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[7].get()));
1498
1499 // The cache remains unchanged.
1500 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
1501 sessions[8].get(), sessions[5].get()}));
1502}
1503
1504static uint16_t EpochFromSequence(uint64_t seq) {
1505 return static_cast<uint16_t>(seq >> 48);
1506}
1507
David Benjamin71dfad42017-07-16 17:27:39 -04001508static const uint8_t kTestName[] = {
1509 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
1510 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
1511 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
1512 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
1513 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
1514 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64,
1515};
1516
David Benjaminb79cc842016-12-07 15:57:14 -05001517static bool CompleteHandshakes(SSL *client, SSL *server) {
1518 // Drive both their handshakes to completion.
1519 for (;;) {
1520 int client_ret = SSL_do_handshake(client);
1521 int client_err = SSL_get_error(client, client_ret);
1522 if (client_err != SSL_ERROR_NONE &&
1523 client_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001524 client_err != SSL_ERROR_WANT_WRITE &&
1525 client_err != SSL_ERROR_PENDING_TICKET) {
David Benjaminb79cc842016-12-07 15:57:14 -05001526 fprintf(stderr, "Client error: %d\n", client_err);
1527 return false;
1528 }
1529
1530 int server_ret = SSL_do_handshake(server);
1531 int server_err = SSL_get_error(server, server_ret);
1532 if (server_err != SSL_ERROR_NONE &&
1533 server_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001534 server_err != SSL_ERROR_WANT_WRITE &&
1535 server_err != SSL_ERROR_PENDING_TICKET) {
David Benjaminb79cc842016-12-07 15:57:14 -05001536 fprintf(stderr, "Server error: %d\n", server_err);
1537 return false;
1538 }
1539
1540 if (client_ret == 1 && server_ret == 1) {
1541 break;
1542 }
1543 }
1544
1545 return true;
1546}
1547
David Benjamina8614602017-09-06 15:40:19 -04001548struct ClientConfig {
1549 SSL_SESSION *session = nullptr;
1550 std::string servername;
1551};
1552
David Benjaminb79cc842016-12-07 15:57:14 -05001553static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client,
1554 bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001555 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
Adam Langleyddb57cf2018-01-26 09:17:53 -08001556 const ClientConfig &config = ClientConfig(),
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001557 bool do_handshake = true,
1558 bool shed_handshake_config = true) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001559 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001560 if (!client || !server) {
1561 return false;
1562 }
1563 SSL_set_connect_state(client.get());
1564 SSL_set_accept_state(server.get());
1565
David Benjamina8614602017-09-06 15:40:19 -04001566 if (config.session) {
1567 SSL_set_session(client.get(), config.session);
1568 }
1569 if (!config.servername.empty() &&
1570 !SSL_set_tlsext_host_name(client.get(), config.servername.c_str())) {
1571 return false;
1572 }
David Benjamina20e5352016-08-02 19:09:41 -04001573
David Benjaminde942382016-02-11 12:02:01 -05001574 BIO *bio1, *bio2;
1575 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1576 return false;
1577 }
1578 // SSL_set_bio takes ownership.
1579 SSL_set_bio(client.get(), bio1, bio1);
1580 SSL_set_bio(server.get(), bio2, bio2);
1581
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001582 SSL_set_shed_handshake_config(client.get(), shed_handshake_config);
1583 SSL_set_shed_handshake_config(server.get(), shed_handshake_config);
1584
Adam Langleyddb57cf2018-01-26 09:17:53 -08001585 if (do_handshake && !CompleteHandshakes(client.get(), server.get())) {
David Benjaminb79cc842016-12-07 15:57:14 -05001586 return false;
David Benjaminde942382016-02-11 12:02:01 -05001587 }
1588
David Benjamin686bb192016-05-10 15:15:41 -04001589 *out_client = std::move(client);
1590 *out_server = std::move(server);
1591 return true;
1592}
1593
David Benjaminc11ea9422017-08-29 16:33:21 -04001594// SSLVersionTest executes its test cases under all available protocol versions.
1595// Test cases call |Connect| to create a connection using context objects with
1596// the protocol version fixed to the current version under test.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001597class SSLVersionTest : public ::testing::TestWithParam<VersionParam> {
1598 protected:
1599 SSLVersionTest() : cert_(GetTestCertificate()), key_(GetTestKey()) {}
1600
1601 void SetUp() { ResetContexts(); }
1602
1603 bssl::UniquePtr<SSL_CTX> CreateContext() const {
1604 const SSL_METHOD *method = is_dtls() ? DTLS_method() : TLS_method();
1605 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
1606 if (!ctx || !SSL_CTX_set_min_proto_version(ctx.get(), version()) ||
1607 !SSL_CTX_set_max_proto_version(ctx.get(), version())) {
1608 return nullptr;
1609 }
1610 return ctx;
David Benjamin0fef3052016-11-18 15:11:10 +09001611 }
David Benjamin686bb192016-05-10 15:15:41 -04001612
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001613 void ResetContexts() {
1614 ASSERT_TRUE(cert_);
1615 ASSERT_TRUE(key_);
1616 client_ctx_ = CreateContext();
1617 ASSERT_TRUE(client_ctx_);
1618 server_ctx_ = CreateContext();
1619 ASSERT_TRUE(server_ctx_);
1620 // Set up a server cert. Client certs can be set up explicitly.
1621 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09001622 }
David Benjamin686bb192016-05-10 15:15:41 -04001623
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001624 bool UseCertAndKey(SSL_CTX *ctx) const {
1625 return SSL_CTX_use_certificate(ctx, cert_.get()) &&
1626 SSL_CTX_use_PrivateKey(ctx, key_.get());
David Benjamin0fef3052016-11-18 15:11:10 +09001627 }
David Benjamin686bb192016-05-10 15:15:41 -04001628
David Benjamina8614602017-09-06 15:40:19 -04001629 bool Connect(const ClientConfig &config = ClientConfig()) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001630 return ConnectClientAndServer(&client_, &server_, client_ctx_.get(),
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001631 server_ctx_.get(), config, true,
1632 shed_handshake_config_);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001633 }
1634
1635 uint16_t version() const { return GetParam().version; }
1636
1637 bool is_dtls() const {
1638 return GetParam().ssl_method == VersionParam::is_dtls;
1639 }
1640
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001641 bool shed_handshake_config_ = true;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001642 bssl::UniquePtr<SSL> client_, server_;
1643 bssl::UniquePtr<SSL_CTX> server_ctx_, client_ctx_;
1644 bssl::UniquePtr<X509> cert_;
1645 bssl::UniquePtr<EVP_PKEY> key_;
1646};
1647
1648INSTANTIATE_TEST_CASE_P(WithVersion, SSLVersionTest,
1649 testing::ValuesIn(kAllVersions),
1650 [](const testing::TestParamInfo<VersionParam> &i) {
1651 return i.param.name;
1652 });
1653
1654TEST_P(SSLVersionTest, SequenceNumber) {
1655 ASSERT_TRUE(Connect());
1656
David Benjamin0fef3052016-11-18 15:11:10 +09001657 // Drain any post-handshake messages to ensure there are no unread records
1658 // on either end.
1659 uint8_t byte = 0;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001660 ASSERT_LE(SSL_read(client_.get(), &byte, 1), 0);
1661 ASSERT_LE(SSL_read(server_.get(), &byte, 1), 0);
David Benjaminde942382016-02-11 12:02:01 -05001662
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001663 uint64_t client_read_seq = SSL_get_read_sequence(client_.get());
1664 uint64_t client_write_seq = SSL_get_write_sequence(client_.get());
1665 uint64_t server_read_seq = SSL_get_read_sequence(server_.get());
1666 uint64_t server_write_seq = SSL_get_write_sequence(server_.get());
Steven Valdez2c62fe92016-10-14 12:08:12 -04001667
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001668 if (is_dtls()) {
David Benjamin0fef3052016-11-18 15:11:10 +09001669 // Both client and server must be at epoch 1.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001670 EXPECT_EQ(EpochFromSequence(client_read_seq), 1);
1671 EXPECT_EQ(EpochFromSequence(client_write_seq), 1);
1672 EXPECT_EQ(EpochFromSequence(server_read_seq), 1);
1673 EXPECT_EQ(EpochFromSequence(server_write_seq), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09001674
1675 // The next record to be written should exceed the largest received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001676 EXPECT_GT(client_write_seq, server_read_seq);
1677 EXPECT_GT(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09001678 } else {
1679 // The next record to be written should equal the next to be received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001680 EXPECT_EQ(client_write_seq, server_read_seq);
1681 EXPECT_EQ(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09001682 }
1683
1684 // Send a record from client to server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001685 EXPECT_EQ(SSL_write(client_.get(), &byte, 1), 1);
1686 EXPECT_EQ(SSL_read(server_.get(), &byte, 1), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09001687
1688 // The client write and server read sequence numbers should have
1689 // incremented.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001690 EXPECT_EQ(client_write_seq + 1, SSL_get_write_sequence(client_.get()));
1691 EXPECT_EQ(server_read_seq + 1, SSL_get_read_sequence(server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05001692}
1693
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001694TEST_P(SSLVersionTest, OneSidedShutdown) {
David Benjamin68f37b72016-11-18 15:14:42 +09001695 // SSL_shutdown is a no-op in DTLS.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001696 if (is_dtls()) {
1697 return;
David Benjamin686bb192016-05-10 15:15:41 -04001698 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001699 ASSERT_TRUE(Connect());
David Benjamin686bb192016-05-10 15:15:41 -04001700
1701 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1702 // one side has shut down.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001703 ASSERT_EQ(SSL_shutdown(client_.get()), 0);
David Benjamin686bb192016-05-10 15:15:41 -04001704
1705 // Reading from the server should consume the EOF.
1706 uint8_t byte;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001707 ASSERT_EQ(SSL_read(server_.get(), &byte, 1), 0);
1708 ASSERT_EQ(SSL_get_error(server_.get(), 0), SSL_ERROR_ZERO_RETURN);
David Benjamin686bb192016-05-10 15:15:41 -04001709
1710 // However, the server may continue to write data and then shut down the
1711 // connection.
1712 byte = 42;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001713 ASSERT_EQ(SSL_write(server_.get(), &byte, 1), 1);
1714 ASSERT_EQ(SSL_read(client_.get(), &byte, 1), 1);
1715 ASSERT_EQ(byte, 42);
David Benjamin686bb192016-05-10 15:15:41 -04001716
1717 // The server may then shutdown the connection.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001718 EXPECT_EQ(SSL_shutdown(server_.get()), 1);
1719 EXPECT_EQ(SSL_shutdown(client_.get()), 1);
David Benjamin686bb192016-05-10 15:15:41 -04001720}
David Benjamin68f37b72016-11-18 15:14:42 +09001721
David Benjaminf0d8e222017-02-04 10:58:26 -05001722TEST(SSLTest, SessionDuplication) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001723 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1724 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001725 ASSERT_TRUE(client_ctx);
1726 ASSERT_TRUE(server_ctx);
Steven Valdez87eab492016-06-27 16:34:59 -04001727
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001728 bssl::UniquePtr<X509> cert = GetTestCertificate();
1729 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminf0d8e222017-02-04 10:58:26 -05001730 ASSERT_TRUE(cert);
1731 ASSERT_TRUE(key);
1732 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
1733 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04001734
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001735 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05001736 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04001737 server_ctx.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04001738
1739 SSL_SESSION *session0 = SSL_get_session(client.get());
David Benjamin31b0c9b2017-07-20 14:49:15 -04001740 bssl::UniquePtr<SSL_SESSION> session1 =
1741 bssl::SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL);
David Benjaminf0d8e222017-02-04 10:58:26 -05001742 ASSERT_TRUE(session1);
David Benjamin4501bd52016-08-01 13:39:41 -04001743
David Benjamina3a71e92018-06-29 13:24:45 -04001744 session1->not_resumable = false;
Steven Valdez84b5c002016-08-25 16:30:58 -04001745
Steven Valdez87eab492016-06-27 16:34:59 -04001746 uint8_t *s0_bytes, *s1_bytes;
1747 size_t s0_len, s1_len;
1748
David Benjaminf0d8e222017-02-04 10:58:26 -05001749 ASSERT_TRUE(SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001750 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001751
David Benjaminf0d8e222017-02-04 10:58:26 -05001752 ASSERT_TRUE(SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001753 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001754
David Benjamin7d7554b2017-02-04 11:48:59 -05001755 EXPECT_EQ(Bytes(s0_bytes, s0_len), Bytes(s1_bytes, s1_len));
Steven Valdez87eab492016-06-27 16:34:59 -04001756}
David Benjamin686bb192016-05-10 15:15:41 -04001757
David Benjaminf0d8e222017-02-04 10:58:26 -05001758static void ExpectFDs(const SSL *ssl, int rfd, int wfd) {
David Benjaminca743582017-06-15 17:51:35 -04001759 EXPECT_EQ(rfd, SSL_get_fd(ssl));
David Benjaminf0d8e222017-02-04 10:58:26 -05001760 EXPECT_EQ(rfd, SSL_get_rfd(ssl));
1761 EXPECT_EQ(wfd, SSL_get_wfd(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04001762
1763 // The wrapper BIOs are always equal when fds are equal, even if set
1764 // individually.
David Benjaminf0d8e222017-02-04 10:58:26 -05001765 if (rfd == wfd) {
1766 EXPECT_EQ(SSL_get_rbio(ssl), SSL_get_wbio(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04001767 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001768}
1769
David Benjaminf0d8e222017-02-04 10:58:26 -05001770TEST(SSLTest, SetFD) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001771 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001772 ASSERT_TRUE(ctx);
David Benjamin5c0fb882016-06-14 14:03:51 -04001773
1774 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001775 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001776 ASSERT_TRUE(ssl);
1777 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1778 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
1779 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04001780
1781 // Test setting the same FD.
1782 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001783 ASSERT_TRUE(ssl);
1784 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1785 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001786
1787 // Test setting the same FD one side at a time.
1788 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001789 ASSERT_TRUE(ssl);
1790 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1791 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1792 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001793
1794 // Test setting the same FD in the other order.
1795 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001796 ASSERT_TRUE(ssl);
1797 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1798 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1799 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001800
David Benjamin5c0fb882016-06-14 14:03:51 -04001801 // Test changing the read FD partway through.
1802 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001803 ASSERT_TRUE(ssl);
1804 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1805 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 2));
1806 ExpectFDs(ssl.get(), 2, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001807
1808 // Test changing the write FD partway through.
1809 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001810 ASSERT_TRUE(ssl);
1811 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1812 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
1813 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04001814
1815 // Test a no-op change to the read FD partway through.
1816 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001817 ASSERT_TRUE(ssl);
1818 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1819 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1820 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001821
1822 // Test a no-op change to the write FD partway through.
1823 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001824 ASSERT_TRUE(ssl);
1825 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1826 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1827 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001828
1829 // ASan builds will implicitly test that the internal |BIO| reference-counting
1830 // is correct.
David Benjamin5c0fb882016-06-14 14:03:51 -04001831}
1832
David Benjaminf0d8e222017-02-04 10:58:26 -05001833TEST(SSLTest, SetBIO) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001834 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001835 ASSERT_TRUE(ctx);
David Benjamin4501bd52016-08-01 13:39:41 -04001836
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001837 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1838 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04001839 bio3(BIO_new(BIO_s_mem()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001840 ASSERT_TRUE(ssl);
1841 ASSERT_TRUE(bio1);
1842 ASSERT_TRUE(bio2);
1843 ASSERT_TRUE(bio3);
David Benjamin4501bd52016-08-01 13:39:41 -04001844
1845 // SSL_set_bio takes one reference when the parameters are the same.
1846 BIO_up_ref(bio1.get());
1847 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1848
1849 // Repeating the call does nothing.
1850 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1851
1852 // It takes one reference each when the parameters are different.
1853 BIO_up_ref(bio2.get());
1854 BIO_up_ref(bio3.get());
1855 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1856
1857 // Repeating the call does nothing.
1858 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1859
1860 // It takes one reference when changing only wbio.
1861 BIO_up_ref(bio1.get());
1862 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1863
1864 // It takes one reference when changing only rbio and the two are different.
1865 BIO_up_ref(bio3.get());
1866 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1867
1868 // If setting wbio to rbio, it takes no additional references.
1869 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1870
1871 // From there, wbio may be switched to something else.
1872 BIO_up_ref(bio1.get());
1873 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1874
1875 // If setting rbio to wbio, it takes no additional references.
1876 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1877
1878 // From there, rbio may be switched to something else, but, for historical
1879 // reasons, it takes a reference to both parameters.
1880 BIO_up_ref(bio1.get());
1881 BIO_up_ref(bio2.get());
1882 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1883
1884 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1885 // is correct.
David Benjamin4501bd52016-08-01 13:39:41 -04001886}
1887
David Benjamin25490f22016-07-14 00:22:54 -04001888static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1889
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001890TEST_P(SSLVersionTest, GetPeerCertificate) {
1891 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04001892
David Benjamin0fef3052016-11-18 15:11:10 +09001893 // Configure both client and server to accept any certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001894 SSL_CTX_set_verify(client_ctx_.get(),
1895 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1896 nullptr);
1897 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
1898 SSL_CTX_set_verify(server_ctx_.get(),
1899 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1900 nullptr);
1901 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjaminadd5e522016-07-14 00:33:24 -04001902
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001903 ASSERT_TRUE(Connect());
David Benjaminadd5e522016-07-14 00:33:24 -04001904
David Benjamin0fef3052016-11-18 15:11:10 +09001905 // Client and server should both see the leaf certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001906 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1907 ASSERT_TRUE(peer);
1908 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04001909
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001910 peer.reset(SSL_get_peer_certificate(client_.get()));
1911 ASSERT_TRUE(peer);
1912 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04001913
David Benjamine664a532017-07-20 20:19:36 -04001914 // However, for historical reasons, the X509 chain includes the leaf on the
David Benjamin0fef3052016-11-18 15:11:10 +09001915 // client, but does not on the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001916 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(client_.get())), 1u);
1917 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(client_.get())),
1918 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04001919
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001920 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(server_.get())), 0u);
1921 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(server_.get())),
1922 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04001923}
1924
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001925TEST_P(SSLVersionTest, NoPeerCertificate) {
1926 SSL_CTX_set_verify(server_ctx_.get(), SSL_VERIFY_PEER, nullptr);
1927 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
1928 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
David Benjamine664a532017-07-20 20:19:36 -04001929
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001930 ASSERT_TRUE(Connect());
David Benjamine664a532017-07-20 20:19:36 -04001931
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001932 // Server should not see a peer certificate.
1933 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1934 ASSERT_FALSE(peer);
1935 ASSERT_FALSE(SSL_get0_peer_certificates(server_.get()));
David Benjamine664a532017-07-20 20:19:36 -04001936}
1937
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001938TEST_P(SSLVersionTest, RetainOnlySHA256OfCerts) {
David Benjamin25490f22016-07-14 00:22:54 -04001939 uint8_t *cert_der = NULL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001940 int cert_der_len = i2d_X509(cert_.get(), &cert_der);
1941 ASSERT_GE(cert_der_len, 0);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001942 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04001943
1944 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1945 SHA256(cert_der, cert_der_len, cert_sha256);
1946
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001947 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
1948
David Benjamin0fef3052016-11-18 15:11:10 +09001949 // Configure both client and server to accept any certificate, but the
1950 // server must retain only the SHA-256 of the peer.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001951 SSL_CTX_set_verify(client_ctx_.get(),
1952 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1953 nullptr);
1954 SSL_CTX_set_verify(server_ctx_.get(),
1955 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1956 nullptr);
1957 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
1958 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
1959 SSL_CTX_set_retain_only_sha256_of_client_certs(server_ctx_.get(), 1);
David Benjamin25490f22016-07-14 00:22:54 -04001960
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001961 ASSERT_TRUE(Connect());
David Benjamin25490f22016-07-14 00:22:54 -04001962
David Benjamin0fef3052016-11-18 15:11:10 +09001963 // The peer certificate has been dropped.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001964 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1965 EXPECT_FALSE(peer);
David Benjamin25490f22016-07-14 00:22:54 -04001966
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001967 SSL_SESSION *session = SSL_get_session(server_.get());
David Benjamin02de7bd2018-05-08 18:13:54 -04001968 EXPECT_TRUE(SSL_SESSION_has_peer_sha256(session));
David Benjamin25490f22016-07-14 00:22:54 -04001969
David Benjamin02de7bd2018-05-08 18:13:54 -04001970 const uint8_t *peer_sha256;
1971 size_t peer_sha256_len;
1972 SSL_SESSION_get0_peer_sha256(session, &peer_sha256, &peer_sha256_len);
1973 EXPECT_EQ(Bytes(cert_sha256), Bytes(peer_sha256, peer_sha256_len));
David Benjamin25490f22016-07-14 00:22:54 -04001974}
1975
David Benjamin737d2df2017-09-25 15:05:19 -04001976// Tests that our ClientHellos do not change unexpectedly. These are purely
1977// change detection tests. If they fail as part of an intentional ClientHello
1978// change, update the test vector.
1979TEST(SSLTest, ClientHello) {
1980 struct {
1981 uint16_t max_version;
1982 std::vector<uint8_t> expected;
1983 } kTests[] = {
David Benjamin737d2df2017-09-25 15:05:19 -04001984 {TLS1_VERSION,
1985 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x01, 0x00,
1986 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1987 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1988 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
1989 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
Adam Langleyd6680952018-08-23 08:01:23 -07001990 0x01, 0x00, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01,
1991 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
1992 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
David Benjamin737d2df2017-09-25 15:05:19 -04001993 {TLS1_1_VERSION,
1994 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x02, 0x00,
1995 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1996 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1997 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
1998 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
Adam Langleyd6680952018-08-23 08:01:23 -07001999 0x01, 0x00, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01,
2000 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
2001 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
David Benjamin737d2df2017-09-25 15:05:19 -04002002 {TLS1_2_VERSION,
David Benjamin6e678ee2018-04-16 19:54:42 -04002003 {0x16, 0x03, 0x01, 0x00, 0x82, 0x01, 0x00, 0x00, 0x7e, 0x03, 0x03, 0x00,
David Benjamin737d2df2017-09-25 15:05:19 -04002004 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2005 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
David Benjamin6e678ee2018-04-16 19:54:42 -04002006 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xcc, 0xa9,
David Benjamin737d2df2017-09-25 15:05:19 -04002007 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xc0, 0x09,
David Benjamin6e678ee2018-04-16 19:54:42 -04002008 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
Adam Langleyd6680952018-08-23 08:01:23 -07002009 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37, 0x00, 0x17, 0x00, 0x00,
2010 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00,
2011 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
2012 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04, 0x03, 0x08,
2013 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06,
2014 0x01, 0x02, 0x01}},
David Benjamin737d2df2017-09-25 15:05:19 -04002015 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
2016 // implementation has settled enough that it won't change.
David Benjaminafc64de2016-07-19 17:12:41 +02002017 };
David Benjamin737d2df2017-09-25 15:05:19 -04002018
2019 for (const auto &t : kTests) {
2020 SCOPED_TRACE(t.max_version);
2021
2022 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2023 ASSERT_TRUE(ctx);
2024 // Our default cipher list varies by CPU capabilities, so manually place the
2025 // ChaCha20 ciphers in front.
2026 const char *cipher_list = "CHACHA20:ALL";
David Benjamin737d2df2017-09-25 15:05:19 -04002027 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), t.max_version));
2028 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list));
2029
2030 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
2031 ASSERT_TRUE(ssl);
2032 std::vector<uint8_t> client_hello;
2033 ASSERT_TRUE(GetClientHello(ssl.get(), &client_hello));
2034
2035 // Zero the client_random.
2036 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
2037 1 + 3 + // handshake message header
2038 2; // client_version
2039 ASSERT_GE(client_hello.size(), kRandomOffset + SSL3_RANDOM_SIZE);
2040 OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
2041
2042 if (client_hello != t.expected) {
2043 ADD_FAILURE() << "ClientHellos did not match.";
2044 // Print the value manually so it is easier to update the test vector.
2045 for (size_t i = 0; i < client_hello.size(); i += 12) {
2046 printf(" %c", i == 0 ? '{' : ' ');
2047 for (size_t j = i; j < client_hello.size() && j < i + 12; j++) {
2048 if (j > i) {
2049 printf(" ");
2050 }
2051 printf("0x%02x", client_hello[j]);
2052 if (j < client_hello.size() - 1) {
2053 printf(",");
2054 }
2055 }
2056 if (i + 12 >= client_hello.size()) {
Adam Langleyd6680952018-08-23 08:01:23 -07002057 printf("}},");
David Benjamin737d2df2017-09-25 15:05:19 -04002058 }
2059 printf("\n");
2060 }
2061 }
David Benjaminafc64de2016-07-19 17:12:41 +02002062 }
David Benjaminafc64de2016-07-19 17:12:41 +02002063}
2064
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002065static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04002066
2067static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
2068 // Save the most recent session.
2069 g_last_session.reset(session);
2070 return 1;
2071}
2072
David Benjamina8614602017-09-06 15:40:19 -04002073static bssl::UniquePtr<SSL_SESSION> CreateClientSession(
2074 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2075 const ClientConfig &config = ClientConfig()) {
David Benjamina20e5352016-08-02 19:09:41 -04002076 g_last_session = nullptr;
2077 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2078
2079 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002080 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04002081 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
David Benjamina8614602017-09-06 15:40:19 -04002082 config)) {
David Benjamina20e5352016-08-02 19:09:41 -04002083 fprintf(stderr, "Failed to connect client and server.\n");
2084 return nullptr;
2085 }
2086
2087 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2088 SSL_read(client.get(), nullptr, 0);
2089
2090 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2091
2092 if (!g_last_session) {
2093 fprintf(stderr, "Client did not receive a session.\n");
2094 return nullptr;
2095 }
2096 return std::move(g_last_session);
2097}
2098
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002099static void ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2100 SSL_SESSION *session, bool want_reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002101 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002102 ClientConfig config;
2103 config.session = session;
2104 EXPECT_TRUE(
2105 ConnectClientAndServer(&client, &server, client_ctx, server_ctx, config));
David Benjamina20e5352016-08-02 19:09:41 -04002106
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002107 EXPECT_EQ(SSL_session_reused(client.get()), SSL_session_reused(server.get()));
David Benjamina20e5352016-08-02 19:09:41 -04002108
2109 bool was_reused = !!SSL_session_reused(client.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002110 EXPECT_EQ(was_reused, want_reused);
David Benjamina20e5352016-08-02 19:09:41 -04002111}
2112
David Benjamin3c51d9b2016-11-01 17:50:42 -04002113static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
2114 SSL_CTX *server_ctx,
2115 SSL_SESSION *session) {
2116 g_last_session = nullptr;
2117 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2118
2119 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002120 ClientConfig config;
2121 config.session = session;
2122 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
2123 config)) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002124 fprintf(stderr, "Failed to connect client and server.\n");
2125 return nullptr;
2126 }
2127
2128 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2129 fprintf(stderr, "Client and server were inconsistent.\n");
2130 return nullptr;
2131 }
2132
2133 if (!SSL_session_reused(client.get())) {
2134 fprintf(stderr, "Session was not reused.\n");
2135 return nullptr;
2136 }
2137
2138 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2139 SSL_read(client.get(), nullptr, 0);
2140
2141 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2142
2143 if (!g_last_session) {
2144 fprintf(stderr, "Client did not receive a renewed session.\n");
2145 return nullptr;
2146 }
2147 return std::move(g_last_session);
2148}
2149
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002150static void ExpectTicketKeyChanged(SSL_CTX *ctx, uint8_t *inout_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002151 bool changed) {
2152 uint8_t new_key[kTicketKeyLen];
David Benjaminc11ea9422017-08-29 16:33:21 -04002153 // May return 0, 1 or 48.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002154 ASSERT_EQ(SSL_CTX_get_tlsext_ticket_keys(ctx, new_key, kTicketKeyLen), 1);
2155 if (changed) {
2156 ASSERT_NE(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
2157 } else {
2158 ASSERT_EQ(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002159 }
2160 OPENSSL_memcpy(inout_key, new_key, kTicketKeyLen);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002161}
2162
David Benjamina933c382016-10-28 00:10:03 -04002163static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
2164 static const uint8_t kContext[] = {3};
2165
2166 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
2167 return SSL_TLSEXT_ERR_ALERT_FATAL;
2168 }
2169
2170 return SSL_TLSEXT_ERR_OK;
2171}
2172
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002173TEST_P(SSLVersionTest, SessionIDContext) {
David Benjamina20e5352016-08-02 19:09:41 -04002174 static const uint8_t kContext1[] = {1};
2175 static const uint8_t kContext2[] = {2};
2176
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002177 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2178 sizeof(kContext1)));
David Benjamina20e5352016-08-02 19:09:41 -04002179
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002180 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2181 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002182
David Benjamin0fef3052016-11-18 15:11:10 +09002183 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002184 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2185 ASSERT_TRUE(session);
David Benjamina20e5352016-08-02 19:09:41 -04002186
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002187 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2188 session.get(),
2189 true /* expect session reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002190
David Benjamin0fef3052016-11-18 15:11:10 +09002191 // Change the session ID context.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002192 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext2,
2193 sizeof(kContext2)));
David Benjamina20e5352016-08-02 19:09:41 -04002194
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002195 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2196 session.get(),
2197 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002198
David Benjamin0fef3052016-11-18 15:11:10 +09002199 // Change the session ID context back and install an SNI callback to switch
2200 // it.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002201 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2202 sizeof(kContext1)));
David Benjamina933c382016-10-28 00:10:03 -04002203
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002204 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09002205 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04002206
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002207 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2208 session.get(),
2209 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002210
David Benjamin0fef3052016-11-18 15:11:10 +09002211 // Switch the session ID context with the early callback instead.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002212 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), nullptr);
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002213 SSL_CTX_set_select_certificate_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002214 server_ctx_.get(),
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002215 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
2216 static const uint8_t kContext[] = {3};
2217
2218 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
2219 sizeof(kContext))) {
2220 return ssl_select_cert_error;
2221 }
2222
2223 return ssl_select_cert_success;
2224 });
David Benjamina933c382016-10-28 00:10:03 -04002225
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002226 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2227 session.get(),
2228 false /* expect session not reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002229}
2230
David Benjamin721e8b72016-08-03 13:13:17 -04002231static timeval g_current_time;
2232
2233static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2234 *out_clock = g_current_time;
2235}
2236
David Benjamin17b30832017-01-28 14:00:32 -05002237static void FrozenTimeCallback(const SSL *ssl, timeval *out_clock) {
2238 out_clock->tv_sec = 1000;
2239 out_clock->tv_usec = 0;
2240}
2241
David Benjamin3c51d9b2016-11-01 17:50:42 -04002242static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
2243 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
2244 int encrypt) {
2245 static const uint8_t kZeros[16] = {0};
2246
2247 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -05002248 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamin3c51d9b2016-11-01 17:50:42 -04002249 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -05002250 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002251 return 0;
2252 }
2253
2254 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
2255 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
2256 return -1;
2257 }
2258
2259 // Returning two from the callback in decrypt mode renews the
2260 // session in TLS 1.2 and below.
2261 return encrypt ? 1 : 2;
2262}
2263
David Benjamin123db572016-11-03 16:59:25 -04002264static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjaminaaef8332018-06-29 16:45:49 -04002265 const uint8_t *ticket;
2266 size_t ticket_len;
2267 SSL_SESSION_get0_ticket(session, &ticket, &ticket_len);
2268 if (ticket_len < 16 + 16 + SHA256_DIGEST_LENGTH) {
David Benjamin123db572016-11-03 16:59:25 -04002269 return false;
2270 }
2271
David Benjaminaaef8332018-06-29 16:45:49 -04002272 const uint8_t *ciphertext = ticket + 16 + 16;
2273 size_t len = ticket_len - 16 - 16 - SHA256_DIGEST_LENGTH;
David Benjamin123db572016-11-03 16:59:25 -04002274 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
2275
David Benjamin9b63f292016-11-15 00:44:05 -05002276#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
2277 // Fuzzer-mode tickets are unencrypted.
David Benjamin17cf2cb2016-12-13 01:07:13 -05002278 OPENSSL_memcpy(plaintext.get(), ciphertext, len);
David Benjamin9b63f292016-11-15 00:44:05 -05002279#else
2280 static const uint8_t kZeros[16] = {0};
David Benjaminaaef8332018-06-29 16:45:49 -04002281 const uint8_t *iv = ticket + 16;
David Benjamin123db572016-11-03 16:59:25 -04002282 bssl::ScopedEVP_CIPHER_CTX ctx;
2283 int len1, len2;
2284 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
2285 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
2286 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
2287 return false;
2288 }
2289
2290 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05002291#endif
David Benjamin123db572016-11-03 16:59:25 -04002292
Adam Langley46db7af2017-02-01 15:49:37 -08002293 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
2294 if (!ssl_ctx) {
2295 return false;
2296 }
David Benjamin123db572016-11-03 16:59:25 -04002297 bssl::UniquePtr<SSL_SESSION> server_session(
Adam Langley46db7af2017-02-01 15:49:37 -08002298 SSL_SESSION_from_bytes(plaintext.get(), len, ssl_ctx.get()));
David Benjamin123db572016-11-03 16:59:25 -04002299 if (!server_session) {
2300 return false;
2301 }
2302
David Benjaminaaef8332018-06-29 16:45:49 -04002303 *out = SSL_SESSION_get_time(server_session.get());
David Benjamin123db572016-11-03 16:59:25 -04002304 return true;
2305}
2306
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002307TEST_P(SSLVersionTest, SessionTimeout) {
2308 for (bool server_test : {false, true}) {
2309 SCOPED_TRACE(server_test);
David Benjamin721e8b72016-08-03 13:13:17 -04002310
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002311 ResetContexts();
2312 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2313 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
2314
David Benjamin17b30832017-01-28 14:00:32 -05002315 static const time_t kStartTime = 1000;
David Benjamin0fef3052016-11-18 15:11:10 +09002316 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002317
David Benjamin17b30832017-01-28 14:00:32 -05002318 // We are willing to use a longer lifetime for TLS 1.3 sessions as
2319 // resumptions still perform ECDHE.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002320 const time_t timeout = version() == TLS1_3_VERSION
David Benjamin17b30832017-01-28 14:00:32 -05002321 ? SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT
2322 : SSL_DEFAULT_SESSION_TIMEOUT;
2323
David Benjamin17b30832017-01-28 14:00:32 -05002324 // Both client and server must enforce session timeouts. We configure the
2325 // other side with a frozen clock so it never expires tickets.
David Benjamin0fef3052016-11-18 15:11:10 +09002326 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002327 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2328 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002329 } else {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002330 SSL_CTX_set_current_time_cb(client_ctx_.get(), CurrentTimeCallback);
2331 SSL_CTX_set_current_time_cb(server_ctx_.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002332 }
2333
2334 // Configure a ticket callback which renews tickets.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002335 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002336
2337 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002338 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2339 ASSERT_TRUE(session);
David Benjamin0fef3052016-11-18 15:11:10 +09002340
2341 // Advance the clock just behind the timeout.
David Benjamin17b30832017-01-28 14:00:32 -05002342 g_current_time.tv_sec += timeout - 1;
David Benjamin0fef3052016-11-18 15:11:10 +09002343
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002344 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2345 session.get(),
2346 true /* expect session reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002347
2348 // Advance the clock one more second.
2349 g_current_time.tv_sec++;
2350
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002351 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2352 session.get(),
2353 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002354
2355 // Rewind the clock to before the session was minted.
2356 g_current_time.tv_sec = kStartTime - 1;
2357
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002358 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2359 session.get(),
2360 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002361
David Benjamin0fef3052016-11-18 15:11:10 +09002362 // Renew the session 10 seconds before expiration.
David Benjamin17b30832017-01-28 14:00:32 -05002363 time_t new_start_time = kStartTime + timeout - 10;
2364 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002365 bssl::UniquePtr<SSL_SESSION> new_session = ExpectSessionRenewed(
2366 client_ctx_.get(), server_ctx_.get(), session.get());
2367 ASSERT_TRUE(new_session);
David Benjamin0fef3052016-11-18 15:11:10 +09002368
2369 // This new session is not the same object as before.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002370 EXPECT_NE(session.get(), new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002371
2372 // Check the sessions have timestamps measured from issuance.
2373 long session_time = 0;
2374 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002375 ASSERT_TRUE(GetServerTicketTime(&session_time, new_session.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09002376 } else {
David Benjaminaaef8332018-06-29 16:45:49 -04002377 session_time = SSL_SESSION_get_time(new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002378 }
David Benjamin721e8b72016-08-03 13:13:17 -04002379
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002380 ASSERT_EQ(session_time, g_current_time.tv_sec);
David Benjamin721e8b72016-08-03 13:13:17 -04002381
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002382 if (version() == TLS1_3_VERSION) {
David Benjamin17b30832017-01-28 14:00:32 -05002383 // Renewal incorporates fresh key material in TLS 1.3, so we extend the
2384 // lifetime TLS 1.3.
2385 g_current_time.tv_sec = new_start_time + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002386 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2387 new_session.get(),
2388 true /* expect session reused */));
David Benjamin721e8b72016-08-03 13:13:17 -04002389
David Benjamin17b30832017-01-28 14:00:32 -05002390 // The new session expires after the new timeout.
2391 g_current_time.tv_sec = new_start_time + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002392 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2393 new_session.get(),
2394 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002395
2396 // Renew the session until it begins just past the auth timeout.
2397 time_t auth_end_time = kStartTime + SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
2398 while (new_start_time < auth_end_time - 1000) {
2399 // Get as close as possible to target start time.
2400 new_start_time =
2401 std::min(auth_end_time - 1000, new_start_time + timeout - 1);
2402 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002403 new_session = ExpectSessionRenewed(client_ctx_.get(), server_ctx_.get(),
David Benjamin17b30832017-01-28 14:00:32 -05002404 new_session.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002405 ASSERT_TRUE(new_session);
David Benjamin17b30832017-01-28 14:00:32 -05002406 }
2407
2408 // Now the session's lifetime is bound by the auth timeout.
2409 g_current_time.tv_sec = auth_end_time - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002410 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2411 new_session.get(),
2412 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002413
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 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002418 } else {
2419 // The new session is usable just before the old expiration.
2420 g_current_time.tv_sec = kStartTime + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002421 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2422 new_session.get(),
2423 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002424
2425 // Renewal does not extend the lifetime, so it is not usable beyond the
2426 // old expiration.
2427 g_current_time.tv_sec = kStartTime + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002428 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2429 new_session.get(),
2430 false /* expect session not reused */));
David Benjamin1b22f852016-10-27 16:36:32 -04002431 }
David Benjamin721e8b72016-08-03 13:13:17 -04002432 }
David Benjamin721e8b72016-08-03 13:13:17 -04002433}
2434
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002435TEST_P(SSLVersionTest, DefaultTicketKeyInitialization) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002436 static const uint8_t kZeroKey[kTicketKeyLen] = {};
2437 uint8_t ticket_key[kTicketKeyLen];
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002438 ASSERT_EQ(1, SSL_CTX_get_tlsext_ticket_keys(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002439 kTicketKeyLen));
2440 ASSERT_NE(0, OPENSSL_memcmp(ticket_key, kZeroKey, kTicketKeyLen));
2441}
2442
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002443TEST_P(SSLVersionTest, DefaultTicketKeyRotation) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002444 static const time_t kStartTime = 1001;
2445 g_current_time.tv_sec = kStartTime;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002446
David Benjaminc11ea9422017-08-29 16:33:21 -04002447 // We use session reuse as a proxy for ticket decryption success, hence
2448 // disable session timeouts.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002449 SSL_CTX_set_timeout(server_ctx_.get(), std::numeric_limits<uint32_t>::max());
2450 SSL_CTX_set_session_psk_dhe_timeout(server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002451 std::numeric_limits<uint32_t>::max());
2452
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002453 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2454 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002455
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002456 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2457 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_OFF);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002458
David Benjamin1f0d54b2018-08-09 16:19:13 -05002459 // Initialize ticket_key with the current key and check that it was
2460 // initialized to something, not all zeros.
2461 uint8_t ticket_key[kTicketKeyLen] = {0};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002462 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2463 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002464
David Benjaminc11ea9422017-08-29 16:33:21 -04002465 // Verify ticket resumption actually works.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002466 bssl::UniquePtr<SSL> client, server;
2467 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002468 CreateClientSession(client_ctx_.get(), server_ctx_.get());
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002469 ASSERT_TRUE(session);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002470 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002471 session.get(), true /* reused */));
2472
David Benjaminc11ea9422017-08-29 16:33:21 -04002473 // Advance time to just before key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002474 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL - 1;
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 */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002477 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002478 false /* NOT changed */));
2479
David Benjaminc11ea9422017-08-29 16:33:21 -04002480 // Force key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002481 g_current_time.tv_sec += 1;
2482 bssl::UniquePtr<SSL_SESSION> new_session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002483 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2484 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2485 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002486
David Benjaminc11ea9422017-08-29 16:33:21 -04002487 // Resumption with both old and new ticket should work.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002488 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002489 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002490 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002491 new_session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002492 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002493 false /* NOT changed */));
2494
David Benjaminc11ea9422017-08-29 16:33:21 -04002495 // Force key rotation again. Resumption with the old ticket now fails.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002496 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002497 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002498 session.get(), false /* NOT reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002499 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2500 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002501
David Benjaminc11ea9422017-08-29 16:33:21 -04002502 // But resumption with the newer session still works.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002503 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002504 new_session.get(), true /* reused */));
2505}
2506
David Benjamin0fc37ef2016-08-17 15:29:46 -04002507static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002508 SSL_CTX *ctx = reinterpret_cast<SSL_CTX *>(arg);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002509 SSL_set_SSL_CTX(ssl, ctx);
2510 return SSL_TLSEXT_ERR_OK;
2511}
2512
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002513TEST_P(SSLVersionTest, SNICallback) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002514 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002515 ASSERT_TRUE(cert2);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002516 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002517 ASSERT_TRUE(key2);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002518
David Benjamin0fef3052016-11-18 15:11:10 +09002519 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
2520 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002521
David Benjamin83a32122017-02-14 18:34:54 -05002522 static const uint8_t kSCTList[] = {0, 6, 0, 4, 5, 6, 7, 8};
2523 static const uint8_t kOCSPResponse[] = {1, 2, 3, 4};
2524
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002525 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
2526 ASSERT_TRUE(server_ctx2);
2527 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()));
2528 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()));
2529 ASSERT_TRUE(SSL_CTX_set_signed_cert_timestamp_list(
2530 server_ctx2.get(), kSCTList, sizeof(kSCTList)));
2531 ASSERT_TRUE(SSL_CTX_set_ocsp_response(server_ctx2.get(), kOCSPResponse,
2532 sizeof(kOCSPResponse)));
2533 // Historically signing preferences would be lost in some cases with the
2534 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2535 // this doesn't happen when |version| is TLS 1.2, configure the private
2536 // key to only sign SHA-256.
2537 ASSERT_TRUE(SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
2538 &kECDSAWithSHA256, 1));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002539
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002540 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), SwitchContext);
2541 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002542
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002543 SSL_CTX_enable_signed_cert_timestamps(client_ctx_.get());
2544 SSL_CTX_enable_ocsp_stapling(client_ctx_.get());
David Benjamin83a32122017-02-14 18:34:54 -05002545
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002546 ASSERT_TRUE(Connect());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002547
David Benjamin0fef3052016-11-18 15:11:10 +09002548 // The client should have received |cert2|.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002549 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client_.get()));
2550 ASSERT_TRUE(peer);
2551 EXPECT_EQ(X509_cmp(peer.get(), cert2.get()), 0);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002552
David Benjamin83a32122017-02-14 18:34:54 -05002553 // The client should have received |server_ctx2|'s SCT list.
2554 const uint8_t *data;
2555 size_t len;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002556 SSL_get0_signed_cert_timestamp_list(client_.get(), &data, &len);
2557 EXPECT_EQ(Bytes(kSCTList), Bytes(data, len));
David Benjamin83a32122017-02-14 18:34:54 -05002558
2559 // The client should have received |server_ctx2|'s OCSP response.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002560 SSL_get0_ocsp_response(client_.get(), &data, &len);
2561 EXPECT_EQ(Bytes(kOCSPResponse), Bytes(data, len));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002562}
2563
David Benjaminf0d8e222017-02-04 10:58:26 -05002564// Test that the early callback can swap the maximum version.
2565TEST(SSLTest, EarlyCallbackVersionSwitch) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002566 bssl::UniquePtr<X509> cert = GetTestCertificate();
2567 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2568 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2569 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002570 ASSERT_TRUE(cert);
2571 ASSERT_TRUE(key);
2572 ASSERT_TRUE(server_ctx);
2573 ASSERT_TRUE(client_ctx);
2574 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
2575 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
2576 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
2577 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
David Benjamin99620572016-08-30 00:35:36 -04002578
David Benjaminf0d8e222017-02-04 10:58:26 -05002579 SSL_CTX_set_select_certificate_cb(
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002580 server_ctx.get(),
2581 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
David Benjaminf0d8e222017-02-04 10:58:26 -05002582 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002583 return ssl_select_cert_error;
David Benjaminf0d8e222017-02-04 10:58:26 -05002584 }
2585
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002586 return ssl_select_cert_success;
David Benjaminf0d8e222017-02-04 10:58:26 -05002587 });
David Benjamin99620572016-08-30 00:35:36 -04002588
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002589 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05002590 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04002591 server_ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002592 EXPECT_EQ(TLS1_2_VERSION, SSL_version(client.get()));
David Benjamin99620572016-08-30 00:35:36 -04002593}
2594
David Benjaminf0d8e222017-02-04 10:58:26 -05002595TEST(SSLTest, SetVersion) {
David Benjamin2dc02042016-09-19 19:57:37 -04002596 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002597 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002598
David Benjaminf0d8e222017-02-04 10:58:26 -05002599 // Set valid TLS versions.
2600 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2601 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
2602 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2603 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002604
David Benjaminf0d8e222017-02-04 10:58:26 -05002605 // Invalid TLS versions are rejected.
2606 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2607 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x0200));
2608 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2609 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2610 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x0200));
2611 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002612
David Benjaminf0d8e222017-02-04 10:58:26 -05002613 // Zero is the default version.
2614 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002615 EXPECT_EQ(TLS1_2_VERSION, ctx->conf_max_version);
David Benjaminf0d8e222017-02-04 10:58:26 -05002616 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002617 EXPECT_EQ(TLS1_VERSION, ctx->conf_min_version);
David Benjamin3cfeb952017-03-01 16:48:38 -05002618
David Benjamin9bb15f52018-06-26 00:07:40 -04002619 // TLS 1.3 is available, but not by default.
David Benjamin3cfeb952017-03-01 16:48:38 -05002620 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002621 EXPECT_EQ(TLS1_3_VERSION, ctx->conf_max_version);
David Benjamine34bcc92016-09-21 16:53:09 -04002622
David Benjamin9bb15f52018-06-26 00:07:40 -04002623 // SSL 3.0 is not available.
2624 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION));
2625
David Benjamin353577c2017-06-29 15:54:58 -04002626 // TLS1_3_DRAFT_VERSION is not an API-level version.
Steven Valdez64cc1212017-12-04 11:15:37 -05002627 EXPECT_FALSE(
Steven Valdez7e5dd252018-01-22 15:20:31 -05002628 SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_DRAFT23_VERSION));
David Benjamin353577c2017-06-29 15:54:58 -04002629 ERR_clear_error();
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 Benjamin5df5be12017-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
David Benjamin5869eb32018-07-17 00:59:45 -04004356TEST_P(SSLVersionTest, VerifyBeforeCertRequest) {
4357 // Configure the server to request client certificates.
4358 SSL_CTX_set_custom_verify(
4359 server_ctx_.get(), SSL_VERIFY_PEER,
4360 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
4361
4362 // Configure the client to reject the server certificate.
4363 SSL_CTX_set_custom_verify(
4364 client_ctx_.get(), SSL_VERIFY_PEER,
4365 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_invalid; });
4366
4367 // cert_cb should not be called. Verification should fail first.
4368 SSL_CTX_set_cert_cb(client_ctx_.get(),
4369 [](SSL *ssl, void *arg) {
4370 ADD_FAILURE() << "cert_cb unexpectedly called";
4371 return 0;
4372 },
4373 nullptr);
4374
4375 bssl::UniquePtr<SSL> client, server;
4376 EXPECT_FALSE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
4377 server_ctx_.get()));
4378}
4379
David Benjamin492c9aa2018-08-31 16:35:22 -05004380// Test that ticket-based sessions on the client get fake session IDs.
4381TEST_P(SSLVersionTest, FakeIDsForTickets) {
4382 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4383 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4384
4385 bssl::UniquePtr<SSL_SESSION> session =
4386 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4387 ASSERT_TRUE(session);
4388
4389 EXPECT_TRUE(SSL_SESSION_has_ticket(session.get()));
4390 unsigned session_id_length;
4391 SSL_SESSION_get_id(session.get(), &session_id_length);
4392 EXPECT_NE(session_id_length, 0u);
4393}
4394
David Benjamin6c04bd12018-07-19 18:13:09 -04004395// These tests test multi-threaded behavior. They are intended to run with
4396// ThreadSanitizer.
David Benjamin5b33eff2018-09-22 16:52:48 -07004397#if defined(OPENSSL_THREADS)
David Benjamin6c04bd12018-07-19 18:13:09 -04004398TEST_P(SSLVersionTest, SessionCacheThreads) {
4399 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
4400 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4401 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4402
4403 if (version() == TLS1_3_VERSION) {
4404 // Our TLS 1.3 implementation does not support stateful resumption.
4405 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
4406 return;
4407 }
4408
4409 // Establish two client sessions to test with.
4410 bssl::UniquePtr<SSL_SESSION> session1 =
4411 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4412 ASSERT_TRUE(session1);
4413 bssl::UniquePtr<SSL_SESSION> session2 =
4414 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4415 ASSERT_TRUE(session2);
4416
4417 auto connect_with_session = [&](SSL_SESSION *session) {
4418 ClientConfig config;
4419 config.session = session;
4420 UniquePtr<SSL> client, server;
4421 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
4422 server_ctx_.get(), config));
4423 };
4424
4425 // Resume sessions in parallel with establishing new ones.
4426 {
4427 std::vector<std::thread> threads;
4428 threads.emplace_back([&] { connect_with_session(nullptr); });
4429 threads.emplace_back([&] { connect_with_session(nullptr); });
4430 threads.emplace_back([&] { connect_with_session(session1.get()); });
4431 threads.emplace_back([&] { connect_with_session(session1.get()); });
4432 threads.emplace_back([&] { connect_with_session(session2.get()); });
4433 threads.emplace_back([&] { connect_with_session(session2.get()); });
4434 for (auto &thread : threads) {
4435 thread.join();
4436 }
4437 }
4438
4439 // Hit the maximum session cache size across multiple threads
4440 size_t limit = SSL_CTX_sess_number(server_ctx_.get()) + 2;
4441 SSL_CTX_sess_set_cache_size(server_ctx_.get(), limit);
4442 {
4443 std::vector<std::thread> threads;
4444 for (int i = 0; i < 4; i++) {
4445 threads.emplace_back([&]() {
4446 connect_with_session(nullptr);
4447 EXPECT_LE(SSL_CTX_sess_number(server_ctx_.get()), limit);
4448 });
4449 }
4450 for (auto &thread : threads) {
4451 thread.join();
4452 }
4453 EXPECT_EQ(SSL_CTX_sess_number(server_ctx_.get()), limit);
4454 }
4455}
4456
4457TEST_P(SSLVersionTest, SessionTicketThreads) {
4458 for (bool renew_ticket : {false, true}) {
4459 SCOPED_TRACE(renew_ticket);
4460 ResetContexts();
4461 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4462 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4463 if (renew_ticket) {
4464 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
4465 }
4466
4467 // Establish two client sessions to test with.
4468 bssl::UniquePtr<SSL_SESSION> session1 =
4469 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4470 ASSERT_TRUE(session1);
4471 bssl::UniquePtr<SSL_SESSION> session2 =
4472 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4473 ASSERT_TRUE(session2);
4474
4475 auto connect_with_session = [&](SSL_SESSION *session) {
4476 ClientConfig config;
4477 config.session = session;
4478 UniquePtr<SSL> client, server;
4479 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
4480 server_ctx_.get(), config));
4481 };
4482
4483 // Resume sessions in parallel with establishing new ones.
4484 {
4485 std::vector<std::thread> threads;
4486 threads.emplace_back([&] { connect_with_session(nullptr); });
4487 threads.emplace_back([&] { connect_with_session(nullptr); });
4488 threads.emplace_back([&] { connect_with_session(session1.get()); });
4489 threads.emplace_back([&] { connect_with_session(session1.get()); });
4490 threads.emplace_back([&] { connect_with_session(session2.get()); });
4491 threads.emplace_back([&] { connect_with_session(session2.get()); });
4492 for (auto &thread : threads) {
4493 thread.join();
4494 }
4495 }
4496 }
4497}
4498
4499// SSL_CTX_get0_certificate needs to lock internally. Test this works.
4500TEST(SSLTest, GetCertificateThreads) {
4501 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4502 ASSERT_TRUE(ctx);
4503 bssl::UniquePtr<X509> cert = GetTestCertificate();
4504 ASSERT_TRUE(cert);
4505 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
4506
4507 // Existing code expects |SSL_CTX_get0_certificate| to be callable from two
4508 // threads concurrently. It originally was an immutable operation. Now we
4509 // implement it with a thread-safe cache, so it is worth testing.
4510 X509 *cert2_thread;
4511 std::thread thread(
4512 [&] { cert2_thread = SSL_CTX_get0_certificate(ctx.get()); });
4513 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
4514 thread.join();
4515
4516 EXPECT_EQ(cert2, cert2_thread);
4517 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
4518}
4519#endif
4520
Steven Valdezc8e0f902018-07-14 11:23:01 -04004521constexpr size_t kNumQUICLevels = 4;
4522static_assert(ssl_encryption_initial < kNumQUICLevels,
4523 "kNumQUICLevels is wrong");
4524static_assert(ssl_encryption_early_data < kNumQUICLevels,
4525 "kNumQUICLevels is wrong");
4526static_assert(ssl_encryption_handshake < kNumQUICLevels,
4527 "kNumQUICLevels is wrong");
4528static_assert(ssl_encryption_application < kNumQUICLevels,
4529 "kNumQUICLevels is wrong");
4530
4531class MockQUICTransport {
4532 public:
4533 MockQUICTransport() {
4534 // The caller is expected to configure initial secrets.
4535 levels_[ssl_encryption_initial].write_secret = {1};
4536 levels_[ssl_encryption_initial].read_secret = {1};
4537 }
4538
4539 void set_peer(MockQUICTransport *peer) { peer_ = peer; }
4540
4541 bool has_alert() const { return has_alert_; }
4542 ssl_encryption_level_t alert_level() const { return alert_level_; }
4543 uint8_t alert() const { return alert_; }
4544
4545 bool PeerSecretsMatch(ssl_encryption_level_t level) const {
4546 return levels_[level].write_secret == peer_->levels_[level].read_secret &&
Steven Valdez384d0ea2018-11-06 10:45:36 -05004547 levels_[level].read_secret == peer_->levels_[level].write_secret &&
4548 levels_[level].cipher == peer_->levels_[level].cipher;
Steven Valdezc8e0f902018-07-14 11:23:01 -04004549 }
4550
4551 bool HasSecrets(ssl_encryption_level_t level) const {
4552 return !levels_[level].write_secret.empty() ||
4553 !levels_[level].read_secret.empty();
4554 }
4555
4556 bool SetEncryptionSecrets(ssl_encryption_level_t level,
4557 const uint8_t *read_secret,
Steven Valdez384d0ea2018-11-06 10:45:36 -05004558 const uint8_t *write_secret, size_t secret_len,
4559 const SSL_CIPHER *cipher) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04004560 if (HasSecrets(level)) {
4561 ADD_FAILURE() << "duplicate keys configured";
4562 return false;
4563 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05004564
4565 if (cipher == nullptr) {
4566 ADD_FAILURE() << "current cipher unavailable";
4567 return false;
4568 }
4569
Steven Valdezc8e0f902018-07-14 11:23:01 -04004570 if (level != ssl_encryption_early_data &&
4571 (read_secret == nullptr || write_secret == nullptr)) {
4572 ADD_FAILURE() << "key was unexpectedly null";
4573 return false;
4574 }
4575 if (read_secret != nullptr) {
4576 levels_[level].read_secret.assign(read_secret, read_secret + secret_len);
4577 }
4578 if (write_secret != nullptr) {
4579 levels_[level].write_secret.assign(write_secret,
4580 write_secret + secret_len);
4581 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05004582 levels_[level].cipher = SSL_CIPHER_get_id(cipher);
Steven Valdezc8e0f902018-07-14 11:23:01 -04004583 return true;
4584 }
4585
4586 bool WriteHandshakeData(ssl_encryption_level_t level,
4587 Span<const uint8_t> data) {
4588 if (levels_[level].write_secret.empty()) {
4589 ADD_FAILURE() << "data written before keys configured";
4590 return false;
4591 }
4592 levels_[level].write_data.insert(levels_[level].write_data.end(),
4593 data.begin(), data.end());
4594 return true;
4595 }
4596
4597 bool SendAlert(ssl_encryption_level_t level, uint8_t alert_value) {
4598 if (has_alert_) {
4599 ADD_FAILURE() << "duplicate alert sent";
4600 return false;
4601 }
4602
4603 if (levels_[level].write_secret.empty()) {
4604 ADD_FAILURE() << "alert sent before keys configured";
4605 return false;
4606 }
4607
4608 has_alert_ = true;
4609 alert_level_ = level;
4610 alert_ = alert_value;
4611 return true;
4612 }
4613
4614 bool ReadHandshakeData(std::vector<uint8_t> *out,
4615 ssl_encryption_level_t level,
4616 size_t num = std::numeric_limits<size_t>::max()) {
4617 if (levels_[level].read_secret.empty()) {
4618 ADD_FAILURE() << "data read before keys configured";
4619 return false;
4620 }
4621 // The peer may not have configured any keys yet.
4622 if (peer_->levels_[level].write_secret.empty()) {
4623 return true;
4624 }
4625 // Check the peer computed the same key.
4626 if (peer_->levels_[level].write_secret != levels_[level].read_secret) {
4627 ADD_FAILURE() << "peer write key does not match read key";
4628 return false;
4629 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05004630 if (peer_->levels_[level].cipher != levels_[level].cipher) {
4631 ADD_FAILURE() << "peer cipher does not match";
4632 return false;
4633 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04004634 std::vector<uint8_t> *peer_data = &peer_->levels_[level].write_data;
4635 num = std::min(num, peer_data->size());
4636 out->assign(peer_data->begin(), peer_data->begin() + num);
4637 peer_data->erase(peer_data->begin(), peer_data->begin() + num);
4638 return true;
4639 }
4640
4641 private:
4642 MockQUICTransport *peer_ = nullptr;
4643
4644 bool has_alert_ = false;
4645 ssl_encryption_level_t alert_level_ = ssl_encryption_initial;
4646 uint8_t alert_ = 0;
4647
4648 struct Level {
4649 std::vector<uint8_t> write_data;
4650 std::vector<uint8_t> write_secret;
4651 std::vector<uint8_t> read_secret;
Steven Valdez384d0ea2018-11-06 10:45:36 -05004652 uint32_t cipher = 0;
Steven Valdezc8e0f902018-07-14 11:23:01 -04004653 };
4654 Level levels_[kNumQUICLevels];
4655};
4656
4657class MockQUICTransportPair {
4658 public:
4659 MockQUICTransportPair() {
4660 server_.set_peer(&client_);
4661 client_.set_peer(&server_);
4662 }
4663
4664 ~MockQUICTransportPair() {
4665 server_.set_peer(nullptr);
4666 client_.set_peer(nullptr);
4667 }
4668
4669 MockQUICTransport *client() { return &client_; }
4670 MockQUICTransport *server() { return &server_; }
4671
4672 bool SecretsMatch(ssl_encryption_level_t level) const {
4673 return client_.PeerSecretsMatch(level);
4674 }
4675
4676 private:
4677 MockQUICTransport client_;
4678 MockQUICTransport server_;
4679};
4680
4681class QUICMethodTest : public testing::Test {
4682 protected:
4683 void SetUp() override {
4684 client_ctx_.reset(SSL_CTX_new(TLS_method()));
4685 server_ctx_.reset(SSL_CTX_new(TLS_method()));
4686 ASSERT_TRUE(client_ctx_);
4687 ASSERT_TRUE(server_ctx_);
4688
4689 bssl::UniquePtr<X509> cert = GetTestCertificate();
4690 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4691 ASSERT_TRUE(cert);
4692 ASSERT_TRUE(key);
4693 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx_.get(), cert.get()));
4694 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx_.get(), key.get()));
4695
4696 SSL_CTX_set_min_proto_version(server_ctx_.get(), TLS1_3_VERSION);
4697 SSL_CTX_set_max_proto_version(server_ctx_.get(), TLS1_3_VERSION);
4698 SSL_CTX_set_min_proto_version(client_ctx_.get(), TLS1_3_VERSION);
4699 SSL_CTX_set_max_proto_version(client_ctx_.get(), TLS1_3_VERSION);
4700 }
4701
4702 static MockQUICTransport *TransportFromSSL(const SSL *ssl) {
4703 return ex_data_.Get(ssl);
4704 }
4705
4706 static bool ProvideHandshakeData(
4707 SSL *ssl, size_t num = std::numeric_limits<size_t>::max()) {
4708 MockQUICTransport *transport = TransportFromSSL(ssl);
4709 ssl_encryption_level_t level = SSL_quic_read_level(ssl);
4710 std::vector<uint8_t> data;
4711 return transport->ReadHandshakeData(&data, level, num) &&
4712 SSL_provide_quic_data(ssl, level, data.data(), data.size());
4713 }
4714
4715 bool CreateClientAndServer() {
4716 client_.reset(SSL_new(client_ctx_.get()));
4717 server_.reset(SSL_new(server_ctx_.get()));
4718 if (!client_ || !server_) {
4719 return false;
4720 }
4721
4722 SSL_set_connect_state(client_.get());
4723 SSL_set_accept_state(server_.get());
4724
4725 ex_data_.Set(client_.get(), transport_.client());
4726 ex_data_.Set(server_.get(), transport_.server());
4727 return true;
4728 }
4729
Steven Valdeze6eef1c2018-11-09 13:32:34 -05004730 bool CreateSecondClientAndServer() {
4731 client_.reset(SSL_new(client_ctx_.get()));
4732 server_.reset(SSL_new(server_ctx_.get()));
4733 if (!client_ || !server_) {
4734 return false;
4735 }
4736
4737 SSL_set_connect_state(client_.get());
4738 SSL_set_accept_state(server_.get());
4739
4740 ex_data_.Set(client_.get(), second_transport_.client());
4741 ex_data_.Set(server_.get(), second_transport_.server());
4742 return true;
4743 }
4744
Steven Valdezc8e0f902018-07-14 11:23:01 -04004745 // The following functions may be configured on an |SSL_QUIC_METHOD| as
4746 // default implementations.
4747
4748 static int SetEncryptionSecretsCallback(SSL *ssl,
4749 ssl_encryption_level_t level,
4750 const uint8_t *read_key,
4751 const uint8_t *write_key,
4752 size_t key_len) {
Steven Valdez384d0ea2018-11-06 10:45:36 -05004753 return TransportFromSSL(ssl)->SetEncryptionSecrets(
4754 level, read_key, write_key, key_len, SSL_get_current_cipher(ssl));
Steven Valdezc8e0f902018-07-14 11:23:01 -04004755 }
4756
David Benjamincc9d9352018-10-30 19:45:22 -05004757 static int AddHandshakeDataCallback(SSL *ssl,
4758 enum ssl_encryption_level_t level,
4759 const uint8_t *data, size_t len) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04004760 EXPECT_EQ(level, SSL_quic_write_level(ssl));
4761 return TransportFromSSL(ssl)->WriteHandshakeData(level,
4762 MakeConstSpan(data, len));
4763 }
4764
4765 static int FlushFlightCallback(SSL *ssl) { return 1; }
4766
4767 static int SendAlertCallback(SSL *ssl, ssl_encryption_level_t level,
4768 uint8_t alert) {
4769 EXPECT_EQ(level, SSL_quic_write_level(ssl));
4770 return TransportFromSSL(ssl)->SendAlert(level, alert);
4771 }
4772
4773 bssl::UniquePtr<SSL_CTX> client_ctx_;
4774 bssl::UniquePtr<SSL_CTX> server_ctx_;
4775
4776 static UnownedSSLExData<MockQUICTransport> ex_data_;
4777 MockQUICTransportPair transport_;
Steven Valdeze6eef1c2018-11-09 13:32:34 -05004778 MockQUICTransportPair second_transport_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04004779
4780 bssl::UniquePtr<SSL> client_;
4781 bssl::UniquePtr<SSL> server_;
4782};
4783
4784UnownedSSLExData<MockQUICTransport> QUICMethodTest::ex_data_;
4785
4786// Test a full handshake works.
4787TEST_F(QUICMethodTest, Basic) {
4788 const SSL_QUIC_METHOD quic_method = {
4789 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05004790 AddHandshakeDataCallback,
Steven Valdezc8e0f902018-07-14 11:23:01 -04004791 FlushFlightCallback,
4792 SendAlertCallback,
4793 };
4794
Steven Valdeze6eef1c2018-11-09 13:32:34 -05004795 g_last_session = nullptr;
4796
4797 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4798 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
Steven Valdezc8e0f902018-07-14 11:23:01 -04004799 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
4800 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
4801 ASSERT_TRUE(CreateClientAndServer());
4802
4803 for (;;) {
4804 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
4805 int client_ret = SSL_do_handshake(client_.get());
4806 if (client_ret != 1) {
4807 ASSERT_EQ(client_ret, -1);
4808 ASSERT_EQ(SSL_get_error(client_.get(), client_ret), SSL_ERROR_WANT_READ);
4809 }
4810
4811 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
4812 int server_ret = SSL_do_handshake(server_.get());
4813 if (server_ret != 1) {
4814 ASSERT_EQ(server_ret, -1);
4815 ASSERT_EQ(SSL_get_error(server_.get(), server_ret), SSL_ERROR_WANT_READ);
4816 }
4817
4818 if (client_ret == 1 && server_ret == 1) {
4819 break;
4820 }
4821 }
4822
4823 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
4824 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
4825 EXPECT_TRUE(transport_.SecretsMatch(ssl_encryption_application));
4826 EXPECT_FALSE(transport_.client()->has_alert());
4827 EXPECT_FALSE(transport_.server()->has_alert());
4828
4829 // The server sent NewSessionTicket messages in the handshake.
Steven Valdeze6eef1c2018-11-09 13:32:34 -05004830 EXPECT_FALSE(g_last_session);
4831 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
4832 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
4833 EXPECT_TRUE(g_last_session);
4834
4835 // Create a second connection to verify resumption works.
4836 ASSERT_TRUE(CreateSecondClientAndServer());
4837 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
4838 SSL_set_session(client_.get(), session.get());
4839
4840 for (;;) {
4841 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
4842 int client_ret = SSL_do_handshake(client_.get());
4843 if (client_ret != 1) {
4844 ASSERT_EQ(client_ret, -1);
4845 ASSERT_EQ(SSL_get_error(client_.get(), client_ret), SSL_ERROR_WANT_READ);
4846 }
4847
4848 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
4849 int server_ret = SSL_do_handshake(server_.get());
4850 if (server_ret != 1) {
4851 ASSERT_EQ(server_ret, -1);
4852 ASSERT_EQ(SSL_get_error(server_.get(), server_ret), SSL_ERROR_WANT_READ);
4853 }
4854
4855 if (client_ret == 1 && server_ret == 1) {
4856 break;
4857 }
4858 }
4859
4860 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
4861 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
4862 EXPECT_TRUE(transport_.SecretsMatch(ssl_encryption_application));
4863 EXPECT_FALSE(transport_.client()->has_alert());
4864 EXPECT_FALSE(transport_.server()->has_alert());
4865 EXPECT_TRUE(SSL_session_reused(client_.get()));
4866 EXPECT_TRUE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04004867}
4868
4869// Test only releasing data to QUIC one byte at a time on request, to maximize
4870// state machine pauses. Additionally, test that existing asynchronous callbacks
4871// still work.
4872TEST_F(QUICMethodTest, Async) {
4873 const SSL_QUIC_METHOD quic_method = {
4874 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05004875 AddHandshakeDataCallback,
Steven Valdezc8e0f902018-07-14 11:23:01 -04004876 FlushFlightCallback,
4877 SendAlertCallback,
4878 };
4879
4880 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
4881 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
4882 ASSERT_TRUE(CreateClientAndServer());
4883
4884 // Install an asynchronous certificate callback.
4885 bool cert_cb_ok = false;
4886 SSL_set_cert_cb(server_.get(),
4887 [](SSL *, void *arg) -> int {
4888 return *static_cast<bool *>(arg) ? 1 : -1;
4889 },
4890 &cert_cb_ok);
4891
4892 for (;;) {
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 ASSERT_TRUE(ProvideHandshakeData(client_.get(), 1));
4898 }
4899
4900 int server_ret = SSL_do_handshake(server_.get());
4901 if (server_ret != 1) {
4902 ASSERT_EQ(server_ret, -1);
4903 int ssl_err = SSL_get_error(server_.get(), server_ret);
4904 switch (ssl_err) {
4905 case SSL_ERROR_WANT_READ:
4906 ASSERT_TRUE(ProvideHandshakeData(server_.get(), 1));
4907 break;
4908 case SSL_ERROR_WANT_X509_LOOKUP:
4909 ASSERT_FALSE(cert_cb_ok);
4910 cert_cb_ok = true;
4911 break;
4912 default:
4913 FAIL() << "Unexpected SSL_get_error result: " << ssl_err;
4914 }
4915 }
4916
4917 if (client_ret == 1 && server_ret == 1) {
4918 break;
4919 }
4920 }
4921
4922 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
4923 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
4924 EXPECT_TRUE(transport_.SecretsMatch(ssl_encryption_application));
4925 EXPECT_FALSE(transport_.client()->has_alert());
4926 EXPECT_FALSE(transport_.server()->has_alert());
4927}
4928
4929// Test buffering write data until explicit flushes.
4930TEST_F(QUICMethodTest, Buffered) {
4931 struct BufferedFlight {
4932 std::vector<uint8_t> data[kNumQUICLevels];
4933 };
4934 static UnownedSSLExData<BufferedFlight> buffered_flights;
4935
David Benjamincc9d9352018-10-30 19:45:22 -05004936 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
4937 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04004938 BufferedFlight *flight = buffered_flights.Get(ssl);
4939 flight->data[level].insert(flight->data[level].end(), data, data + len);
4940 return 1;
4941 };
4942
4943 auto flush_flight = [](SSL *ssl) -> int {
4944 BufferedFlight *flight = buffered_flights.Get(ssl);
4945 for (size_t level = 0; level < kNumQUICLevels; level++) {
4946 if (!flight->data[level].empty()) {
4947 if (!TransportFromSSL(ssl)->WriteHandshakeData(
4948 static_cast<ssl_encryption_level_t>(level),
4949 flight->data[level])) {
4950 return 0;
4951 }
4952 flight->data[level].clear();
4953 }
4954 }
4955 return 1;
4956 };
4957
4958 const SSL_QUIC_METHOD quic_method = {
4959 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05004960 add_handshake_data,
Steven Valdezc8e0f902018-07-14 11:23:01 -04004961 flush_flight,
4962 SendAlertCallback,
4963 };
4964
4965 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
4966 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
4967 ASSERT_TRUE(CreateClientAndServer());
4968
4969 BufferedFlight client_flight, server_flight;
4970 buffered_flights.Set(client_.get(), &client_flight);
4971 buffered_flights.Set(server_.get(), &server_flight);
4972
4973 for (;;) {
4974 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
4975 int client_ret = SSL_do_handshake(client_.get());
4976 if (client_ret != 1) {
4977 ASSERT_EQ(client_ret, -1);
4978 ASSERT_EQ(SSL_get_error(client_.get(), client_ret), SSL_ERROR_WANT_READ);
4979 }
4980
4981 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
4982 int server_ret = SSL_do_handshake(server_.get());
4983 if (server_ret != 1) {
4984 ASSERT_EQ(server_ret, -1);
4985 ASSERT_EQ(SSL_get_error(server_.get(), server_ret), SSL_ERROR_WANT_READ);
4986 }
4987
4988 if (client_ret == 1 && server_ret == 1) {
4989 break;
4990 }
4991 }
4992
4993 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
4994 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
4995 EXPECT_TRUE(transport_.SecretsMatch(ssl_encryption_application));
4996 EXPECT_FALSE(transport_.client()->has_alert());
4997 EXPECT_FALSE(transport_.server()->has_alert());
4998}
4999
5000// Test that excess data at one level is rejected. That is, if a single
5001// |SSL_provide_quic_data| call included both ServerHello and
5002// EncryptedExtensions in a single chunk, BoringSSL notices and rejects this on
5003// key change.
5004TEST_F(QUICMethodTest, ExcessProvidedData) {
David Benjamincc9d9352018-10-30 19:45:22 -05005005 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
5006 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005007 // Switch everything to the initial level.
5008 return TransportFromSSL(ssl)->WriteHandshakeData(ssl_encryption_initial,
5009 MakeConstSpan(data, len));
5010 };
5011
5012 const SSL_QUIC_METHOD quic_method = {
5013 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05005014 add_handshake_data,
Steven Valdezc8e0f902018-07-14 11:23:01 -04005015 FlushFlightCallback,
5016 SendAlertCallback,
5017 };
5018
5019 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5020 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5021 ASSERT_TRUE(CreateClientAndServer());
5022
5023 // Send the ClientHello and ServerHello through Finished.
5024 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5025 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
5026 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5027 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
5028 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
5029
5030 // The client is still waiting for the ServerHello at initial
5031 // encryption.
5032 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
5033
David Benjamincc9d9352018-10-30 19:45:22 -05005034 // |add_handshake_data| incorrectly wrote everything at the initial level, so
5035 // this queues up ServerHello through Finished in one chunk.
Steven Valdezc8e0f902018-07-14 11:23:01 -04005036 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5037
5038 // The client reads ServerHello successfully, but then rejects the buffered
5039 // EncryptedExtensions on key change.
5040 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5041 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_SSL);
5042 uint32_t err = ERR_get_error();
5043 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
5044 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_BUFFERED_MESSAGES_ON_CIPHER_CHANGE);
5045
5046 // The client sends an alert in response to this.
5047 ASSERT_TRUE(transport_.client()->has_alert());
5048 EXPECT_EQ(transport_.client()->alert_level(), ssl_encryption_initial);
5049 EXPECT_EQ(transport_.client()->alert(), SSL_AD_UNEXPECTED_MESSAGE);
5050
5051 // Sanity-check client did get far enough to process the ServerHello and
5052 // install keys.
5053 EXPECT_TRUE(transport_.client()->HasSecrets(ssl_encryption_handshake));
5054}
5055
5056// Test that |SSL_provide_quic_data| will reject data at the wrong level.
5057TEST_F(QUICMethodTest, ProvideWrongLevel) {
5058 const SSL_QUIC_METHOD quic_method = {
5059 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05005060 AddHandshakeDataCallback,
Steven Valdezc8e0f902018-07-14 11:23:01 -04005061 FlushFlightCallback,
5062 SendAlertCallback,
5063 };
5064
5065 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5066 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5067 ASSERT_TRUE(CreateClientAndServer());
5068
5069 // Send the ClientHello and ServerHello through Finished.
5070 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5071 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
5072 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5073 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
5074 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
5075
5076 // The client is still waiting for the ServerHello at initial
5077 // encryption.
5078 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
5079
5080 // Data cannot be provided at the next level.
5081 std::vector<uint8_t> data;
5082 ASSERT_TRUE(
5083 transport_.client()->ReadHandshakeData(&data, ssl_encryption_initial));
5084 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_handshake,
5085 data.data(), data.size()));
5086 ERR_clear_error();
5087
5088 // Progress to EncryptedExtensions.
5089 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
5090 data.data(), data.size()));
5091 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5092 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
5093 ASSERT_EQ(ssl_encryption_handshake, SSL_quic_read_level(client_.get()));
5094
5095 // Data cannot be provided at the previous level.
5096 ASSERT_TRUE(
5097 transport_.client()->ReadHandshakeData(&data, ssl_encryption_handshake));
5098 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
5099 data.data(), data.size()));
5100}
5101
5102TEST_F(QUICMethodTest, TooMuchData) {
5103 const SSL_QUIC_METHOD quic_method = {
5104 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05005105 AddHandshakeDataCallback,
Steven Valdezc8e0f902018-07-14 11:23:01 -04005106 FlushFlightCallback,
5107 SendAlertCallback,
5108 };
5109
5110 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5111 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5112 ASSERT_TRUE(CreateClientAndServer());
5113
5114 size_t limit =
5115 SSL_quic_max_handshake_flight_len(client_.get(), ssl_encryption_initial);
5116 uint8_t b = 0;
5117 for (size_t i = 0; i < limit; i++) {
5118 ASSERT_TRUE(
5119 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
5120 }
5121
5122 EXPECT_FALSE(
5123 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
5124}
5125
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005126// Provide invalid post-handshake data.
5127TEST_F(QUICMethodTest, BadPostHandshake) {
5128 const SSL_QUIC_METHOD quic_method = {
5129 SetEncryptionSecretsCallback,
5130 AddHandshakeDataCallback,
5131 FlushFlightCallback,
5132 SendAlertCallback,
5133 };
5134
5135 g_last_session = nullptr;
5136
5137 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5138 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
5139 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5140 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5141 ASSERT_TRUE(CreateClientAndServer());
5142
5143 for (;;) {
5144 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5145 int client_ret = SSL_do_handshake(client_.get());
5146 if (client_ret != 1) {
5147 ASSERT_EQ(client_ret, -1);
5148 ASSERT_EQ(SSL_get_error(client_.get(), client_ret), SSL_ERROR_WANT_READ);
5149 }
5150
5151 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5152 int server_ret = SSL_do_handshake(server_.get());
5153 if (server_ret != 1) {
5154 ASSERT_EQ(server_ret, -1);
5155 ASSERT_EQ(SSL_get_error(server_.get(), server_ret), SSL_ERROR_WANT_READ);
5156 }
5157
5158 if (client_ret == 1 && server_ret == 1) {
5159 break;
5160 }
5161 }
5162
5163 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
5164 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
5165 EXPECT_TRUE(transport_.SecretsMatch(ssl_encryption_application));
5166 EXPECT_FALSE(transport_.client()->has_alert());
5167 EXPECT_FALSE(transport_.server()->has_alert());
5168
5169 // Junk sent as part of post-handshake data should cause an error.
5170 uint8_t kJunk[] = {0x17, 0x0, 0x0, 0x4, 0xB, 0xE, 0xE, 0xF};
5171 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_application,
5172 kJunk, sizeof(kJunk)));
5173 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 0);
5174}
5175
David Benjamin96628432017-01-19 19:05:47 -05005176// TODO(davidben): Convert this file to GTest properly.
5177TEST(SSLTest, AllTests) {
David Benjamine11726a2017-04-23 12:14:28 -04005178 if (!TestSSL_SESSIONEncoding(kOpenSSLSession) ||
Adam Langley10f97f32016-07-12 08:09:33 -07005179 !TestSSL_SESSIONEncoding(kCustomSession) ||
5180 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
5181 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
5182 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
5183 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
Steven Valdeza833c352016-11-01 13:39:36 -04005184 // Test the padding extension at TLS 1.2.
5185 !TestPaddingExtension(TLS1_2_VERSION, TLS1_2_VERSION) ||
5186 // Test the padding extension at TLS 1.3 with a TLS 1.2 session, so there
5187 // will be no PSK binder after the padding extension.
5188 !TestPaddingExtension(TLS1_3_VERSION, TLS1_2_VERSION) ||
5189 // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
5190 // will be a PSK binder after the padding extension.
David Benjaminaaef8332018-06-29 16:45:49 -04005191 !TestPaddingExtension(TLS1_3_VERSION, TLS1_3_VERSION)) {
David Benjamin96628432017-01-19 19:05:47 -05005192 ADD_FAILURE() << "Tests failed";
David Benjaminbb0a17c2014-09-20 15:35:39 -04005193 }
David Benjamin2e521212014-07-16 14:37:51 -04005194}
Martin Kreichgauer72912d22017-08-04 12:06:43 -07005195
5196} // namespace
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -07005197BSSL_NAMESPACE_END