blob: 6f180c74e19708da5b99054bc3c112240f0bfe39 [file] [log] [blame]
David Benjamin2e521212014-07-16 14:37:51 -04001/* Copyright (c) 2014, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15#include <stdio.h>
David Benjamin751e8892014-10-19 00:59:36 -040016#include <string.h>
David Benjamin1269ddd2015-10-18 15:18:55 -040017#include <time.h>
David Benjamin2e521212014-07-16 14:37:51 -040018
David Benjamin0f653952015-10-18 14:28:01 -040019#include <algorithm>
Steven Valdezc8e0f902018-07-14 11:23:01 -040020#include <limits>
David Benjamin1d77e562015-03-22 17:22:08 -040021#include <string>
David Benjamin4f6acaf2015-11-21 03:00:50 -050022#include <utility>
David Benjamin1d77e562015-03-22 17:22:08 -040023#include <vector>
24
David Benjamin96628432017-01-19 19:05:47 -050025#include <gtest/gtest.h>
26
David Benjamin751e8892014-10-19 00:59:36 -040027#include <openssl/base64.h>
28#include <openssl/bio.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040029#include <openssl/cipher.h>
David Benjamin7a1eefd2015-10-17 23:39:22 -040030#include <openssl/crypto.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040031#include <openssl/err.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040032#include <openssl/hmac.h>
David Benjaminde942382016-02-11 12:02:01 -050033#include <openssl/pem.h>
David Benjamin25490f22016-07-14 00:22:54 -040034#include <openssl/sha.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040035#include <openssl/ssl.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040036#include <openssl/rand.h>
David Benjaminde942382016-02-11 12:02:01 -050037#include <openssl/x509.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040038
Steven Valdez87eab492016-06-27 16:34:59 -040039#include "internal.h"
Steven Valdezcb966542016-08-17 16:56:14 -040040#include "../crypto/internal.h"
Sigbjorn Vik2b23d242015-06-29 15:07:26 +020041#include "../crypto/test/test_util.h"
42
David Benjamin721e8b72016-08-03 13:13:17 -040043#if defined(OPENSSL_WINDOWS)
David Benjaminc11ea9422017-08-29 16:33:21 -040044// Windows defines struct timeval in winsock2.h.
David Benjamin721e8b72016-08-03 13:13:17 -040045OPENSSL_MSVC_PRAGMA(warning(push, 3))
46#include <winsock2.h>
47OPENSSL_MSVC_PRAGMA(warning(pop))
48#else
49#include <sys/time.h>
50#endif
51
David Benjamin5b33eff2018-09-22 16:52:48 -070052#if defined(OPENSSL_THREADS)
David Benjamin6c04bd12018-07-19 18:13:09 -040053#include <thread>
54#endif
55
David Benjamin1d77e562015-03-22 17:22:08 -040056
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -070057BSSL_NAMESPACE_BEGIN
Martin Kreichgauer72912d22017-08-04 12:06:43 -070058
59namespace {
60
Martin Kreichgauer1a663262017-08-16 14:54:04 -070061#define TRACED_CALL(code) \
62 do { \
63 SCOPED_TRACE("<- called from here"); \
64 code; \
65 if (::testing::Test::HasFatalFailure()) { \
66 return; \
67 } \
68 } while (false)
69
Martin Kreichgauer72912d22017-08-04 12:06:43 -070070struct VersionParam {
71 uint16_t version;
72 enum { is_tls, is_dtls } ssl_method;
73 const char name[8];
74};
75
76static const size_t kTicketKeyLen = 48;
77
78static const VersionParam kAllVersions[] = {
Martin Kreichgauer72912d22017-08-04 12:06:43 -070079 {TLS1_VERSION, VersionParam::is_tls, "TLS1"},
80 {TLS1_1_VERSION, VersionParam::is_tls, "TLS1_1"},
81 {TLS1_2_VERSION, VersionParam::is_tls, "TLS1_2"},
Martin Kreichgauer72912d22017-08-04 12:06:43 -070082 {TLS1_3_VERSION, VersionParam::is_tls, "TLS1_3"},
Martin Kreichgauer72912d22017-08-04 12:06:43 -070083 {DTLS1_VERSION, VersionParam::is_dtls, "DTLS1"},
84 {DTLS1_2_VERSION, VersionParam::is_dtls, "DTLS1_2"},
85};
86
David Benjamin1d77e562015-03-22 17:22:08 -040087struct ExpectedCipher {
88 unsigned long id;
David Benjaminbb0a17c2014-09-20 15:35:39 -040089 int in_group_flag;
David Benjamin1d77e562015-03-22 17:22:08 -040090};
David Benjaminbb0a17c2014-09-20 15:35:39 -040091
David Benjamin1d77e562015-03-22 17:22:08 -040092struct CipherTest {
93 // The rule string to apply.
David Benjaminbb0a17c2014-09-20 15:35:39 -040094 const char *rule;
David Benjaminfb974e62015-12-16 19:34:22 -050095 // The list of expected ciphers, in order.
96 std::vector<ExpectedCipher> expected;
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -080097 // True if this cipher list should fail in strict mode.
98 bool strict_fail;
David Benjamin1d77e562015-03-22 17:22:08 -040099};
David Benjaminbb0a17c2014-09-20 15:35:39 -0400100
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100101struct CurveTest {
102 // The rule string to apply.
103 const char *rule;
104 // The list of expected curves, in order.
105 std::vector<uint16_t> expected;
106};
107
Steven Valdezc8e0f902018-07-14 11:23:01 -0400108template <typename T>
109class UnownedSSLExData {
110 public:
111 UnownedSSLExData() {
112 index_ = SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
113 }
114
115 T *Get(const SSL *ssl) {
116 return index_ < 0 ? nullptr
117 : static_cast<T *>(SSL_get_ex_data(ssl, index_));
118 }
119
120 bool Set(SSL *ssl, T *t) {
121 return index_ >= 0 && SSL_set_ex_data(ssl, index_, t);
122 }
123
124 private:
125 int index_;
126};
127
David Benjaminfb974e62015-12-16 19:34:22 -0500128static const CipherTest kCipherTests[] = {
129 // Selecting individual ciphers should work.
130 {
131 "ECDHE-ECDSA-CHACHA20-POLY1305:"
132 "ECDHE-RSA-CHACHA20-POLY1305:"
133 "ECDHE-ECDSA-AES128-GCM-SHA256:"
134 "ECDHE-RSA-AES128-GCM-SHA256",
135 {
136 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500137 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500138 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
139 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
140 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800141 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500142 },
143 // + reorders selected ciphers to the end, keeping their relative order.
144 {
145 "ECDHE-ECDSA-CHACHA20-POLY1305:"
146 "ECDHE-RSA-CHACHA20-POLY1305:"
147 "ECDHE-ECDSA-AES128-GCM-SHA256:"
148 "ECDHE-RSA-AES128-GCM-SHA256:"
149 "+aRSA",
150 {
151 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500152 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
153 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500154 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
155 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800156 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500157 },
158 // ! banishes ciphers from future selections.
159 {
160 "!aRSA:"
161 "ECDHE-ECDSA-CHACHA20-POLY1305:"
162 "ECDHE-RSA-CHACHA20-POLY1305:"
163 "ECDHE-ECDSA-AES128-GCM-SHA256:"
164 "ECDHE-RSA-AES128-GCM-SHA256",
165 {
166 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500167 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
168 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800169 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500170 },
171 // Multiple masks can be ANDed in a single rule.
172 {
173 "kRSA+AESGCM+AES128",
174 {
175 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
176 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800177 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500178 },
179 // - removes selected ciphers, but preserves their order for future
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700180 // selections. Select AES_128_GCM, but order the key exchanges RSA,
David Benjaminfb974e62015-12-16 19:34:22 -0500181 // ECDHE_RSA.
182 {
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700183 "ALL:-kECDHE:"
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700184 "-kRSA:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500185 "AESGCM+AES128+aRSA",
186 {
187 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500188 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
189 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800190 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500191 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800192 // Unknown selectors are no-ops, except in strict mode.
David Benjaminfb974e62015-12-16 19:34:22 -0500193 {
194 "ECDHE-ECDSA-CHACHA20-POLY1305:"
195 "ECDHE-RSA-CHACHA20-POLY1305:"
196 "ECDHE-ECDSA-AES128-GCM-SHA256:"
197 "ECDHE-RSA-AES128-GCM-SHA256:"
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800198 "BOGUS1",
David Benjaminfb974e62015-12-16 19:34:22 -0500199 {
200 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500201 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500202 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
203 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
204 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800205 true,
206 },
207 // Unknown selectors are no-ops, except in strict mode.
208 {
209 "ECDHE-ECDSA-CHACHA20-POLY1305:"
210 "ECDHE-RSA-CHACHA20-POLY1305:"
211 "ECDHE-ECDSA-AES128-GCM-SHA256:"
212 "ECDHE-RSA-AES128-GCM-SHA256:"
213 "-BOGUS2:+BOGUS3:!BOGUS4",
214 {
215 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
216 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
217 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
218 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
219 },
220 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500221 },
222 // Square brackets specify equi-preference groups.
223 {
224 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
225 "[ECDHE-RSA-CHACHA20-POLY1305]:"
226 "ECDHE-RSA-AES128-GCM-SHA256",
227 {
228 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
David Benjaminfb974e62015-12-16 19:34:22 -0500229 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley2e839242017-01-19 15:12:44 -0800230 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500231 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
232 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800233 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500234 },
David Benjamin6fff3862017-06-21 21:07:04 -0400235 // Standard names may be used instead of OpenSSL names.
236 {
237 "[TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256|"
David Benjaminbf5f1922017-07-01 11:13:53 -0400238 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256]:"
David Benjamin6fff3862017-06-21 21:07:04 -0400239 "[TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256]:"
240 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
241 {
242 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
243 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
244 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
245 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
246 },
247 false,
248 },
David Benjaminfb974e62015-12-16 19:34:22 -0500249 // @STRENGTH performs a stable strength-sort of the selected ciphers and
250 // only the selected ciphers.
251 {
252 // To simplify things, banish all but {ECDHE_RSA,RSA} x
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700253 // {CHACHA20,AES_256_CBC,AES_128_CBC} x SHA1.
David Benjamin6e678ee2018-04-16 19:54:42 -0400254 "!AESGCM:!3DES:"
David Benjaminfb974e62015-12-16 19:34:22 -0500255 // Order some ciphers backwards by strength.
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700256 "ALL:-CHACHA20:-AES256:-AES128:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500257 // Select ECDHE ones and sort them by strength. Ties should resolve
258 // based on the order above.
259 "kECDHE:@STRENGTH:-ALL:"
260 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
261 // by strength. Then RSA, backwards by strength.
262 "aRSA",
263 {
264 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
265 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500266 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500267 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
268 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
269 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800270 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500271 },
David Benjaminbf5f1922017-07-01 11:13:53 -0400272 // Additional masks after @STRENGTH get silently discarded.
273 //
274 // TODO(davidben): Make this an error. If not silently discarded, they get
275 // interpreted as + opcodes which are very different.
276 {
277 "ECDHE-RSA-AES128-GCM-SHA256:"
278 "ECDHE-RSA-AES256-GCM-SHA384:"
279 "@STRENGTH+AES256",
280 {
281 {TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
282 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
283 },
284 false,
285 },
286 {
287 "ECDHE-RSA-AES128-GCM-SHA256:"
288 "ECDHE-RSA-AES256-GCM-SHA384:"
289 "@STRENGTH+AES256:"
290 "ECDHE-RSA-CHACHA20-POLY1305",
291 {
292 {TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
293 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
294 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
295 },
296 false,
297 },
David Benjaminfb974e62015-12-16 19:34:22 -0500298 // Exact ciphers may not be used in multi-part rules; they are treated
299 // as unknown aliases.
300 {
301 "ECDHE-ECDSA-AES128-GCM-SHA256:"
302 "ECDHE-RSA-AES128-GCM-SHA256:"
303 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
304 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
305 {
306 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
307 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
308 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800309 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500310 },
311 // SSLv3 matches everything that existed before TLS 1.2.
312 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400313 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!SSLv3",
David Benjaminfb974e62015-12-16 19:34:22 -0500314 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400315 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500316 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800317 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500318 },
319 // TLSv1.2 matches everything added in TLS 1.2.
320 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400321 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!TLSv1.2",
David Benjaminfb974e62015-12-16 19:34:22 -0500322 {
323 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
324 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800325 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500326 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800327 // The two directives have no intersection. But each component is valid, so
328 // even in strict mode it is accepted.
David Benjaminfb974e62015-12-16 19:34:22 -0500329 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400330 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!TLSv1.2+SSLv3",
David Benjaminfb974e62015-12-16 19:34:22 -0500331 {
332 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400333 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500334 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800335 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500336 },
Adam Langley22df6912017-07-25 12:27:37 -0700337 // Spaces, semi-colons and commas are separators.
338 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400339 "AES128-SHA: ECDHE-RSA-AES128-GCM-SHA256 AES256-SHA ,ECDHE-ECDSA-AES128-GCM-SHA256 ; AES128-GCM-SHA256",
Adam Langley22df6912017-07-25 12:27:37 -0700340 {
341 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400342 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley22df6912017-07-25 12:27:37 -0700343 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400344 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley22df6912017-07-25 12:27:37 -0700345 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
346 },
347 // …but not in strict mode.
348 true,
349 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400350};
351
352static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400353 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400354 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
355 "RSA]",
356 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400357 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400358 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400359 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400360 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400361 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400362 "",
363 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400364 // COMPLEMENTOFDEFAULT is empty.
365 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400366 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400367 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400368 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400369 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
370 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
371 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
372 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
Adam Langleyf99f2442016-10-02 09:53:38 -0700373 // Opcode supplied, but missing selector.
374 "+",
Adam Langley22df6912017-07-25 12:27:37 -0700375 // Spaces are forbidden in equal-preference groups.
376 "[AES128-SHA | AES128-SHA256]",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400377};
378
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700379static const char *kMustNotIncludeNull[] = {
380 "ALL",
381 "DEFAULT",
David Benjamind6e9eec2015-11-18 09:48:55 -0500382 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700383 "FIPS",
384 "SHA",
385 "SHA1",
386 "RSA",
387 "SSLv3",
388 "TLSv1",
389 "TLSv1.2",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700390};
391
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100392static const CurveTest kCurveTests[] = {
393 {
394 "P-256",
395 { SSL_CURVE_SECP256R1 },
396 },
397 {
Adam Langley7b935932018-11-12 13:53:42 -0800398 "P-256:CECPQ2",
399 { SSL_CURVE_SECP256R1, SSL_CURVE_CECPQ2 },
400 },
401
402 {
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100403 "P-256:P-384:P-521:X25519",
404 {
405 SSL_CURVE_SECP256R1,
406 SSL_CURVE_SECP384R1,
407 SSL_CURVE_SECP521R1,
408 SSL_CURVE_X25519,
409 },
410 },
David Benjamin6dda1662017-11-02 20:44:26 -0400411 {
412 "prime256v1:secp384r1:secp521r1:x25519",
413 {
414 SSL_CURVE_SECP256R1,
415 SSL_CURVE_SECP384R1,
416 SSL_CURVE_SECP521R1,
417 SSL_CURVE_X25519,
418 },
419 },
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100420};
421
422static const char *kBadCurvesLists[] = {
423 "",
424 ":",
425 "::",
426 "P-256::X25519",
427 "RSA:P-256",
428 "P-256:RSA",
429 "X25519:P-256:",
430 ":X25519:P-256",
431};
432
David Benjamin70dbf042017-08-08 18:51:37 -0400433static std::string CipherListToString(SSL_CTX *ctx) {
David Benjamin1d77e562015-03-22 17:22:08 -0400434 bool in_group = false;
David Benjamine11726a2017-04-23 12:14:28 -0400435 std::string ret;
David Benjamin70dbf042017-08-08 18:51:37 -0400436 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
437 for (size_t i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
438 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
439 if (!in_group && SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400440 ret += "\t[\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400441 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400442 }
David Benjamine11726a2017-04-23 12:14:28 -0400443 ret += "\t";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400444 if (in_group) {
David Benjamine11726a2017-04-23 12:14:28 -0400445 ret += " ";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400446 }
David Benjamine11726a2017-04-23 12:14:28 -0400447 ret += SSL_CIPHER_get_name(cipher);
448 ret += "\n";
David Benjamin70dbf042017-08-08 18:51:37 -0400449 if (in_group && !SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400450 ret += "\t]\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400451 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400452 }
453 }
David Benjamine11726a2017-04-23 12:14:28 -0400454 return ret;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400455}
456
David Benjamin70dbf042017-08-08 18:51:37 -0400457static bool CipherListsEqual(SSL_CTX *ctx,
David Benjamine11726a2017-04-23 12:14:28 -0400458 const std::vector<ExpectedCipher> &expected) {
David Benjamin70dbf042017-08-08 18:51:37 -0400459 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
460 if (sk_SSL_CIPHER_num(ciphers) != expected.size()) {
David Benjamin1d77e562015-03-22 17:22:08 -0400461 return false;
David Benjamin65226252015-02-05 16:49:47 -0500462 }
463
David Benjamine11726a2017-04-23 12:14:28 -0400464 for (size_t i = 0; i < expected.size(); i++) {
David Benjamin70dbf042017-08-08 18:51:37 -0400465 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
David Benjamine11726a2017-04-23 12:14:28 -0400466 if (expected[i].id != SSL_CIPHER_get_id(cipher) ||
David Benjamin70dbf042017-08-08 18:51:37 -0400467 expected[i].in_group_flag != !!SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400468 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400469 }
470 }
471
David Benjamin1d77e562015-03-22 17:22:08 -0400472 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400473}
474
David Benjamine11726a2017-04-23 12:14:28 -0400475TEST(SSLTest, CipherRules) {
476 for (const CipherTest &t : kCipherTests) {
477 SCOPED_TRACE(t.rule);
478 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
479 ASSERT_TRUE(ctx);
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700480
David Benjamine11726a2017-04-23 12:14:28 -0400481 // Test lax mode.
482 ASSERT_TRUE(SSL_CTX_set_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400483 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400484 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400485 << CipherListToString(ctx.get());
David Benjamine11726a2017-04-23 12:14:28 -0400486
487 // Test strict mode.
488 if (t.strict_fail) {
489 EXPECT_FALSE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
490 } else {
491 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400492 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400493 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400494 << CipherListToString(ctx.get());
David Benjaminbb0a17c2014-09-20 15:35:39 -0400495 }
496 }
497
David Benjaminfb974e62015-12-16 19:34:22 -0500498 for (const char *rule : kBadRules) {
David Benjamine11726a2017-04-23 12:14:28 -0400499 SCOPED_TRACE(rule);
500 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
501 ASSERT_TRUE(ctx);
502
503 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), rule));
David Benjaminbb0a17c2014-09-20 15:35:39 -0400504 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400505 }
506
David Benjaminfb974e62015-12-16 19:34:22 -0500507 for (const char *rule : kMustNotIncludeNull) {
David Benjamine11726a2017-04-23 12:14:28 -0400508 SCOPED_TRACE(rule);
509 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
510 ASSERT_TRUE(ctx);
511
512 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400513 for (const SSL_CIPHER *cipher : SSL_CTX_get_ciphers(ctx.get())) {
David Benjamine3bb51c2017-08-22 23:16:02 -0700514 EXPECT_NE(NID_undef, SSL_CIPHER_get_cipher_nid(cipher));
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700515 }
516 }
David Benjaminbb0a17c2014-09-20 15:35:39 -0400517}
David Benjamin2e521212014-07-16 14:37:51 -0400518
David Benjamine11726a2017-04-23 12:14:28 -0400519TEST(SSLTest, CurveRules) {
520 for (const CurveTest &t : kCurveTests) {
521 SCOPED_TRACE(t.rule);
522 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
523 ASSERT_TRUE(ctx);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100524
David Benjamine11726a2017-04-23 12:14:28 -0400525 ASSERT_TRUE(SSL_CTX_set1_curves_list(ctx.get(), t.rule));
David Benjamin0ce090a2018-07-02 20:24:40 -0400526 ASSERT_EQ(t.expected.size(), ctx->supported_group_list.size());
David Benjamine11726a2017-04-23 12:14:28 -0400527 for (size_t i = 0; i < t.expected.size(); i++) {
528 EXPECT_EQ(t.expected[i], ctx->supported_group_list[i]);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100529 }
530 }
531
532 for (const char *rule : kBadCurvesLists) {
David Benjamine11726a2017-04-23 12:14:28 -0400533 SCOPED_TRACE(rule);
534 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
535 ASSERT_TRUE(ctx);
536
537 EXPECT_FALSE(SSL_CTX_set1_curves_list(ctx.get(), rule));
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100538 ERR_clear_error();
539 }
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100540}
541
Adam Langley364f7a62016-12-12 10:51:00 -0800542// kOpenSSLSession is a serialized SSL_SESSION.
Adam Langley10f97f32016-07-12 08:09:33 -0700543static const char kOpenSSLSession[] =
Adam Langley364f7a62016-12-12 10:51:00 -0800544 "MIIFqgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700545 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
546 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
547 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
548 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
549 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
550 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
551 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
552 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
553 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
554 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
555 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
556 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
557 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
558 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
559 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
560 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
561 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
562 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
563 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
564 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
565 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
566 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
567 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
568 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
569 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
570 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
571 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
572 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
573 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
Adam Langley364f7a62016-12-12 10:51:00 -0800574 "i4gv7Y5oliyntgMBAQA=";
Adam Langley10f97f32016-07-12 08:09:33 -0700575
576// kCustomSession is a custom serialized SSL_SESSION generated by
577// filling in missing fields from |kOpenSSLSession|. This includes
578// providing |peer_sha256|, so |peer| is not serialized.
579static const char kCustomSession[] =
David Benjamina8614602017-09-06 15:40:19 -0400580 "MIIBZAIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700581 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
David Benjamina8614602017-09-06 15:40:19 -0400582 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUqAcEBXdvcmxkqQUCAwGJwKqBpwSB"
583 "pBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38"
584 "VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd"
585 "3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hg"
586 "b+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYGBgYGBgYGBgYGBgYGBgYGBgYG"
587 "BgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
Adam Langley10f97f32016-07-12 08:09:33 -0700588
589// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
590static const char kBoringSSLSession[] =
591 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
592 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
593 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
594 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
595 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
596 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
597 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
598 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
599 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
600 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
601 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
602 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
603 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
604 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
605 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
606 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
607 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
608 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
609 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
610 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
611 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
612 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
613 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
614 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
615 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
616 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
617 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
618 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
619 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
620 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
621 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
622 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
623 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
624 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
625 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
626 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
627 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
628 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
629 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
630 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
631 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
632 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
633 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
634 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
635 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
636 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
637 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
638 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
639 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
640 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
641 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
642 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
643 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
644 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
645 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
646 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
647 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
648 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
649 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
650 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
651 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
652 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
653 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
654 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
655 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
656 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
657 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
658 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
659 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
660 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
661 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
662 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
663 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
664 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
665 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
666 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
667 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
668 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
669 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
670 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
671 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
672 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
673 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
674 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
675 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
676 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
677 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
678 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
679 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
680 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
681 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
682 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
683 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
684 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
685 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
686
687// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
688// the final (optional) element of |kCustomSession| with tag number 30.
689static const char kBadSessionExtraField[] =
690 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
691 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
692 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
693 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
694 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
695 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
696 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
697 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
698
699// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
700// the version of |kCustomSession| with 2.
701static const char kBadSessionVersion[] =
702 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
703 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
704 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
705 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
706 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
707 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
708 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
709 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
710
711// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
712// appended.
713static const char kBadSessionTrailingData[] =
714 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
715 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
716 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
717 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
718 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
719 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
720 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
721 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
722
David Benjamin1d77e562015-03-22 17:22:08 -0400723static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400724 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400725 if (!EVP_DecodedLength(&len, strlen(in))) {
726 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400727 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400728 }
729
David Benjamin1d77e562015-03-22 17:22:08 -0400730 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800731 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400732 strlen(in))) {
733 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400734 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400735 }
David Benjamin1d77e562015-03-22 17:22:08 -0400736 out->resize(len);
737 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400738}
739
David Benjamina486c6c2019-03-28 18:32:38 -0500740TEST(SSLTest, SessionEncoding) {
741 for (const char *input_b64 : {
742 kOpenSSLSession,
743 kCustomSession,
744 kBoringSSLSession,
745 }) {
746 SCOPED_TRACE(std::string(input_b64));
747 // Decode the input.
748 std::vector<uint8_t> input;
749 ASSERT_TRUE(DecodeBase64(&input, input_b64));
David Benjamin751e8892014-10-19 00:59:36 -0400750
David Benjamina486c6c2019-03-28 18:32:38 -0500751 // Verify the SSL_SESSION decodes.
752 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
753 ASSERT_TRUE(ssl_ctx);
754 bssl::UniquePtr<SSL_SESSION> session(
755 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
756 ASSERT_TRUE(session) << "SSL_SESSION_from_bytes failed";
757
758 // Verify the SSL_SESSION encoding round-trips.
759 size_t encoded_len;
760 bssl::UniquePtr<uint8_t> encoded;
761 uint8_t *encoded_raw;
762 ASSERT_TRUE(SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len))
763 << "SSL_SESSION_to_bytes failed";
764 encoded.reset(encoded_raw);
765 EXPECT_EQ(Bytes(encoded.get(), encoded_len), Bytes(input))
766 << "SSL_SESSION_to_bytes did not round-trip";
767
768 // Verify the SSL_SESSION also decodes with the legacy API.
769 const uint8_t *cptr = input.data();
770 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
771 ASSERT_TRUE(session) << "d2i_SSL_SESSION failed";
772 EXPECT_EQ(cptr, input.data() + input.size());
773
774 // Verify the SSL_SESSION encoding round-trips via the legacy API.
775 int len = i2d_SSL_SESSION(session.get(), NULL);
776 ASSERT_GT(len, 0) << "i2d_SSL_SESSION failed";
777 ASSERT_EQ(static_cast<size_t>(len), input.size())
778 << "i2d_SSL_SESSION(NULL) returned invalid length";
779
780 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
781 ASSERT_TRUE(encoded);
782
783 uint8_t *ptr = encoded.get();
784 len = i2d_SSL_SESSION(session.get(), &ptr);
785 ASSERT_GT(len, 0) << "i2d_SSL_SESSION failed";
786 ASSERT_EQ(static_cast<size_t>(len), input.size())
787 << "i2d_SSL_SESSION(NULL) returned invalid length";
788 ASSERT_EQ(ptr, encoded.get() + input.size())
789 << "i2d_SSL_SESSION did not advance ptr correctly";
790 EXPECT_EQ(Bytes(encoded.get(), encoded_len), Bytes(input))
791 << "SSL_SESSION_to_bytes did not round-trip";
David Benjamin751e8892014-10-19 00:59:36 -0400792 }
793
David Benjamina486c6c2019-03-28 18:32:38 -0500794 for (const char *input_b64 : {
795 kBadSessionExtraField,
796 kBadSessionVersion,
797 kBadSessionTrailingData,
798 }) {
799 SCOPED_TRACE(std::string(input_b64));
800 std::vector<uint8_t> input;
801 ASSERT_TRUE(DecodeBase64(&input, input_b64));
David Benjamin751e8892014-10-19 00:59:36 -0400802
David Benjamina486c6c2019-03-28 18:32:38 -0500803 // Verify that the SSL_SESSION fails to decode.
804 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
805 ASSERT_TRUE(ssl_ctx);
806 bssl::UniquePtr<SSL_SESSION> session(
807 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
808 EXPECT_FALSE(session) << "SSL_SESSION_from_bytes unexpectedly succeeded";
809 ERR_clear_error();
David Benjamin3cac4502014-10-21 01:46:30 -0400810 }
David Benjaminf297e022015-05-28 19:55:29 -0400811}
812
David Benjamin321fcdc2017-04-24 11:42:42 -0400813static void ExpectDefaultVersion(uint16_t min_version, uint16_t max_version,
814 const SSL_METHOD *(*method)(void)) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700815 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
David Benjamin321fcdc2017-04-24 11:42:42 -0400816 ASSERT_TRUE(ctx);
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -0700817 EXPECT_EQ(min_version, SSL_CTX_get_min_proto_version(ctx.get()));
818 EXPECT_EQ(max_version, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjamin321fcdc2017-04-24 11:42:42 -0400819}
820
821TEST(SSLTest, DefaultVersion) {
822 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
823 ExpectDefaultVersion(TLS1_VERSION, TLS1_2_VERSION, &TLS_method);
824 ExpectDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method);
825 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method);
826 ExpectDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method);
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -0700827 ExpectDefaultVersion(DTLS1_VERSION, DTLS1_2_VERSION, &DTLS_method);
828 ExpectDefaultVersion(DTLS1_VERSION, DTLS1_VERSION, &DTLSv1_method);
829 ExpectDefaultVersion(DTLS1_2_VERSION, DTLS1_2_VERSION, &DTLSv1_2_method);
David Benjamin82c9e902014-12-12 15:55:27 -0500830}
831
David Benjamin348f0d82017-08-10 16:06:27 -0400832TEST(SSLTest, CipherProperties) {
David Benjamin6fff3862017-06-21 21:07:04 -0400833 static const struct {
834 int id;
835 const char *standard_name;
David Benjamin348f0d82017-08-10 16:06:27 -0400836 int cipher_nid;
837 int digest_nid;
838 int kx_nid;
839 int auth_nid;
David Benjaminb1b76ae2017-09-21 17:03:34 -0400840 int prf_nid;
David Benjamin6fff3862017-06-21 21:07:04 -0400841 } kTests[] = {
David Benjamin348f0d82017-08-10 16:06:27 -0400842 {
843 SSL3_CK_RSA_DES_192_CBC3_SHA,
844 "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
845 NID_des_ede3_cbc,
846 NID_sha1,
847 NID_kx_rsa,
848 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400849 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400850 },
851 {
852 TLS1_CK_RSA_WITH_AES_128_SHA,
853 "TLS_RSA_WITH_AES_128_CBC_SHA",
854 NID_aes_128_cbc,
855 NID_sha1,
856 NID_kx_rsa,
857 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400858 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400859 },
860 {
861 TLS1_CK_PSK_WITH_AES_256_CBC_SHA,
862 "TLS_PSK_WITH_AES_256_CBC_SHA",
863 NID_aes_256_cbc,
864 NID_sha1,
865 NID_kx_psk,
866 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400867 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400868 },
869 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400870 TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA,
871 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
David Benjamin348f0d82017-08-10 16:06:27 -0400872 NID_aes_128_cbc,
David Benjamin6e678ee2018-04-16 19:54:42 -0400873 NID_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400874 NID_kx_ecdhe,
875 NID_auth_rsa,
David Benjamin6e678ee2018-04-16 19:54:42 -0400876 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400877 },
878 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400879 TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA,
880 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
David Benjamin348f0d82017-08-10 16:06:27 -0400881 NID_aes_256_cbc,
David Benjamin6e678ee2018-04-16 19:54:42 -0400882 NID_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400883 NID_kx_ecdhe,
884 NID_auth_rsa,
David Benjamin6e678ee2018-04-16 19:54:42 -0400885 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400886 },
887 {
888 TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
889 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
890 NID_aes_128_gcm,
891 NID_undef,
892 NID_kx_ecdhe,
893 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400894 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400895 },
896 {
897 TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
898 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
899 NID_aes_128_gcm,
900 NID_undef,
901 NID_kx_ecdhe,
902 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400903 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400904 },
905 {
906 TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
907 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
908 NID_aes_256_gcm,
909 NID_undef,
910 NID_kx_ecdhe,
911 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400912 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -0400913 },
914 {
915 TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
916 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
917 NID_aes_128_cbc,
918 NID_sha1,
919 NID_kx_ecdhe,
920 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400921 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400922 },
923 {
924 TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
925 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
926 NID_chacha20_poly1305,
927 NID_undef,
928 NID_kx_ecdhe,
929 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400930 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400931 },
932 {
933 TLS1_CK_AES_256_GCM_SHA384,
934 "TLS_AES_256_GCM_SHA384",
935 NID_aes_256_gcm,
936 NID_undef,
937 NID_kx_any,
938 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400939 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -0400940 },
941 {
942 TLS1_CK_AES_128_GCM_SHA256,
943 "TLS_AES_128_GCM_SHA256",
944 NID_aes_128_gcm,
945 NID_undef,
946 NID_kx_any,
947 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400948 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400949 },
950 {
951 TLS1_CK_CHACHA20_POLY1305_SHA256,
952 "TLS_CHACHA20_POLY1305_SHA256",
953 NID_chacha20_poly1305,
954 NID_undef,
955 NID_kx_any,
956 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400957 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400958 },
David Benjamin6fff3862017-06-21 21:07:04 -0400959 };
David Benjamin65226252015-02-05 16:49:47 -0500960
David Benjamin6fff3862017-06-21 21:07:04 -0400961 for (const auto &t : kTests) {
962 SCOPED_TRACE(t.standard_name);
David Benjamine11726a2017-04-23 12:14:28 -0400963
964 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(t.id & 0xffff);
965 ASSERT_TRUE(cipher);
David Benjamin6fff3862017-06-21 21:07:04 -0400966 EXPECT_STREQ(t.standard_name, SSL_CIPHER_standard_name(cipher));
967
David Benjamine11726a2017-04-23 12:14:28 -0400968 bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
969 ASSERT_TRUE(rfc_name);
David Benjamin6fff3862017-06-21 21:07:04 -0400970 EXPECT_STREQ(t.standard_name, rfc_name.get());
David Benjamin348f0d82017-08-10 16:06:27 -0400971
972 EXPECT_EQ(t.cipher_nid, SSL_CIPHER_get_cipher_nid(cipher));
973 EXPECT_EQ(t.digest_nid, SSL_CIPHER_get_digest_nid(cipher));
974 EXPECT_EQ(t.kx_nid, SSL_CIPHER_get_kx_nid(cipher));
975 EXPECT_EQ(t.auth_nid, SSL_CIPHER_get_auth_nid(cipher));
David Benjaminb1b76ae2017-09-21 17:03:34 -0400976 EXPECT_EQ(t.prf_nid, SSL_CIPHER_get_prf_nid(cipher));
David Benjamin65226252015-02-05 16:49:47 -0500977 }
David Benjamin65226252015-02-05 16:49:47 -0500978}
979
Steven Valdeza833c352016-11-01 13:39:36 -0400980// CreateSessionWithTicket returns a sample |SSL_SESSION| with the specified
981// version and ticket length or nullptr on failure.
982static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(uint16_t version,
983 size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -0400984 std::vector<uint8_t> der;
985 if (!DecodeBase64(&der, kOpenSSLSession)) {
986 return nullptr;
987 }
Adam Langley46db7af2017-02-01 15:49:37 -0800988
989 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
990 if (!ssl_ctx) {
991 return nullptr;
992 }
David Benjaminaaef8332018-06-29 16:45:49 -0400993 // Use a garbage ticket.
994 std::vector<uint8_t> ticket(ticket_len, 'a');
Steven Valdeza833c352016-11-01 13:39:36 -0400995 bssl::UniquePtr<SSL_SESSION> session(
Adam Langley46db7af2017-02-01 15:49:37 -0800996 SSL_SESSION_from_bytes(der.data(), der.size(), ssl_ctx.get()));
David Benjaminaaef8332018-06-29 16:45:49 -0400997 if (!session ||
998 !SSL_SESSION_set_protocol_version(session.get(), version) ||
999 !SSL_SESSION_set_ticket(session.get(), ticket.data(), ticket.size())) {
David Benjamin422fe082015-07-21 22:03:43 -04001000 return nullptr;
1001 }
David Benjamin1269ddd2015-10-18 15:18:55 -04001002 // Fix up the timeout.
David Benjamin9b63f292016-11-15 00:44:05 -05001003#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
David Benjaminaaef8332018-06-29 16:45:49 -04001004 SSL_SESSION_set_time(session.get(), 1234);
David Benjamin9b63f292016-11-15 00:44:05 -05001005#else
David Benjaminaaef8332018-06-29 16:45:49 -04001006 SSL_SESSION_set_time(session.get(), time(nullptr));
David Benjamin9b63f292016-11-15 00:44:05 -05001007#endif
David Benjamin422fe082015-07-21 22:03:43 -04001008 return session;
1009}
1010
David Benjaminafc64de2016-07-19 17:12:41 +02001011static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001012 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +02001013 if (!bio) {
1014 return false;
1015 }
1016 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -04001017 BIO_up_ref(bio.get());
1018 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +02001019 int ret = SSL_connect(ssl);
1020 if (ret > 0) {
1021 // SSL_connect should fail without a BIO to write to.
1022 return false;
1023 }
1024 ERR_clear_error();
1025
1026 const uint8_t *client_hello;
1027 size_t client_hello_len;
1028 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
1029 return false;
1030 }
1031 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
1032 return true;
1033}
1034
Steven Valdeza833c352016-11-01 13:39:36 -04001035// GetClientHelloLen creates a client SSL connection with the specified version
1036// and ticket length. It returns the length of the ClientHello, not including
1037// the record header, on success and zero on error.
1038static size_t GetClientHelloLen(uint16_t max_version, uint16_t session_version,
1039 size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001040 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Steven Valdeza833c352016-11-01 13:39:36 -04001041 bssl::UniquePtr<SSL_SESSION> session =
1042 CreateSessionWithTicket(session_version, ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -04001043 if (!ctx || !session) {
1044 return 0;
1045 }
Steven Valdeza833c352016-11-01 13:39:36 -04001046
1047 // Set a one-element cipher list so the baseline ClientHello is unpadded.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001048 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
Steven Valdez2c62fe92016-10-14 12:08:12 -04001049 if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -08001050 !SSL_set_strict_cipher_list(ssl.get(), "ECDHE-RSA-AES128-GCM-SHA256") ||
Steven Valdeza833c352016-11-01 13:39:36 -04001051 !SSL_set_max_proto_version(ssl.get(), max_version)) {
David Benjamin422fe082015-07-21 22:03:43 -04001052 return 0;
1053 }
Steven Valdeza833c352016-11-01 13:39:36 -04001054
David Benjaminafc64de2016-07-19 17:12:41 +02001055 std::vector<uint8_t> client_hello;
1056 if (!GetClientHello(ssl.get(), &client_hello) ||
1057 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -04001058 return 0;
1059 }
Steven Valdeza833c352016-11-01 13:39:36 -04001060
David Benjaminafc64de2016-07-19 17:12:41 +02001061 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -04001062}
1063
David Benjamina486c6c2019-03-28 18:32:38 -05001064TEST(SSLTest, Padding) {
1065 struct PaddingVersions {
1066 uint16_t max_version, session_version;
1067 };
1068 static const PaddingVersions kPaddingVersions[] = {
1069 // Test the padding extension at TLS 1.2.
1070 {TLS1_2_VERSION, TLS1_2_VERSION},
1071 // Test the padding extension at TLS 1.3 with a TLS 1.2 session, so there
1072 // will be no PSK binder after the padding extension.
1073 {TLS1_3_VERSION, TLS1_2_VERSION},
1074 // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
1075 // will be a PSK binder after the padding extension.
1076 {TLS1_3_VERSION, TLS1_3_VERSION},
David Benjamin422fe082015-07-21 22:03:43 -04001077
David Benjamina486c6c2019-03-28 18:32:38 -05001078 };
David Benjamin422fe082015-07-21 22:03:43 -04001079
David Benjamina486c6c2019-03-28 18:32:38 -05001080 struct PaddingTest {
1081 size_t input_len, padded_len;
1082 };
1083 static const PaddingTest kPaddingTests[] = {
1084 // ClientHellos of length below 0x100 do not require padding.
1085 {0xfe, 0xfe},
1086 {0xff, 0xff},
1087 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
1088 {0x100, 0x200},
1089 {0x123, 0x200},
1090 {0x1fb, 0x200},
1091 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
1092 // padding extension takes a minimum of four bytes plus one required
1093 // content
1094 // byte. (To work around yet more server bugs, we avoid empty final
1095 // extensions.)
1096 {0x1fc, 0x201},
1097 {0x1fd, 0x202},
1098 {0x1fe, 0x203},
1099 {0x1ff, 0x204},
1100 // Finally, larger ClientHellos need no padding.
1101 {0x200, 0x200},
1102 {0x201, 0x201},
1103 };
David Benjamin422fe082015-07-21 22:03:43 -04001104
David Benjamina486c6c2019-03-28 18:32:38 -05001105 for (const PaddingVersions &versions : kPaddingVersions) {
1106 SCOPED_TRACE(versions.max_version);
1107 SCOPED_TRACE(versions.session_version);
David Benjamin422fe082015-07-21 22:03:43 -04001108
David Benjamina486c6c2019-03-28 18:32:38 -05001109 // Sample a baseline length.
1110 size_t base_len =
1111 GetClientHelloLen(versions.max_version, versions.session_version, 1);
1112 ASSERT_NE(base_len, 0u) << "Baseline length could not be sampled";
1113
1114 for (const PaddingTest &test : kPaddingTests) {
1115 SCOPED_TRACE(test.input_len);
1116 ASSERT_LE(base_len, test.input_len) << "Baseline ClientHello too long";
1117
1118 size_t padded_len =
1119 GetClientHelloLen(versions.max_version, versions.session_version,
1120 1 + test.input_len - base_len);
1121 EXPECT_EQ(padded_len, test.padded_len)
1122 << "ClientHello was not padded to expected length";
David Benjamin422fe082015-07-21 22:03:43 -04001123 }
1124 }
David Benjamin422fe082015-07-21 22:03:43 -04001125}
1126
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001127static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001128 static const char kCertPEM[] =
1129 "-----BEGIN CERTIFICATE-----\n"
1130 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1131 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1132 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1133 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1134 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1135 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1136 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1137 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1138 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1139 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1140 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1141 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1142 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1143 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001144 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
David Benjamin1444c3a2016-12-20 17:23:11 -05001145 return bssl::UniquePtr<X509>(
1146 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjaminde942382016-02-11 12:02:01 -05001147}
1148
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001149static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001150 static const char kKeyPEM[] =
1151 "-----BEGIN RSA PRIVATE KEY-----\n"
1152 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1153 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1154 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1155 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1156 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1157 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1158 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1159 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1160 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1161 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1162 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1163 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1164 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1165 "-----END RSA PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001166 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1167 return bssl::UniquePtr<EVP_PKEY>(
David Benjaminde942382016-02-11 12:02:01 -05001168 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1169}
1170
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001171static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001172 static const char kCertPEM[] =
1173 "-----BEGIN CERTIFICATE-----\n"
1174 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1175 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1176 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1177 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1178 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1179 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1180 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1181 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1182 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1183 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1184 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001185 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1186 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjamin0fc37ef2016-08-17 15:29:46 -04001187}
1188
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001189static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001190 static const char kKeyPEM[] =
1191 "-----BEGIN PRIVATE KEY-----\n"
1192 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1193 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1194 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1195 "-----END PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001196 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1197 return bssl::UniquePtr<EVP_PKEY>(
David Benjamin0fc37ef2016-08-17 15:29:46 -04001198 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1199}
1200
Adam Langleyd04ca952017-02-28 11:26:51 -08001201static bssl::UniquePtr<CRYPTO_BUFFER> BufferFromPEM(const char *pem) {
1202 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1203 char *name, *header;
1204 uint8_t *data;
1205 long data_len;
1206 if (!PEM_read_bio(bio.get(), &name, &header, &data,
1207 &data_len)) {
1208 return nullptr;
1209 }
1210 OPENSSL_free(name);
1211 OPENSSL_free(header);
1212
1213 auto ret = bssl::UniquePtr<CRYPTO_BUFFER>(
1214 CRYPTO_BUFFER_new(data, data_len, nullptr));
1215 OPENSSL_free(data);
1216 return ret;
1217}
1218
1219static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestCertificateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001220 static const char kCertPEM[] =
1221 "-----BEGIN CERTIFICATE-----\n"
1222 "MIIC0jCCAbqgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQiBD\n"
1223 "QTAeFw0xNjAyMjgyMDI3MDNaFw0yNjAyMjUyMDI3MDNaMBgxFjAUBgNVBAMMDUNs\n"
1224 "aWVudCBDZXJ0IEEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRvaz8\n"
1225 "CC/cshpCafJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/\n"
1226 "kLRcH89M/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3\n"
1227 "tHb+xs2PSs8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+c\n"
1228 "IDs2rQ+lP7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1\n"
1229 "z7C8jU50Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9V\n"
1230 "iLeXANgZi+Xx9KgfAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI\n"
1231 "KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBFEVbmYl+2RtNw\n"
1232 "rDftRDF1v2QUbcN2ouSnQDHxeDQdSgasLzT3ui8iYu0Rw2WWcZ0DV5e0ztGPhWq7\n"
1233 "AO0B120aFRMOY+4+bzu9Q2FFkQqc7/fKTvTDzIJI5wrMnFvUfzzvxh3OHWMYSs/w\n"
1234 "giq33hTKeHEq6Jyk3btCny0Ycecyc3yGXH10sizUfiHlhviCkDuESk8mFDwDDzqW\n"
1235 "ZF0IipzFbEDHoIxLlm3GQxpiLoEV4k8KYJp3R5KBLFyxM6UGPz8h72mIPCJp2RuK\n"
1236 "MYgF91UDvVzvnYm6TfseM2+ewKirC00GOrZ7rEcFvtxnKSqYf4ckqfNdSU1Y+RRC\n"
1237 "1ngWZ7Ih\n"
1238 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001239 return BufferFromPEM(kCertPEM);
David Benjamin1444c3a2016-12-20 17:23:11 -05001240}
1241
Adam Langleyd04ca952017-02-28 11:26:51 -08001242static bssl::UniquePtr<X509> X509FromBuffer(
1243 bssl::UniquePtr<CRYPTO_BUFFER> buffer) {
1244 if (!buffer) {
1245 return nullptr;
1246 }
1247 const uint8_t *derp = CRYPTO_BUFFER_data(buffer.get());
1248 return bssl::UniquePtr<X509>(
1249 d2i_X509(NULL, &derp, CRYPTO_BUFFER_len(buffer.get())));
1250}
1251
1252static bssl::UniquePtr<X509> GetChainTestCertificate() {
1253 return X509FromBuffer(GetChainTestCertificateBuffer());
1254}
1255
1256static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestIntermediateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001257 static const char kCertPEM[] =
1258 "-----BEGIN CERTIFICATE-----\n"
1259 "MIICwjCCAaqgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS\n"
1260 "b290IENBMB4XDTE2MDIyODIwMjcwM1oXDTI2MDIyNTIwMjcwM1owDzENMAsGA1UE\n"
1261 "AwwEQiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALsSCYmDip2D\n"
1262 "GkjFxw7ykz26JSjELkl6ArlYjFJ3aT/SCh8qbS4gln7RH8CPBd78oFdfhIKQrwtZ\n"
1263 "3/q21ykD9BAS3qHe2YdcJfm8/kWAy5DvXk6NXU4qX334KofBAEpgdA/igEFq1P1l\n"
1264 "HAuIfZCpMRfT+i5WohVsGi8f/NgpRvVaMONLNfgw57mz1lbtFeBEISmX0kbsuJxF\n"
1265 "Qj/Bwhi5/0HAEXG8e7zN4cEx0yPRvmOATRdVb/8dW2pwOHRJq9R5M0NUkIsTSnL7\n"
1266 "6N/z8hRAHMsV3IudC5Yd7GXW1AGu9a+iKU+Q4xcZCoj0DC99tL4VKujrV1kAeqsM\n"
1267 "cz5/dKzi6+cCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
1268 "AQYwDQYJKoZIhvcNAQELBQADggEBAIIeZiEeNhWWQ8Y4D+AGDwqUUeG8NjCbKrXQ\n"
1269 "BlHg5wZ8xftFaiP1Dp/UAezmx2LNazdmuwrYB8lm3FVTyaPDTKEGIPS4wJKHgqH1\n"
1270 "QPDhqNm85ey7TEtI9oYjsNim/Rb+iGkIAMXaxt58SzxbjvP0kMr1JfJIZbic9vye\n"
1271 "NwIspMFIpP3FB8ywyu0T0hWtCQgL4J47nigCHpOu58deP88fS/Nyz/fyGVWOZ76b\n"
1272 "WhWwgM3P3X95fQ3d7oFPR/bVh0YV+Cf861INwplokXgXQ3/TCQ+HNXeAMWn3JLWv\n"
1273 "XFwk8owk9dq/kQGdndGgy3KTEW4ctPX5GNhf3LJ9Q7dLji4ReQ4=\n"
1274 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001275 return BufferFromPEM(kCertPEM);
1276}
1277
1278static bssl::UniquePtr<X509> GetChainTestIntermediate() {
1279 return X509FromBuffer(GetChainTestIntermediateBuffer());
David Benjamin1444c3a2016-12-20 17:23:11 -05001280}
1281
1282static bssl::UniquePtr<EVP_PKEY> GetChainTestKey() {
1283 static const char kKeyPEM[] =
1284 "-----BEGIN PRIVATE KEY-----\n"
1285 "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRvaz8CC/cshpC\n"
1286 "afJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/kLRcH89M\n"
1287 "/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3tHb+xs2P\n"
1288 "Ss8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+cIDs2rQ+l\n"
1289 "P7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1z7C8jU50\n"
1290 "Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9ViLeXANgZ\n"
1291 "i+Xx9KgfAgMBAAECggEBAK0VjSJzkyPaamcyTVSWjo7GdaBGcK60lk657RjR+lK0\n"
1292 "YJ7pkej4oM2hdsVZFsP8Cs4E33nXLa/0pDsRov/qrp0WQm2skwqGMC1I/bZ0WRPk\n"
1293 "wHaDrBBfESWnJDX/AGpVtlyOjPmgmK6J2usMPihQUDkKdAYrVWJePrMIxt1q6BMe\n"
1294 "iczs3qriMmtY3bUc4UyUwJ5fhDLjshHvfuIpYQyI6EXZM6dZksn9LylXJnigY6QJ\n"
1295 "HxOYO0BDwOsZ8yQ8J8afLk88i0GizEkgE1z3REtQUwgWfxr1WV/ud+T6/ZhSAgH9\n"
1296 "042mQvSFZnIUSEsmCvjhWuAunfxHKCTcAoYISWfzWpkCgYEA7gpf3HHU5Tn+CgUn\n"
1297 "1X5uGpG3DmcMgfeGgs2r2f/IIg/5Ac1dfYILiybL1tN9zbyLCJfcbFpWBc9hJL6f\n"
1298 "CPc5hUiwWFJqBJewxQkC1Ae/HakHbip+IZ+Jr0842O4BAArvixk4Lb7/N2Ct9sTE\n"
1299 "NJO6RtK9lbEZ5uK61DglHy8CS2UCgYEA4ZC1o36kPAMQBggajgnucb2yuUEelk0f\n"
1300 "AEr+GI32MGE+93xMr7rAhBoqLg4AITyIfEnOSQ5HwagnIHonBbv1LV/Gf9ursx8Z\n"
1301 "YOGbvT8zzzC+SU1bkDzdjAYnFQVGIjMtKOBJ3K07++ypwX1fr4QsQ8uKL8WSOWwt\n"
1302 "Z3Bym6XiZzMCgYADnhy+2OwHX85AkLt+PyGlPbmuelpyTzS4IDAQbBa6jcuW/2wA\n"
1303 "UE2km75VUXmD+u2R/9zVuLm99NzhFhSMqlUxdV1YukfqMfP5yp1EY6m/5aW7QuIP\n"
1304 "2MDa7TVL9rIFMiVZ09RKvbBbQxjhuzPQKL6X/PPspnhiTefQ+dl2k9xREQKBgHDS\n"
1305 "fMfGNEeAEKezrfSVqxphE9/tXms3L+ZpnCaT+yu/uEr5dTIAawKoQ6i9f/sf1/Sy\n"
1306 "xedsqR+IB+oKrzIDDWMgoJybN4pkZ8E5lzhVQIjFjKgFdWLzzqyW9z1gYfABQPlN\n"
1307 "FiS20WX0vgP1vcKAjdNrHzc9zyHBpgQzDmAj3NZZAoGBAI8vKCKdH7w3aL5CNkZQ\n"
1308 "2buIeWNA2HZazVwAGG5F2TU/LmXfRKnG6dX5bkU+AkBZh56jNZy//hfFSewJB4Kk\n"
1309 "buB7ERSdaNbO21zXt9FEA3+z0RfMd/Zv2vlIWOSB5nzl/7UKti3sribK6s9ZVLfi\n"
1310 "SxpiPQ8d/hmSGwn4ksrWUsJD\n"
1311 "-----END PRIVATE KEY-----\n";
1312 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1313 return bssl::UniquePtr<EVP_PKEY>(
1314 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1315}
1316
David Benjaminc79ae7a2017-08-29 16:09:44 -04001317// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
1318// before configuring as a server.
1319TEST(SSLTest, ClientCAList) {
1320 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1321 ASSERT_TRUE(ctx);
1322 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1323 ASSERT_TRUE(ssl);
1324
1325 bssl::UniquePtr<X509_NAME> name(X509_NAME_new());
1326 ASSERT_TRUE(name);
1327
1328 bssl::UniquePtr<X509_NAME> name_dup(X509_NAME_dup(name.get()));
1329 ASSERT_TRUE(name_dup);
1330
1331 bssl::UniquePtr<STACK_OF(X509_NAME)> stack(sk_X509_NAME_new_null());
1332 ASSERT_TRUE(stack);
David Benjamin2908dd12018-06-29 17:46:42 -04001333 ASSERT_TRUE(PushToStack(stack.get(), std::move(name_dup)));
David Benjaminc79ae7a2017-08-29 16:09:44 -04001334
1335 // |SSL_set_client_CA_list| takes ownership.
1336 SSL_set_client_CA_list(ssl.get(), stack.release());
1337
1338 STACK_OF(X509_NAME) *result = SSL_get_client_CA_list(ssl.get());
1339 ASSERT_TRUE(result);
1340 ASSERT_EQ(1u, sk_X509_NAME_num(result));
1341 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(result, 0), name.get()));
1342}
1343
1344TEST(SSLTest, AddClientCA) {
1345 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1346 ASSERT_TRUE(ctx);
1347 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1348 ASSERT_TRUE(ssl);
1349
1350 bssl::UniquePtr<X509> cert1 = GetTestCertificate();
1351 bssl::UniquePtr<X509> cert2 = GetChainTestCertificate();
1352 ASSERT_TRUE(cert1 && cert2);
1353 X509_NAME *name1 = X509_get_subject_name(cert1.get());
1354 X509_NAME *name2 = X509_get_subject_name(cert2.get());
1355
1356 EXPECT_EQ(0u, sk_X509_NAME_num(SSL_get_client_CA_list(ssl.get())));
1357
1358 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1359 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert2.get()));
1360
1361 STACK_OF(X509_NAME) *list = SSL_get_client_CA_list(ssl.get());
1362 ASSERT_EQ(2u, sk_X509_NAME_num(list));
1363 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1364 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1365
1366 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1367
1368 list = SSL_get_client_CA_list(ssl.get());
1369 ASSERT_EQ(3u, sk_X509_NAME_num(list));
1370 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1371 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1372 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 2), name1));
1373}
1374
1375static void AppendSession(SSL_SESSION *session, void *arg) {
1376 std::vector<SSL_SESSION*> *out =
1377 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
1378 out->push_back(session);
1379}
1380
1381// CacheEquals returns true if |ctx|'s session cache consists of |expected|, in
1382// order.
1383static bool CacheEquals(SSL_CTX *ctx,
1384 const std::vector<SSL_SESSION*> &expected) {
1385 // Check the linked list.
1386 SSL_SESSION *ptr = ctx->session_cache_head;
1387 for (SSL_SESSION *session : expected) {
1388 if (ptr != session) {
1389 return false;
1390 }
1391 // TODO(davidben): This is an absurd way to denote the end of the list.
1392 if (ptr->next ==
1393 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
1394 ptr = nullptr;
1395 } else {
1396 ptr = ptr->next;
1397 }
1398 }
1399 if (ptr != nullptr) {
1400 return false;
1401 }
1402
1403 // Check the hash table.
1404 std::vector<SSL_SESSION*> actual, expected_copy;
David Benjamin9eaa3bd2017-09-27 17:03:54 -04001405 lh_SSL_SESSION_doall_arg(ctx->sessions, AppendSession, &actual);
David Benjaminc79ae7a2017-08-29 16:09:44 -04001406 expected_copy = expected;
1407
1408 std::sort(actual.begin(), actual.end());
1409 std::sort(expected_copy.begin(), expected_copy.end());
1410
1411 return actual == expected_copy;
1412}
1413
1414static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
1415 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
1416 if (!ssl_ctx) {
1417 return nullptr;
1418 }
1419 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new(ssl_ctx.get()));
1420 if (!ret) {
1421 return nullptr;
1422 }
1423
David Benjaminaaef8332018-06-29 16:45:49 -04001424 uint8_t id[SSL3_SSL_SESSION_ID_LENGTH] = {0};
1425 OPENSSL_memcpy(id, &number, sizeof(number));
1426 if (!SSL_SESSION_set1_id(ret.get(), id, sizeof(id))) {
1427 return nullptr;
1428 }
David Benjaminc79ae7a2017-08-29 16:09:44 -04001429 return ret;
1430}
1431
1432// Test that the internal session cache behaves as expected.
1433TEST(SSLTest, InternalSessionCache) {
1434 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1435 ASSERT_TRUE(ctx);
1436
1437 // Prepare 10 test sessions.
1438 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
1439 for (int i = 0; i < 10; i++) {
1440 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
1441 ASSERT_TRUE(session);
1442 sessions.push_back(std::move(session));
1443 }
1444
1445 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1446
1447 // Insert all the test sessions.
1448 for (const auto &session : sessions) {
1449 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), session.get()));
1450 }
1451
1452 // Only the last five should be in the list.
1453 ASSERT_TRUE(CacheEquals(
1454 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
1455 sessions[6].get(), sessions[5].get()}));
1456
1457 // Inserting an element already in the cache should fail and leave the cache
1458 // unchanged.
1459 ASSERT_FALSE(SSL_CTX_add_session(ctx.get(), sessions[7].get()));
1460 ASSERT_TRUE(CacheEquals(
1461 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
1462 sessions[6].get(), sessions[5].get()}));
1463
1464 // Although collisions should be impossible (256-bit session IDs), the cache
1465 // must handle them gracefully.
1466 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
1467 ASSERT_TRUE(collision);
1468 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), collision.get()));
1469 ASSERT_TRUE(CacheEquals(
1470 ctx.get(), {collision.get(), sessions[9].get(), sessions[8].get(),
1471 sessions[6].get(), sessions[5].get()}));
1472
1473 // Removing sessions behaves correctly.
1474 ASSERT_TRUE(SSL_CTX_remove_session(ctx.get(), sessions[6].get()));
1475 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
1476 sessions[8].get(), sessions[5].get()}));
1477
1478 // Removing sessions requires an exact match.
1479 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[0].get()));
1480 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[7].get()));
1481
1482 // The cache remains unchanged.
1483 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
1484 sessions[8].get(), sessions[5].get()}));
1485}
1486
1487static uint16_t EpochFromSequence(uint64_t seq) {
1488 return static_cast<uint16_t>(seq >> 48);
1489}
1490
David Benjamin71dfad42017-07-16 17:27:39 -04001491static const uint8_t kTestName[] = {
1492 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
1493 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
1494 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
1495 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
1496 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
1497 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64,
1498};
1499
David Benjaminb79cc842016-12-07 15:57:14 -05001500static bool CompleteHandshakes(SSL *client, SSL *server) {
1501 // Drive both their handshakes to completion.
1502 for (;;) {
1503 int client_ret = SSL_do_handshake(client);
1504 int client_err = SSL_get_error(client, client_ret);
1505 if (client_err != SSL_ERROR_NONE &&
1506 client_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001507 client_err != SSL_ERROR_WANT_WRITE &&
1508 client_err != SSL_ERROR_PENDING_TICKET) {
David Benjaminb79cc842016-12-07 15:57:14 -05001509 fprintf(stderr, "Client error: %d\n", client_err);
1510 return false;
1511 }
1512
1513 int server_ret = SSL_do_handshake(server);
1514 int server_err = SSL_get_error(server, server_ret);
1515 if (server_err != SSL_ERROR_NONE &&
1516 server_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001517 server_err != SSL_ERROR_WANT_WRITE &&
1518 server_err != SSL_ERROR_PENDING_TICKET) {
David Benjaminb79cc842016-12-07 15:57:14 -05001519 fprintf(stderr, "Server error: %d\n", server_err);
1520 return false;
1521 }
1522
1523 if (client_ret == 1 && server_ret == 1) {
1524 break;
1525 }
1526 }
1527
1528 return true;
1529}
1530
Steven Valdez777a2392019-02-21 11:30:47 -05001531static bool FlushNewSessionTickets(SSL *client, SSL *server) {
1532 // NewSessionTickets are deferred on the server to |SSL_write|, and clients do
1533 // not pick them up until |SSL_read|.
1534 for (;;) {
1535 int server_ret = SSL_write(server, nullptr, 0);
1536 int server_err = SSL_get_error(server, server_ret);
1537 // The server may either succeed (|server_ret| is zero) or block on write
1538 // (|server_ret| is -1 and |server_err| is |SSL_ERROR_WANT_WRITE|).
1539 if (server_ret > 0 ||
1540 (server_ret < 0 && server_err != SSL_ERROR_WANT_WRITE)) {
1541 fprintf(stderr, "Unexpected server result: %d %d\n", server_ret,
1542 server_err);
1543 return false;
1544 }
1545
1546 int client_ret = SSL_read(client, nullptr, 0);
1547 int client_err = SSL_get_error(client, client_ret);
1548 // The client must always block on read.
1549 if (client_ret != -1 || client_err != SSL_ERROR_WANT_READ) {
1550 fprintf(stderr, "Unexpected client result: %d %d\n", client_ret,
1551 client_err);
1552 return false;
1553 }
1554
1555 // The server flushed everything it had to write.
1556 if (server_ret == 0) {
1557 return true;
1558 }
1559 }
1560}
1561
David Benjamina8614602017-09-06 15:40:19 -04001562struct ClientConfig {
1563 SSL_SESSION *session = nullptr;
1564 std::string servername;
1565};
1566
David Benjaminb79cc842016-12-07 15:57:14 -05001567static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client,
1568 bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001569 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
Adam Langleyddb57cf2018-01-26 09:17:53 -08001570 const ClientConfig &config = ClientConfig(),
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001571 bool do_handshake = true,
1572 bool shed_handshake_config = true) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001573 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001574 if (!client || !server) {
1575 return false;
1576 }
1577 SSL_set_connect_state(client.get());
1578 SSL_set_accept_state(server.get());
1579
David Benjamina8614602017-09-06 15:40:19 -04001580 if (config.session) {
1581 SSL_set_session(client.get(), config.session);
1582 }
1583 if (!config.servername.empty() &&
1584 !SSL_set_tlsext_host_name(client.get(), config.servername.c_str())) {
1585 return false;
1586 }
David Benjamina20e5352016-08-02 19:09:41 -04001587
David Benjaminde942382016-02-11 12:02:01 -05001588 BIO *bio1, *bio2;
1589 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1590 return false;
1591 }
1592 // SSL_set_bio takes ownership.
1593 SSL_set_bio(client.get(), bio1, bio1);
1594 SSL_set_bio(server.get(), bio2, bio2);
1595
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001596 SSL_set_shed_handshake_config(client.get(), shed_handshake_config);
1597 SSL_set_shed_handshake_config(server.get(), shed_handshake_config);
1598
Adam Langleyddb57cf2018-01-26 09:17:53 -08001599 if (do_handshake && !CompleteHandshakes(client.get(), server.get())) {
David Benjaminb79cc842016-12-07 15:57:14 -05001600 return false;
David Benjaminde942382016-02-11 12:02:01 -05001601 }
1602
David Benjamin686bb192016-05-10 15:15:41 -04001603 *out_client = std::move(client);
1604 *out_server = std::move(server);
1605 return true;
1606}
1607
David Benjaminc11ea9422017-08-29 16:33:21 -04001608// SSLVersionTest executes its test cases under all available protocol versions.
1609// Test cases call |Connect| to create a connection using context objects with
1610// the protocol version fixed to the current version under test.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001611class SSLVersionTest : public ::testing::TestWithParam<VersionParam> {
1612 protected:
1613 SSLVersionTest() : cert_(GetTestCertificate()), key_(GetTestKey()) {}
1614
1615 void SetUp() { ResetContexts(); }
1616
1617 bssl::UniquePtr<SSL_CTX> CreateContext() const {
1618 const SSL_METHOD *method = is_dtls() ? DTLS_method() : TLS_method();
1619 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
1620 if (!ctx || !SSL_CTX_set_min_proto_version(ctx.get(), version()) ||
1621 !SSL_CTX_set_max_proto_version(ctx.get(), version())) {
1622 return nullptr;
1623 }
1624 return ctx;
David Benjamin0fef3052016-11-18 15:11:10 +09001625 }
David Benjamin686bb192016-05-10 15:15:41 -04001626
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001627 void ResetContexts() {
1628 ASSERT_TRUE(cert_);
1629 ASSERT_TRUE(key_);
1630 client_ctx_ = CreateContext();
1631 ASSERT_TRUE(client_ctx_);
1632 server_ctx_ = CreateContext();
1633 ASSERT_TRUE(server_ctx_);
1634 // Set up a server cert. Client certs can be set up explicitly.
1635 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09001636 }
David Benjamin686bb192016-05-10 15:15:41 -04001637
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001638 bool UseCertAndKey(SSL_CTX *ctx) const {
1639 return SSL_CTX_use_certificate(ctx, cert_.get()) &&
1640 SSL_CTX_use_PrivateKey(ctx, key_.get());
David Benjamin0fef3052016-11-18 15:11:10 +09001641 }
David Benjamin686bb192016-05-10 15:15:41 -04001642
David Benjamina8614602017-09-06 15:40:19 -04001643 bool Connect(const ClientConfig &config = ClientConfig()) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001644 return ConnectClientAndServer(&client_, &server_, client_ctx_.get(),
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001645 server_ctx_.get(), config, true,
1646 shed_handshake_config_);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001647 }
1648
1649 uint16_t version() const { return GetParam().version; }
1650
1651 bool is_dtls() const {
1652 return GetParam().ssl_method == VersionParam::is_dtls;
1653 }
1654
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001655 bool shed_handshake_config_ = true;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001656 bssl::UniquePtr<SSL> client_, server_;
1657 bssl::UniquePtr<SSL_CTX> server_ctx_, client_ctx_;
1658 bssl::UniquePtr<X509> cert_;
1659 bssl::UniquePtr<EVP_PKEY> key_;
1660};
1661
David Benjaminbe7006a2019-04-09 18:05:02 -05001662INSTANTIATE_TEST_SUITE_P(WithVersion, SSLVersionTest,
1663 testing::ValuesIn(kAllVersions),
1664 [](const testing::TestParamInfo<VersionParam> &i) {
1665 return i.param.name;
1666 });
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001667
1668TEST_P(SSLVersionTest, SequenceNumber) {
1669 ASSERT_TRUE(Connect());
1670
David Benjamin0fef3052016-11-18 15:11:10 +09001671 // Drain any post-handshake messages to ensure there are no unread records
1672 // on either end.
Steven Valdez777a2392019-02-21 11:30:47 -05001673 ASSERT_TRUE(FlushNewSessionTickets(client_.get(), server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05001674
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001675 uint64_t client_read_seq = SSL_get_read_sequence(client_.get());
1676 uint64_t client_write_seq = SSL_get_write_sequence(client_.get());
1677 uint64_t server_read_seq = SSL_get_read_sequence(server_.get());
1678 uint64_t server_write_seq = SSL_get_write_sequence(server_.get());
Steven Valdez2c62fe92016-10-14 12:08:12 -04001679
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001680 if (is_dtls()) {
David Benjamin0fef3052016-11-18 15:11:10 +09001681 // Both client and server must be at epoch 1.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001682 EXPECT_EQ(EpochFromSequence(client_read_seq), 1);
1683 EXPECT_EQ(EpochFromSequence(client_write_seq), 1);
1684 EXPECT_EQ(EpochFromSequence(server_read_seq), 1);
1685 EXPECT_EQ(EpochFromSequence(server_write_seq), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09001686
1687 // The next record to be written should exceed the largest received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001688 EXPECT_GT(client_write_seq, server_read_seq);
1689 EXPECT_GT(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09001690 } else {
1691 // The next record to be written should equal the next to be received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001692 EXPECT_EQ(client_write_seq, server_read_seq);
1693 EXPECT_EQ(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09001694 }
1695
1696 // Send a record from client to server.
Steven Valdez777a2392019-02-21 11:30:47 -05001697 uint8_t byte = 0;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001698 EXPECT_EQ(SSL_write(client_.get(), &byte, 1), 1);
1699 EXPECT_EQ(SSL_read(server_.get(), &byte, 1), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09001700
1701 // The client write and server read sequence numbers should have
1702 // incremented.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001703 EXPECT_EQ(client_write_seq + 1, SSL_get_write_sequence(client_.get()));
1704 EXPECT_EQ(server_read_seq + 1, SSL_get_read_sequence(server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05001705}
1706
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001707TEST_P(SSLVersionTest, OneSidedShutdown) {
David Benjamin68f37b72016-11-18 15:14:42 +09001708 // SSL_shutdown is a no-op in DTLS.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001709 if (is_dtls()) {
1710 return;
David Benjamin686bb192016-05-10 15:15:41 -04001711 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001712 ASSERT_TRUE(Connect());
David Benjamin686bb192016-05-10 15:15:41 -04001713
1714 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1715 // one side has shut down.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001716 ASSERT_EQ(SSL_shutdown(client_.get()), 0);
David Benjamin686bb192016-05-10 15:15:41 -04001717
1718 // Reading from the server should consume the EOF.
1719 uint8_t byte;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001720 ASSERT_EQ(SSL_read(server_.get(), &byte, 1), 0);
1721 ASSERT_EQ(SSL_get_error(server_.get(), 0), SSL_ERROR_ZERO_RETURN);
David Benjamin686bb192016-05-10 15:15:41 -04001722
1723 // However, the server may continue to write data and then shut down the
1724 // connection.
1725 byte = 42;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001726 ASSERT_EQ(SSL_write(server_.get(), &byte, 1), 1);
1727 ASSERT_EQ(SSL_read(client_.get(), &byte, 1), 1);
1728 ASSERT_EQ(byte, 42);
David Benjamin686bb192016-05-10 15:15:41 -04001729
1730 // The server may then shutdown the connection.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001731 EXPECT_EQ(SSL_shutdown(server_.get()), 1);
1732 EXPECT_EQ(SSL_shutdown(client_.get()), 1);
David Benjamin686bb192016-05-10 15:15:41 -04001733}
David Benjamin68f37b72016-11-18 15:14:42 +09001734
David Benjaminf0d8e222017-02-04 10:58:26 -05001735TEST(SSLTest, SessionDuplication) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001736 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1737 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001738 ASSERT_TRUE(client_ctx);
1739 ASSERT_TRUE(server_ctx);
Steven Valdez87eab492016-06-27 16:34:59 -04001740
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001741 bssl::UniquePtr<X509> cert = GetTestCertificate();
1742 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminf0d8e222017-02-04 10:58:26 -05001743 ASSERT_TRUE(cert);
1744 ASSERT_TRUE(key);
1745 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
1746 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04001747
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001748 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05001749 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04001750 server_ctx.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04001751
1752 SSL_SESSION *session0 = SSL_get_session(client.get());
David Benjamin31b0c9b2017-07-20 14:49:15 -04001753 bssl::UniquePtr<SSL_SESSION> session1 =
1754 bssl::SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL);
David Benjaminf0d8e222017-02-04 10:58:26 -05001755 ASSERT_TRUE(session1);
David Benjamin4501bd52016-08-01 13:39:41 -04001756
David Benjamina3a71e92018-06-29 13:24:45 -04001757 session1->not_resumable = false;
Steven Valdez84b5c002016-08-25 16:30:58 -04001758
Steven Valdez87eab492016-06-27 16:34:59 -04001759 uint8_t *s0_bytes, *s1_bytes;
1760 size_t s0_len, s1_len;
1761
David Benjaminf0d8e222017-02-04 10:58:26 -05001762 ASSERT_TRUE(SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001763 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001764
David Benjaminf0d8e222017-02-04 10:58:26 -05001765 ASSERT_TRUE(SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001766 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001767
David Benjamin7d7554b2017-02-04 11:48:59 -05001768 EXPECT_EQ(Bytes(s0_bytes, s0_len), Bytes(s1_bytes, s1_len));
Steven Valdez87eab492016-06-27 16:34:59 -04001769}
David Benjamin686bb192016-05-10 15:15:41 -04001770
David Benjaminf0d8e222017-02-04 10:58:26 -05001771static void ExpectFDs(const SSL *ssl, int rfd, int wfd) {
David Benjaminca743582017-06-15 17:51:35 -04001772 EXPECT_EQ(rfd, SSL_get_fd(ssl));
David Benjaminf0d8e222017-02-04 10:58:26 -05001773 EXPECT_EQ(rfd, SSL_get_rfd(ssl));
1774 EXPECT_EQ(wfd, SSL_get_wfd(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04001775
1776 // The wrapper BIOs are always equal when fds are equal, even if set
1777 // individually.
David Benjaminf0d8e222017-02-04 10:58:26 -05001778 if (rfd == wfd) {
1779 EXPECT_EQ(SSL_get_rbio(ssl), SSL_get_wbio(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04001780 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001781}
1782
David Benjaminf0d8e222017-02-04 10:58:26 -05001783TEST(SSLTest, SetFD) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001784 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001785 ASSERT_TRUE(ctx);
David Benjamin5c0fb882016-06-14 14:03:51 -04001786
1787 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001788 bssl::UniquePtr<SSL> ssl(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(), 2));
1792 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04001793
1794 // Test setting the same FD.
1795 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001796 ASSERT_TRUE(ssl);
1797 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1798 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001799
1800 // Test setting the same FD one side at a time.
1801 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001802 ASSERT_TRUE(ssl);
1803 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1804 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1805 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001806
1807 // Test setting the same FD in the other order.
1808 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001809 ASSERT_TRUE(ssl);
1810 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1811 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1812 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001813
David Benjamin5c0fb882016-06-14 14:03:51 -04001814 // Test changing the read FD partway through.
1815 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001816 ASSERT_TRUE(ssl);
1817 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1818 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 2));
1819 ExpectFDs(ssl.get(), 2, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001820
1821 // Test changing the write FD partway through.
1822 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001823 ASSERT_TRUE(ssl);
1824 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1825 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
1826 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04001827
1828 // Test a no-op change to the read FD partway through.
1829 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001830 ASSERT_TRUE(ssl);
1831 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1832 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1833 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001834
1835 // Test a no-op change to the write FD partway through.
1836 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001837 ASSERT_TRUE(ssl);
1838 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1839 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1840 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001841
1842 // ASan builds will implicitly test that the internal |BIO| reference-counting
1843 // is correct.
David Benjamin5c0fb882016-06-14 14:03:51 -04001844}
1845
David Benjaminf0d8e222017-02-04 10:58:26 -05001846TEST(SSLTest, SetBIO) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001847 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001848 ASSERT_TRUE(ctx);
David Benjamin4501bd52016-08-01 13:39:41 -04001849
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001850 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1851 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04001852 bio3(BIO_new(BIO_s_mem()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001853 ASSERT_TRUE(ssl);
1854 ASSERT_TRUE(bio1);
1855 ASSERT_TRUE(bio2);
1856 ASSERT_TRUE(bio3);
David Benjamin4501bd52016-08-01 13:39:41 -04001857
1858 // SSL_set_bio takes one reference when the parameters are the same.
1859 BIO_up_ref(bio1.get());
1860 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1861
1862 // Repeating the call does nothing.
1863 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1864
1865 // It takes one reference each when the parameters are different.
1866 BIO_up_ref(bio2.get());
1867 BIO_up_ref(bio3.get());
1868 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1869
1870 // Repeating the call does nothing.
1871 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1872
1873 // It takes one reference when changing only wbio.
1874 BIO_up_ref(bio1.get());
1875 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1876
1877 // It takes one reference when changing only rbio and the two are different.
1878 BIO_up_ref(bio3.get());
1879 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1880
1881 // If setting wbio to rbio, it takes no additional references.
1882 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1883
1884 // From there, wbio may be switched to something else.
1885 BIO_up_ref(bio1.get());
1886 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1887
1888 // If setting rbio to wbio, it takes no additional references.
1889 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1890
1891 // From there, rbio may be switched to something else, but, for historical
1892 // reasons, it takes a reference to both parameters.
1893 BIO_up_ref(bio1.get());
1894 BIO_up_ref(bio2.get());
1895 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1896
1897 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1898 // is correct.
David Benjamin4501bd52016-08-01 13:39:41 -04001899}
1900
David Benjamin25490f22016-07-14 00:22:54 -04001901static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1902
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001903TEST_P(SSLVersionTest, GetPeerCertificate) {
1904 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04001905
David Benjamin0fef3052016-11-18 15:11:10 +09001906 // Configure both client and server to accept any certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001907 SSL_CTX_set_verify(client_ctx_.get(),
1908 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1909 nullptr);
1910 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
1911 SSL_CTX_set_verify(server_ctx_.get(),
1912 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1913 nullptr);
1914 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjaminadd5e522016-07-14 00:33:24 -04001915
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001916 ASSERT_TRUE(Connect());
David Benjaminadd5e522016-07-14 00:33:24 -04001917
David Benjamin0fef3052016-11-18 15:11:10 +09001918 // Client and server should both see the leaf certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001919 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1920 ASSERT_TRUE(peer);
1921 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04001922
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001923 peer.reset(SSL_get_peer_certificate(client_.get()));
1924 ASSERT_TRUE(peer);
1925 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04001926
David Benjamine664a532017-07-20 20:19:36 -04001927 // However, for historical reasons, the X509 chain includes the leaf on the
David Benjamin0fef3052016-11-18 15:11:10 +09001928 // client, but does not on the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001929 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(client_.get())), 1u);
1930 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(client_.get())),
1931 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04001932
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001933 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(server_.get())), 0u);
1934 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(server_.get())),
1935 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04001936}
1937
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001938TEST_P(SSLVersionTest, NoPeerCertificate) {
1939 SSL_CTX_set_verify(server_ctx_.get(), SSL_VERIFY_PEER, nullptr);
1940 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
1941 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
David Benjamine664a532017-07-20 20:19:36 -04001942
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001943 ASSERT_TRUE(Connect());
David Benjamine664a532017-07-20 20:19:36 -04001944
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001945 // Server should not see a peer certificate.
1946 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1947 ASSERT_FALSE(peer);
1948 ASSERT_FALSE(SSL_get0_peer_certificates(server_.get()));
David Benjamine664a532017-07-20 20:19:36 -04001949}
1950
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001951TEST_P(SSLVersionTest, RetainOnlySHA256OfCerts) {
David Benjamin25490f22016-07-14 00:22:54 -04001952 uint8_t *cert_der = NULL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001953 int cert_der_len = i2d_X509(cert_.get(), &cert_der);
1954 ASSERT_GE(cert_der_len, 0);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001955 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04001956
1957 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1958 SHA256(cert_der, cert_der_len, cert_sha256);
1959
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001960 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
1961
David Benjamin0fef3052016-11-18 15:11:10 +09001962 // Configure both client and server to accept any certificate, but the
1963 // server must retain only the SHA-256 of the peer.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001964 SSL_CTX_set_verify(client_ctx_.get(),
1965 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1966 nullptr);
1967 SSL_CTX_set_verify(server_ctx_.get(),
1968 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1969 nullptr);
1970 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
1971 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
1972 SSL_CTX_set_retain_only_sha256_of_client_certs(server_ctx_.get(), 1);
David Benjamin25490f22016-07-14 00:22:54 -04001973
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001974 ASSERT_TRUE(Connect());
David Benjamin25490f22016-07-14 00:22:54 -04001975
David Benjamin0fef3052016-11-18 15:11:10 +09001976 // The peer certificate has been dropped.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001977 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1978 EXPECT_FALSE(peer);
David Benjamin25490f22016-07-14 00:22:54 -04001979
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001980 SSL_SESSION *session = SSL_get_session(server_.get());
David Benjamin02de7bd2018-05-08 18:13:54 -04001981 EXPECT_TRUE(SSL_SESSION_has_peer_sha256(session));
David Benjamin25490f22016-07-14 00:22:54 -04001982
David Benjamin02de7bd2018-05-08 18:13:54 -04001983 const uint8_t *peer_sha256;
1984 size_t peer_sha256_len;
1985 SSL_SESSION_get0_peer_sha256(session, &peer_sha256, &peer_sha256_len);
1986 EXPECT_EQ(Bytes(cert_sha256), Bytes(peer_sha256, peer_sha256_len));
David Benjamin25490f22016-07-14 00:22:54 -04001987}
1988
David Benjamin737d2df2017-09-25 15:05:19 -04001989// Tests that our ClientHellos do not change unexpectedly. These are purely
1990// change detection tests. If they fail as part of an intentional ClientHello
1991// change, update the test vector.
1992TEST(SSLTest, ClientHello) {
1993 struct {
1994 uint16_t max_version;
1995 std::vector<uint8_t> expected;
1996 } kTests[] = {
David Benjamin737d2df2017-09-25 15:05:19 -04001997 {TLS1_VERSION,
1998 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x01, 0x00,
1999 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2000 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2001 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
2002 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
Adam Langleyd6680952018-08-23 08:01:23 -07002003 0x01, 0x00, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01,
2004 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
2005 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
David Benjamin737d2df2017-09-25 15:05:19 -04002006 {TLS1_1_VERSION,
2007 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x02, 0x00,
2008 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2009 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2010 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
2011 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
Adam Langleyd6680952018-08-23 08:01:23 -07002012 0x01, 0x00, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01,
2013 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
2014 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
David Benjamin737d2df2017-09-25 15:05:19 -04002015 {TLS1_2_VERSION,
David Benjamin6e678ee2018-04-16 19:54:42 -04002016 {0x16, 0x03, 0x01, 0x00, 0x82, 0x01, 0x00, 0x00, 0x7e, 0x03, 0x03, 0x00,
David Benjamin737d2df2017-09-25 15:05:19 -04002017 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2018 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
David Benjamin6e678ee2018-04-16 19:54:42 -04002019 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xcc, 0xa9,
David Benjamin737d2df2017-09-25 15:05:19 -04002020 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xc0, 0x09,
David Benjamin6e678ee2018-04-16 19:54:42 -04002021 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
Adam Langleyd6680952018-08-23 08:01:23 -07002022 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37, 0x00, 0x17, 0x00, 0x00,
2023 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00,
2024 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
2025 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04, 0x03, 0x08,
2026 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06,
2027 0x01, 0x02, 0x01}},
David Benjamin737d2df2017-09-25 15:05:19 -04002028 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
2029 // implementation has settled enough that it won't change.
David Benjaminafc64de2016-07-19 17:12:41 +02002030 };
David Benjamin737d2df2017-09-25 15:05:19 -04002031
2032 for (const auto &t : kTests) {
2033 SCOPED_TRACE(t.max_version);
2034
2035 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2036 ASSERT_TRUE(ctx);
2037 // Our default cipher list varies by CPU capabilities, so manually place the
2038 // ChaCha20 ciphers in front.
2039 const char *cipher_list = "CHACHA20:ALL";
David Benjamin737d2df2017-09-25 15:05:19 -04002040 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), t.max_version));
2041 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list));
2042
2043 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
2044 ASSERT_TRUE(ssl);
2045 std::vector<uint8_t> client_hello;
2046 ASSERT_TRUE(GetClientHello(ssl.get(), &client_hello));
2047
2048 // Zero the client_random.
2049 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
2050 1 + 3 + // handshake message header
2051 2; // client_version
2052 ASSERT_GE(client_hello.size(), kRandomOffset + SSL3_RANDOM_SIZE);
2053 OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
2054
2055 if (client_hello != t.expected) {
2056 ADD_FAILURE() << "ClientHellos did not match.";
2057 // Print the value manually so it is easier to update the test vector.
2058 for (size_t i = 0; i < client_hello.size(); i += 12) {
2059 printf(" %c", i == 0 ? '{' : ' ');
2060 for (size_t j = i; j < client_hello.size() && j < i + 12; j++) {
2061 if (j > i) {
2062 printf(" ");
2063 }
2064 printf("0x%02x", client_hello[j]);
2065 if (j < client_hello.size() - 1) {
2066 printf(",");
2067 }
2068 }
2069 if (i + 12 >= client_hello.size()) {
Adam Langleyd6680952018-08-23 08:01:23 -07002070 printf("}},");
David Benjamin737d2df2017-09-25 15:05:19 -04002071 }
2072 printf("\n");
2073 }
2074 }
David Benjaminafc64de2016-07-19 17:12:41 +02002075 }
David Benjaminafc64de2016-07-19 17:12:41 +02002076}
2077
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002078static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04002079
2080static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
2081 // Save the most recent session.
2082 g_last_session.reset(session);
2083 return 1;
2084}
2085
David Benjamina8614602017-09-06 15:40:19 -04002086static bssl::UniquePtr<SSL_SESSION> CreateClientSession(
2087 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2088 const ClientConfig &config = ClientConfig()) {
David Benjamina20e5352016-08-02 19:09:41 -04002089 g_last_session = nullptr;
2090 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2091
2092 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002093 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04002094 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
Steven Valdez777a2392019-02-21 11:30:47 -05002095 config) ||
2096 !FlushNewSessionTickets(client.get(), server.get())) {
David Benjamina20e5352016-08-02 19:09:41 -04002097 fprintf(stderr, "Failed to connect client and server.\n");
2098 return nullptr;
2099 }
2100
David Benjamina20e5352016-08-02 19:09:41 -04002101 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2102
2103 if (!g_last_session) {
2104 fprintf(stderr, "Client did not receive a session.\n");
2105 return nullptr;
2106 }
2107 return std::move(g_last_session);
2108}
2109
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002110static void ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2111 SSL_SESSION *session, bool want_reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002112 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002113 ClientConfig config;
2114 config.session = session;
2115 EXPECT_TRUE(
2116 ConnectClientAndServer(&client, &server, client_ctx, server_ctx, config));
David Benjamina20e5352016-08-02 19:09:41 -04002117
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002118 EXPECT_EQ(SSL_session_reused(client.get()), SSL_session_reused(server.get()));
David Benjamina20e5352016-08-02 19:09:41 -04002119
2120 bool was_reused = !!SSL_session_reused(client.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002121 EXPECT_EQ(was_reused, want_reused);
David Benjamina20e5352016-08-02 19:09:41 -04002122}
2123
David Benjamin3c51d9b2016-11-01 17:50:42 -04002124static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
2125 SSL_CTX *server_ctx,
2126 SSL_SESSION *session) {
2127 g_last_session = nullptr;
2128 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2129
2130 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002131 ClientConfig config;
2132 config.session = session;
2133 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
Steven Valdez777a2392019-02-21 11:30:47 -05002134 config) ||
2135 !FlushNewSessionTickets(client.get(), server.get())) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002136 fprintf(stderr, "Failed to connect client and server.\n");
2137 return nullptr;
2138 }
2139
2140 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2141 fprintf(stderr, "Client and server were inconsistent.\n");
2142 return nullptr;
2143 }
2144
2145 if (!SSL_session_reused(client.get())) {
2146 fprintf(stderr, "Session was not reused.\n");
2147 return nullptr;
2148 }
2149
David Benjamin3c51d9b2016-11-01 17:50:42 -04002150 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2151
2152 if (!g_last_session) {
2153 fprintf(stderr, "Client did not receive a renewed session.\n");
2154 return nullptr;
2155 }
2156 return std::move(g_last_session);
2157}
2158
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002159static void ExpectTicketKeyChanged(SSL_CTX *ctx, uint8_t *inout_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002160 bool changed) {
2161 uint8_t new_key[kTicketKeyLen];
David Benjaminc11ea9422017-08-29 16:33:21 -04002162 // May return 0, 1 or 48.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002163 ASSERT_EQ(SSL_CTX_get_tlsext_ticket_keys(ctx, new_key, kTicketKeyLen), 1);
2164 if (changed) {
2165 ASSERT_NE(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
2166 } else {
2167 ASSERT_EQ(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002168 }
2169 OPENSSL_memcpy(inout_key, new_key, kTicketKeyLen);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002170}
2171
David Benjamina933c382016-10-28 00:10:03 -04002172static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
2173 static const uint8_t kContext[] = {3};
2174
2175 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
2176 return SSL_TLSEXT_ERR_ALERT_FATAL;
2177 }
2178
2179 return SSL_TLSEXT_ERR_OK;
2180}
2181
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002182TEST_P(SSLVersionTest, SessionIDContext) {
David Benjamina20e5352016-08-02 19:09:41 -04002183 static const uint8_t kContext1[] = {1};
2184 static const uint8_t kContext2[] = {2};
2185
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002186 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2187 sizeof(kContext1)));
David Benjamina20e5352016-08-02 19:09:41 -04002188
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002189 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2190 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002191
David Benjamin0fef3052016-11-18 15:11:10 +09002192 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002193 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2194 ASSERT_TRUE(session);
David Benjamina20e5352016-08-02 19:09:41 -04002195
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002196 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2197 session.get(),
2198 true /* expect session reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002199
David Benjamin0fef3052016-11-18 15:11:10 +09002200 // Change the session ID context.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002201 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext2,
2202 sizeof(kContext2)));
David Benjamina20e5352016-08-02 19:09:41 -04002203
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002204 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2205 session.get(),
2206 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002207
David Benjamin0fef3052016-11-18 15:11:10 +09002208 // Change the session ID context back and install an SNI callback to switch
2209 // it.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002210 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2211 sizeof(kContext1)));
David Benjamina933c382016-10-28 00:10:03 -04002212
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002213 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09002214 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04002215
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002216 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2217 session.get(),
2218 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002219
David Benjamin0fef3052016-11-18 15:11:10 +09002220 // Switch the session ID context with the early callback instead.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002221 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), nullptr);
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002222 SSL_CTX_set_select_certificate_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002223 server_ctx_.get(),
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002224 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
2225 static const uint8_t kContext[] = {3};
2226
2227 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
2228 sizeof(kContext))) {
2229 return ssl_select_cert_error;
2230 }
2231
2232 return ssl_select_cert_success;
2233 });
David Benjamina933c382016-10-28 00:10:03 -04002234
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002235 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2236 session.get(),
2237 false /* expect session not reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002238}
2239
David Benjamin721e8b72016-08-03 13:13:17 -04002240static timeval g_current_time;
2241
2242static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2243 *out_clock = g_current_time;
2244}
2245
David Benjamin17b30832017-01-28 14:00:32 -05002246static void FrozenTimeCallback(const SSL *ssl, timeval *out_clock) {
2247 out_clock->tv_sec = 1000;
2248 out_clock->tv_usec = 0;
2249}
2250
David Benjamin3c51d9b2016-11-01 17:50:42 -04002251static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
2252 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
2253 int encrypt) {
2254 static const uint8_t kZeros[16] = {0};
2255
2256 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -05002257 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamin3c51d9b2016-11-01 17:50:42 -04002258 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -05002259 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002260 return 0;
2261 }
2262
2263 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
2264 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
2265 return -1;
2266 }
2267
2268 // Returning two from the callback in decrypt mode renews the
2269 // session in TLS 1.2 and below.
2270 return encrypt ? 1 : 2;
2271}
2272
David Benjamin123db572016-11-03 16:59:25 -04002273static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjaminaaef8332018-06-29 16:45:49 -04002274 const uint8_t *ticket;
2275 size_t ticket_len;
2276 SSL_SESSION_get0_ticket(session, &ticket, &ticket_len);
2277 if (ticket_len < 16 + 16 + SHA256_DIGEST_LENGTH) {
David Benjamin123db572016-11-03 16:59:25 -04002278 return false;
2279 }
2280
David Benjaminaaef8332018-06-29 16:45:49 -04002281 const uint8_t *ciphertext = ticket + 16 + 16;
2282 size_t len = ticket_len - 16 - 16 - SHA256_DIGEST_LENGTH;
David Benjamin123db572016-11-03 16:59:25 -04002283 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
2284
David Benjamin9b63f292016-11-15 00:44:05 -05002285#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
2286 // Fuzzer-mode tickets are unencrypted.
David Benjamin17cf2cb2016-12-13 01:07:13 -05002287 OPENSSL_memcpy(plaintext.get(), ciphertext, len);
David Benjamin9b63f292016-11-15 00:44:05 -05002288#else
2289 static const uint8_t kZeros[16] = {0};
David Benjaminaaef8332018-06-29 16:45:49 -04002290 const uint8_t *iv = ticket + 16;
David Benjamin123db572016-11-03 16:59:25 -04002291 bssl::ScopedEVP_CIPHER_CTX ctx;
2292 int len1, len2;
2293 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
2294 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
2295 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
2296 return false;
2297 }
2298
2299 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05002300#endif
David Benjamin123db572016-11-03 16:59:25 -04002301
Adam Langley46db7af2017-02-01 15:49:37 -08002302 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
2303 if (!ssl_ctx) {
2304 return false;
2305 }
David Benjamin123db572016-11-03 16:59:25 -04002306 bssl::UniquePtr<SSL_SESSION> server_session(
Adam Langley46db7af2017-02-01 15:49:37 -08002307 SSL_SESSION_from_bytes(plaintext.get(), len, ssl_ctx.get()));
David Benjamin123db572016-11-03 16:59:25 -04002308 if (!server_session) {
2309 return false;
2310 }
2311
David Benjaminaaef8332018-06-29 16:45:49 -04002312 *out = SSL_SESSION_get_time(server_session.get());
David Benjamin123db572016-11-03 16:59:25 -04002313 return true;
2314}
2315
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002316TEST_P(SSLVersionTest, SessionTimeout) {
2317 for (bool server_test : {false, true}) {
2318 SCOPED_TRACE(server_test);
David Benjamin721e8b72016-08-03 13:13:17 -04002319
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002320 ResetContexts();
2321 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2322 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
2323
David Benjamin17b30832017-01-28 14:00:32 -05002324 static const time_t kStartTime = 1000;
David Benjamin0fef3052016-11-18 15:11:10 +09002325 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002326
David Benjamin17b30832017-01-28 14:00:32 -05002327 // We are willing to use a longer lifetime for TLS 1.3 sessions as
2328 // resumptions still perform ECDHE.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002329 const time_t timeout = version() == TLS1_3_VERSION
David Benjamin17b30832017-01-28 14:00:32 -05002330 ? SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT
2331 : SSL_DEFAULT_SESSION_TIMEOUT;
2332
David Benjamin17b30832017-01-28 14:00:32 -05002333 // Both client and server must enforce session timeouts. We configure the
2334 // other side with a frozen clock so it never expires tickets.
David Benjamin0fef3052016-11-18 15:11:10 +09002335 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002336 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2337 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002338 } else {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002339 SSL_CTX_set_current_time_cb(client_ctx_.get(), CurrentTimeCallback);
2340 SSL_CTX_set_current_time_cb(server_ctx_.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002341 }
2342
2343 // Configure a ticket callback which renews tickets.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002344 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002345
2346 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002347 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2348 ASSERT_TRUE(session);
David Benjamin0fef3052016-11-18 15:11:10 +09002349
2350 // Advance the clock just behind the timeout.
David Benjamin17b30832017-01-28 14:00:32 -05002351 g_current_time.tv_sec += timeout - 1;
David Benjamin0fef3052016-11-18 15:11:10 +09002352
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002353 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2354 session.get(),
2355 true /* expect session reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002356
2357 // Advance the clock one more second.
2358 g_current_time.tv_sec++;
2359
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002360 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2361 session.get(),
2362 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002363
2364 // Rewind the clock to before the session was minted.
2365 g_current_time.tv_sec = kStartTime - 1;
2366
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002367 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2368 session.get(),
2369 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002370
David Benjamin0fef3052016-11-18 15:11:10 +09002371 // Renew the session 10 seconds before expiration.
David Benjamin17b30832017-01-28 14:00:32 -05002372 time_t new_start_time = kStartTime + timeout - 10;
2373 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002374 bssl::UniquePtr<SSL_SESSION> new_session = ExpectSessionRenewed(
2375 client_ctx_.get(), server_ctx_.get(), session.get());
2376 ASSERT_TRUE(new_session);
David Benjamin0fef3052016-11-18 15:11:10 +09002377
2378 // This new session is not the same object as before.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002379 EXPECT_NE(session.get(), new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002380
2381 // Check the sessions have timestamps measured from issuance.
2382 long session_time = 0;
2383 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002384 ASSERT_TRUE(GetServerTicketTime(&session_time, new_session.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09002385 } else {
David Benjaminaaef8332018-06-29 16:45:49 -04002386 session_time = SSL_SESSION_get_time(new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002387 }
David Benjamin721e8b72016-08-03 13:13:17 -04002388
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002389 ASSERT_EQ(session_time, g_current_time.tv_sec);
David Benjamin721e8b72016-08-03 13:13:17 -04002390
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002391 if (version() == TLS1_3_VERSION) {
David Benjamin17b30832017-01-28 14:00:32 -05002392 // Renewal incorporates fresh key material in TLS 1.3, so we extend the
2393 // lifetime TLS 1.3.
2394 g_current_time.tv_sec = new_start_time + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002395 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2396 new_session.get(),
2397 true /* expect session reused */));
David Benjamin721e8b72016-08-03 13:13:17 -04002398
David Benjamin17b30832017-01-28 14:00:32 -05002399 // The new session expires after the new timeout.
2400 g_current_time.tv_sec = new_start_time + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002401 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2402 new_session.get(),
2403 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002404
2405 // Renew the session until it begins just past the auth timeout.
2406 time_t auth_end_time = kStartTime + SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
2407 while (new_start_time < auth_end_time - 1000) {
2408 // Get as close as possible to target start time.
2409 new_start_time =
2410 std::min(auth_end_time - 1000, new_start_time + timeout - 1);
2411 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002412 new_session = ExpectSessionRenewed(client_ctx_.get(), server_ctx_.get(),
David Benjamin17b30832017-01-28 14:00:32 -05002413 new_session.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002414 ASSERT_TRUE(new_session);
David Benjamin17b30832017-01-28 14:00:32 -05002415 }
2416
2417 // Now the session's lifetime is bound by the auth timeout.
2418 g_current_time.tv_sec = auth_end_time - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002419 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2420 new_session.get(),
2421 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002422
2423 g_current_time.tv_sec = auth_end_time + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002424 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2425 new_session.get(),
2426 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002427 } else {
2428 // The new session is usable just before the old expiration.
2429 g_current_time.tv_sec = kStartTime + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002430 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2431 new_session.get(),
2432 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002433
2434 // Renewal does not extend the lifetime, so it is not usable beyond the
2435 // old expiration.
2436 g_current_time.tv_sec = kStartTime + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002437 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2438 new_session.get(),
2439 false /* expect session not reused */));
David Benjamin1b22f852016-10-27 16:36:32 -04002440 }
David Benjamin721e8b72016-08-03 13:13:17 -04002441 }
David Benjamin721e8b72016-08-03 13:13:17 -04002442}
2443
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002444TEST_P(SSLVersionTest, DefaultTicketKeyInitialization) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002445 static const uint8_t kZeroKey[kTicketKeyLen] = {};
2446 uint8_t ticket_key[kTicketKeyLen];
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002447 ASSERT_EQ(1, SSL_CTX_get_tlsext_ticket_keys(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002448 kTicketKeyLen));
2449 ASSERT_NE(0, OPENSSL_memcmp(ticket_key, kZeroKey, kTicketKeyLen));
2450}
2451
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002452TEST_P(SSLVersionTest, DefaultTicketKeyRotation) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002453 static const time_t kStartTime = 1001;
2454 g_current_time.tv_sec = kStartTime;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002455
David Benjaminc11ea9422017-08-29 16:33:21 -04002456 // We use session reuse as a proxy for ticket decryption success, hence
2457 // disable session timeouts.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002458 SSL_CTX_set_timeout(server_ctx_.get(), std::numeric_limits<uint32_t>::max());
2459 SSL_CTX_set_session_psk_dhe_timeout(server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002460 std::numeric_limits<uint32_t>::max());
2461
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002462 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2463 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002464
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002465 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2466 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_OFF);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002467
David Benjamin1f0d54b2018-08-09 16:19:13 -05002468 // Initialize ticket_key with the current key and check that it was
2469 // initialized to something, not all zeros.
2470 uint8_t ticket_key[kTicketKeyLen] = {0};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002471 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2472 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002473
David Benjaminc11ea9422017-08-29 16:33:21 -04002474 // Verify ticket resumption actually works.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002475 bssl::UniquePtr<SSL> client, server;
2476 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002477 CreateClientSession(client_ctx_.get(), server_ctx_.get());
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002478 ASSERT_TRUE(session);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002479 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002480 session.get(), true /* reused */));
2481
David Benjaminc11ea9422017-08-29 16:33:21 -04002482 // Advance time to just before key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002483 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002484 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002485 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002486 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002487 false /* NOT changed */));
2488
David Benjaminc11ea9422017-08-29 16:33:21 -04002489 // Force key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002490 g_current_time.tv_sec += 1;
2491 bssl::UniquePtr<SSL_SESSION> new_session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002492 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2493 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2494 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002495
David Benjaminc11ea9422017-08-29 16:33:21 -04002496 // Resumption with both old and new ticket should work.
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(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002499 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002500 new_session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002501 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002502 false /* NOT changed */));
2503
David Benjaminc11ea9422017-08-29 16:33:21 -04002504 // Force key rotation again. Resumption with the old ticket now fails.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002505 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002506 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002507 session.get(), false /* NOT reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002508 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2509 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002510
David Benjaminc11ea9422017-08-29 16:33:21 -04002511 // But resumption with the newer session still works.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002512 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002513 new_session.get(), true /* reused */));
2514}
2515
David Benjamin0fc37ef2016-08-17 15:29:46 -04002516static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002517 SSL_CTX *ctx = reinterpret_cast<SSL_CTX *>(arg);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002518 SSL_set_SSL_CTX(ssl, ctx);
2519 return SSL_TLSEXT_ERR_OK;
2520}
2521
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002522TEST_P(SSLVersionTest, SNICallback) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002523 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002524 ASSERT_TRUE(cert2);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002525 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002526 ASSERT_TRUE(key2);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002527
David Benjamin0fef3052016-11-18 15:11:10 +09002528 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
2529 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002530
David Benjamin83a32122017-02-14 18:34:54 -05002531 static const uint8_t kSCTList[] = {0, 6, 0, 4, 5, 6, 7, 8};
2532 static const uint8_t kOCSPResponse[] = {1, 2, 3, 4};
2533
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002534 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
2535 ASSERT_TRUE(server_ctx2);
2536 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()));
2537 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()));
2538 ASSERT_TRUE(SSL_CTX_set_signed_cert_timestamp_list(
2539 server_ctx2.get(), kSCTList, sizeof(kSCTList)));
2540 ASSERT_TRUE(SSL_CTX_set_ocsp_response(server_ctx2.get(), kOCSPResponse,
2541 sizeof(kOCSPResponse)));
2542 // Historically signing preferences would be lost in some cases with the
2543 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2544 // this doesn't happen when |version| is TLS 1.2, configure the private
2545 // key to only sign SHA-256.
2546 ASSERT_TRUE(SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
2547 &kECDSAWithSHA256, 1));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002548
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002549 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), SwitchContext);
2550 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002551
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002552 SSL_CTX_enable_signed_cert_timestamps(client_ctx_.get());
2553 SSL_CTX_enable_ocsp_stapling(client_ctx_.get());
David Benjamin83a32122017-02-14 18:34:54 -05002554
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002555 ASSERT_TRUE(Connect());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002556
David Benjamin0fef3052016-11-18 15:11:10 +09002557 // The client should have received |cert2|.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002558 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client_.get()));
2559 ASSERT_TRUE(peer);
2560 EXPECT_EQ(X509_cmp(peer.get(), cert2.get()), 0);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002561
David Benjamin83a32122017-02-14 18:34:54 -05002562 // The client should have received |server_ctx2|'s SCT list.
2563 const uint8_t *data;
2564 size_t len;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002565 SSL_get0_signed_cert_timestamp_list(client_.get(), &data, &len);
2566 EXPECT_EQ(Bytes(kSCTList), Bytes(data, len));
David Benjamin83a32122017-02-14 18:34:54 -05002567
2568 // The client should have received |server_ctx2|'s OCSP response.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002569 SSL_get0_ocsp_response(client_.get(), &data, &len);
2570 EXPECT_EQ(Bytes(kOCSPResponse), Bytes(data, len));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002571}
2572
David Benjaminf0d8e222017-02-04 10:58:26 -05002573// Test that the early callback can swap the maximum version.
2574TEST(SSLTest, EarlyCallbackVersionSwitch) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002575 bssl::UniquePtr<X509> cert = GetTestCertificate();
2576 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2577 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2578 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002579 ASSERT_TRUE(cert);
2580 ASSERT_TRUE(key);
2581 ASSERT_TRUE(server_ctx);
2582 ASSERT_TRUE(client_ctx);
2583 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
2584 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
2585 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
2586 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
David Benjamin99620572016-08-30 00:35:36 -04002587
David Benjaminf0d8e222017-02-04 10:58:26 -05002588 SSL_CTX_set_select_certificate_cb(
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002589 server_ctx.get(),
2590 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
David Benjaminf0d8e222017-02-04 10:58:26 -05002591 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002592 return ssl_select_cert_error;
David Benjaminf0d8e222017-02-04 10:58:26 -05002593 }
2594
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002595 return ssl_select_cert_success;
David Benjaminf0d8e222017-02-04 10:58:26 -05002596 });
David Benjamin99620572016-08-30 00:35:36 -04002597
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002598 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05002599 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04002600 server_ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002601 EXPECT_EQ(TLS1_2_VERSION, SSL_version(client.get()));
David Benjamin99620572016-08-30 00:35:36 -04002602}
2603
David Benjaminf0d8e222017-02-04 10:58:26 -05002604TEST(SSLTest, SetVersion) {
David Benjamin2dc02042016-09-19 19:57:37 -04002605 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002606 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002607
David Benjaminf0d8e222017-02-04 10:58:26 -05002608 // Set valid TLS versions.
2609 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2610 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
2611 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2612 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002613
David Benjaminf0d8e222017-02-04 10:58:26 -05002614 // Invalid TLS versions are rejected.
2615 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2616 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x0200));
2617 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2618 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2619 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x0200));
2620 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002621
David Benjaminf0d8e222017-02-04 10:58:26 -05002622 // Zero is the default version.
2623 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07002624 EXPECT_EQ(TLS1_2_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002625 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07002626 EXPECT_EQ(TLS1_VERSION, SSL_CTX_get_min_proto_version(ctx.get()));
David Benjamin3cfeb952017-03-01 16:48:38 -05002627
David Benjamin9bb15f52018-06-26 00:07:40 -04002628 // TLS 1.3 is available, but not by default.
David Benjamin3cfeb952017-03-01 16:48:38 -05002629 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07002630 EXPECT_EQ(TLS1_3_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjamine34bcc92016-09-21 16:53:09 -04002631
David Benjamin9bb15f52018-06-26 00:07:40 -04002632 // SSL 3.0 is not available.
2633 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION));
2634
David Benjamin2dc02042016-09-19 19:57:37 -04002635 ctx.reset(SSL_CTX_new(DTLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002636 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002637
David Benjaminf0d8e222017-02-04 10:58:26 -05002638 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2639 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION));
2640 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2641 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002642
David Benjaminf0d8e222017-02-04 10:58:26 -05002643 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2644 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2645 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2646 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2647 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2648 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2649 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2650 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002651
David Benjaminf0d8e222017-02-04 10:58:26 -05002652 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07002653 EXPECT_EQ(DTLS1_2_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002654 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
Nitish Sakhawalkara4af5f82019-03-25 17:26:59 -07002655 EXPECT_EQ(DTLS1_VERSION, SSL_CTX_get_min_proto_version(ctx.get()));
David Benjamin2dc02042016-09-19 19:57:37 -04002656}
2657
David Benjamin458334a2016-12-15 13:53:25 -05002658static const char *GetVersionName(uint16_t version) {
2659 switch (version) {
David Benjamin458334a2016-12-15 13:53:25 -05002660 case TLS1_VERSION:
2661 return "TLSv1";
2662 case TLS1_1_VERSION:
2663 return "TLSv1.1";
2664 case TLS1_2_VERSION:
2665 return "TLSv1.2";
2666 case TLS1_3_VERSION:
2667 return "TLSv1.3";
2668 case DTLS1_VERSION:
2669 return "DTLSv1";
2670 case DTLS1_2_VERSION:
2671 return "DTLSv1.2";
2672 default:
2673 return "???";
2674 }
2675}
2676
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002677TEST_P(SSLVersionTest, Version) {
2678 ASSERT_TRUE(Connect());
David Benjamincb18ac22016-09-27 14:09:15 -04002679
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002680 EXPECT_EQ(SSL_version(client_.get()), version());
2681 EXPECT_EQ(SSL_version(server_.get()), version());
David Benjamincb18ac22016-09-27 14:09:15 -04002682
David Benjamin458334a2016-12-15 13:53:25 -05002683 // Test the version name is reported as expected.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002684 const char *version_name = GetVersionName(version());
2685 EXPECT_EQ(strcmp(version_name, SSL_get_version(client_.get())), 0);
2686 EXPECT_EQ(strcmp(version_name, SSL_get_version(server_.get())), 0);
David Benjamin458334a2016-12-15 13:53:25 -05002687
2688 // Test SSL_SESSION reports the same name.
2689 const char *client_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002690 SSL_SESSION_get_version(SSL_get_session(client_.get()));
David Benjamin458334a2016-12-15 13:53:25 -05002691 const char *server_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002692 SSL_SESSION_get_version(SSL_get_session(server_.get()));
2693 EXPECT_EQ(strcmp(version_name, client_name), 0);
2694 EXPECT_EQ(strcmp(version_name, server_name), 0);
David Benjamincb18ac22016-09-27 14:09:15 -04002695}
2696
David Benjamin9ef31f02016-10-31 18:01:13 -04002697// Tests that that |SSL_get_pending_cipher| is available during the ALPN
2698// selection callback.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002699TEST_P(SSLVersionTest, ALPNCipherAvailable) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002700 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2701
David Benjamin9ef31f02016-10-31 18:01:13 -04002702 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002703 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
2704 sizeof(kALPNProtos)),
2705 0);
David Benjamin0fef3052016-11-18 15:11:10 +09002706
2707 // The ALPN callback does not fail the handshake on error, so have the
2708 // callback write a boolean.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002709 std::pair<uint16_t, bool> callback_state(version(), false);
David Benjamin0fef3052016-11-18 15:11:10 +09002710 SSL_CTX_set_alpn_select_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002711 server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09002712 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
2713 unsigned in_len, void *arg) -> int {
2714 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
2715 if (SSL_get_pending_cipher(ssl) != nullptr &&
2716 SSL_version(ssl) == state->first) {
2717 state->second = true;
2718 }
2719 return SSL_TLSEXT_ERR_NOACK;
2720 },
2721 &callback_state);
2722
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002723 ASSERT_TRUE(Connect());
David Benjamin0fef3052016-11-18 15:11:10 +09002724
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002725 ASSERT_TRUE(callback_state.second);
David Benjamin0fef3052016-11-18 15:11:10 +09002726}
2727
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002728TEST_P(SSLVersionTest, SSLClearSessionResumption) {
David Benjaminb79cc842016-12-07 15:57:14 -05002729 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
2730 // API pattern.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002731 if (version() == TLS1_3_VERSION) {
2732 return;
David Benjaminb79cc842016-12-07 15:57:14 -05002733 }
2734
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07002735 shed_handshake_config_ = false;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002736 ASSERT_TRUE(Connect());
David Benjaminb79cc842016-12-07 15:57:14 -05002737
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002738 EXPECT_FALSE(SSL_session_reused(client_.get()));
2739 EXPECT_FALSE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002740
2741 // Reset everything.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002742 ASSERT_TRUE(SSL_clear(client_.get()));
2743 ASSERT_TRUE(SSL_clear(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002744
2745 // Attempt to connect a second time.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002746 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002747
2748 // |SSL_clear| should implicitly offer the previous session to the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002749 EXPECT_TRUE(SSL_session_reused(client_.get()));
2750 EXPECT_TRUE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002751}
2752
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07002753TEST_P(SSLVersionTest, SSLClearFailsWithShedding) {
2754 shed_handshake_config_ = false;
2755 ASSERT_TRUE(Connect());
2756 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
2757
2758 // Reset everything.
2759 ASSERT_TRUE(SSL_clear(client_.get()));
2760 ASSERT_TRUE(SSL_clear(server_.get()));
2761
2762 // Now enable shedding, and connect a second time.
2763 shed_handshake_config_ = true;
2764 ASSERT_TRUE(Connect());
2765 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
2766
2767 // |SSL_clear| should now fail.
2768 ASSERT_FALSE(SSL_clear(client_.get()));
2769 ASSERT_FALSE(SSL_clear(server_.get()));
2770}
2771
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002772static bool ChainsEqual(STACK_OF(X509) * chain,
2773 const std::vector<X509 *> &expected) {
David Benjamin1444c3a2016-12-20 17:23:11 -05002774 if (sk_X509_num(chain) != expected.size()) {
2775 return false;
2776 }
2777
2778 for (size_t i = 0; i < expected.size(); i++) {
2779 if (X509_cmp(sk_X509_value(chain, i), expected[i]) != 0) {
2780 return false;
2781 }
2782 }
2783
2784 return true;
2785}
2786
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002787TEST_P(SSLVersionTest, AutoChain) {
2788 cert_ = GetChainTestCertificate();
2789 ASSERT_TRUE(cert_);
2790 key_ = GetChainTestKey();
2791 ASSERT_TRUE(key_);
David Benjamin1444c3a2016-12-20 17:23:11 -05002792 bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002793 ASSERT_TRUE(intermediate);
2794
2795 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2796 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin1444c3a2016-12-20 17:23:11 -05002797
2798 // Configure both client and server to accept any certificate. Add
2799 // |intermediate| to the cert store.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002800 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx_.get()),
2801 intermediate.get()));
2802 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(server_ctx_.get()),
2803 intermediate.get()));
2804 SSL_CTX_set_verify(client_ctx_.get(),
2805 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2806 nullptr);
2807 SSL_CTX_set_verify(server_ctx_.get(),
2808 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2809 nullptr);
2810 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
2811 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjamin1444c3a2016-12-20 17:23:11 -05002812
2813 // By default, the client and server should each only send the leaf.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002814 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002815
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002816 EXPECT_TRUE(
2817 ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()), {cert_.get()}));
2818 EXPECT_TRUE(
2819 ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()), {cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002820
2821 // If auto-chaining is enabled, then the intermediate is sent.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002822 SSL_CTX_clear_mode(client_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
2823 SSL_CTX_clear_mode(server_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
2824 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002825
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002826 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
2827 {cert_.get(), intermediate.get()}));
2828 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
2829 {cert_.get(), intermediate.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002830
2831 // Auto-chaining does not override explicitly-configured intermediates.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002832 ASSERT_TRUE(SSL_CTX_add1_chain_cert(client_ctx_.get(), cert_.get()));
2833 ASSERT_TRUE(SSL_CTX_add1_chain_cert(server_ctx_.get(), cert_.get()));
2834 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002835
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002836 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
2837 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002838
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002839 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
2840 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002841}
2842
David Benjamin48063c22017-01-01 23:56:36 -05002843static bool ExpectBadWriteRetry() {
2844 int err = ERR_get_error();
2845 if (ERR_GET_LIB(err) != ERR_LIB_SSL ||
2846 ERR_GET_REASON(err) != SSL_R_BAD_WRITE_RETRY) {
2847 char buf[ERR_ERROR_STRING_BUF_LEN];
2848 ERR_error_string_n(err, buf, sizeof(buf));
2849 fprintf(stderr, "Wanted SSL_R_BAD_WRITE_RETRY, got: %s.\n", buf);
2850 return false;
2851 }
2852
2853 if (ERR_peek_error() != 0) {
2854 fprintf(stderr, "Unexpected error following SSL_R_BAD_WRITE_RETRY.\n");
2855 return false;
2856 }
2857
2858 return true;
2859}
2860
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002861TEST_P(SSLVersionTest, SSLWriteRetry) {
2862 if (is_dtls()) {
2863 return;
David Benjamin48063c22017-01-01 23:56:36 -05002864 }
2865
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002866 for (bool enable_partial_write : {false, true}) {
2867 SCOPED_TRACE(enable_partial_write);
2868
David Benjamin48063c22017-01-01 23:56:36 -05002869 // Connect a client and server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002870 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2871
2872 ASSERT_TRUE(Connect());
David Benjamin48063c22017-01-01 23:56:36 -05002873
2874 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002875 SSL_set_mode(client_.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002876 }
2877
2878 // Write without reading until the buffer is full and we have an unfinished
2879 // write. Keep a count so we may reread it again later. "hello!" will be
2880 // written in two chunks, "hello" and "!".
2881 char data[] = "hello!";
2882 static const int kChunkLen = 5; // The length of "hello".
2883 unsigned count = 0;
2884 for (;;) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002885 int ret = SSL_write(client_.get(), data, kChunkLen);
David Benjamin48063c22017-01-01 23:56:36 -05002886 if (ret <= 0) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002887 ASSERT_EQ(SSL_get_error(client_.get(), ret), SSL_ERROR_WANT_WRITE);
2888 break;
David Benjamin48063c22017-01-01 23:56:36 -05002889 }
2890
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002891 ASSERT_EQ(ret, 5);
David Benjamin48063c22017-01-01 23:56:36 -05002892
2893 count++;
2894 }
2895
2896 // Retrying with the same parameters is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002897 ASSERT_EQ(
2898 SSL_get_error(client_.get(), SSL_write(client_.get(), data, kChunkLen)),
2899 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002900
2901 // Retrying with the same buffer but shorter length is not legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002902 ASSERT_EQ(SSL_get_error(client_.get(),
2903 SSL_write(client_.get(), data, kChunkLen - 1)),
2904 SSL_ERROR_SSL);
2905 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002906
2907 // Retrying with a different buffer pointer is not legal.
2908 char data2[] = "hello";
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002909 ASSERT_EQ(SSL_get_error(client_.get(),
2910 SSL_write(client_.get(), data2, kChunkLen)),
2911 SSL_ERROR_SSL);
2912 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002913
2914 // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002915 SSL_set_mode(client_.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
2916 ASSERT_EQ(SSL_get_error(client_.get(),
2917 SSL_write(client_.get(), data2, kChunkLen)),
2918 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002919
2920 // |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| does not disable length checks.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002921 ASSERT_EQ(SSL_get_error(client_.get(),
2922 SSL_write(client_.get(), data2, kChunkLen - 1)),
2923 SSL_ERROR_SSL);
2924 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002925
2926 // Retrying with a larger buffer is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002927 ASSERT_EQ(SSL_get_error(client_.get(),
2928 SSL_write(client_.get(), data, kChunkLen + 1)),
2929 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002930
2931 // Drain the buffer.
2932 char buf[20];
2933 for (unsigned i = 0; i < count; i++) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002934 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
2935 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
David Benjamin48063c22017-01-01 23:56:36 -05002936 }
2937
2938 // Now that there is space, a retry with a larger buffer should flush the
2939 // pending record, skip over that many bytes of input (on assumption they
2940 // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE
2941 // is set, this will complete in two steps.
2942 char data3[] = "_____!";
2943 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002944 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen);
2945 ASSERT_EQ(SSL_write(client_.get(), data3 + kChunkLen, 1), 1);
2946 } else {
2947 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen + 1);
David Benjamin48063c22017-01-01 23:56:36 -05002948 }
2949
2950 // Check the last write was correct. The data will be spread over two
2951 // records, so SSL_read returns twice.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002952 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
2953 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
2954 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), 1);
2955 ASSERT_EQ(buf[0], '!');
David Benjamin48063c22017-01-01 23:56:36 -05002956 }
David Benjamin48063c22017-01-01 23:56:36 -05002957}
2958
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002959TEST_P(SSLVersionTest, RecordCallback) {
2960 for (bool test_server : {true, false}) {
2961 SCOPED_TRACE(test_server);
2962 ResetContexts();
David Benjamin5df5be12017-06-22 19:43:11 -04002963
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002964 bool read_seen = false;
2965 bool write_seen = false;
2966 auto cb = [&](int is_write, int cb_version, int cb_type, const void *buf,
2967 size_t len, SSL *ssl) {
2968 if (cb_type != SSL3_RT_HEADER) {
2969 return;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002970 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002971
2972 // The callback does not report a version for records.
2973 EXPECT_EQ(0, cb_version);
2974
2975 if (is_write) {
2976 write_seen = true;
2977 } else {
2978 read_seen = true;
2979 }
2980
2981 // Sanity-check that the record header is plausible.
2982 CBS cbs;
2983 CBS_init(&cbs, reinterpret_cast<const uint8_t *>(buf), len);
2984 uint8_t type;
2985 uint16_t record_version, length;
2986 ASSERT_TRUE(CBS_get_u8(&cbs, &type));
2987 ASSERT_TRUE(CBS_get_u16(&cbs, &record_version));
Steven Valdez64cc1212017-12-04 11:15:37 -05002988 EXPECT_EQ(record_version & 0xff00, version() & 0xff00);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002989 if (is_dtls()) {
2990 uint16_t epoch;
2991 ASSERT_TRUE(CBS_get_u16(&cbs, &epoch));
2992 EXPECT_TRUE(epoch == 0 || epoch == 1) << "Invalid epoch: " << epoch;
2993 ASSERT_TRUE(CBS_skip(&cbs, 6));
2994 }
2995 ASSERT_TRUE(CBS_get_u16(&cbs, &length));
2996 EXPECT_EQ(0u, CBS_len(&cbs));
2997 };
2998 using CallbackType = decltype(cb);
2999 SSL_CTX *ctx = test_server ? server_ctx_.get() : client_ctx_.get();
3000 SSL_CTX_set_msg_callback(
3001 ctx, [](int is_write, int cb_version, int cb_type, const void *buf,
3002 size_t len, SSL *ssl, void *arg) {
3003 CallbackType *cb_ptr = reinterpret_cast<CallbackType *>(arg);
3004 (*cb_ptr)(is_write, cb_version, cb_type, buf, len, ssl);
3005 });
3006 SSL_CTX_set_msg_callback_arg(ctx, &cb);
3007
3008 ASSERT_TRUE(Connect());
3009
3010 EXPECT_TRUE(read_seen);
3011 EXPECT_TRUE(write_seen);
David Benjamin0fef3052016-11-18 15:11:10 +09003012 }
David Benjamin9ef31f02016-10-31 18:01:13 -04003013}
3014
David Benjamina8614602017-09-06 15:40:19 -04003015TEST_P(SSLVersionTest, GetServerName) {
David Benjamina8614602017-09-06 15:40:19 -04003016 ClientConfig config;
3017 config.servername = "host1";
3018
3019 SSL_CTX_set_tlsext_servername_callback(
3020 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
3021 // During the handshake, |SSL_get_servername| must match |config|.
3022 ClientConfig *config_p = reinterpret_cast<ClientConfig *>(arg);
3023 EXPECT_STREQ(config_p->servername.c_str(),
3024 SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name));
3025 return SSL_TLSEXT_ERR_OK;
3026 });
3027 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), &config);
3028
3029 ASSERT_TRUE(Connect(config));
3030 // After the handshake, it must also be available.
3031 EXPECT_STREQ(config.servername.c_str(),
3032 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3033
3034 // Establish a session under host1.
3035 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3036 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3037 bssl::UniquePtr<SSL_SESSION> session =
3038 CreateClientSession(client_ctx_.get(), server_ctx_.get(), config);
3039
3040 // If the client resumes a session with a different name, |SSL_get_servername|
3041 // must return the new name.
3042 ASSERT_TRUE(session);
3043 config.session = session.get();
3044 config.servername = "host2";
3045 ASSERT_TRUE(Connect(config));
3046 EXPECT_STREQ(config.servername.c_str(),
3047 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3048}
3049
David Benjamin3d8f0802017-09-06 16:12:52 -04003050// Test that session cache mode bits are honored in the client session callback.
3051TEST_P(SSLVersionTest, ClientSessionCacheMode) {
3052 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_OFF);
3053 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3054
3055 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_CLIENT);
3056 EXPECT_TRUE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3057
3058 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_SERVER);
3059 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3060}
3061
Steven Valdez777a2392019-02-21 11:30:47 -05003062// Test that all versions survive tiny write buffers. In particular, TLS 1.3
3063// NewSessionTickets are written post-handshake. Servers that block
3064// |SSL_do_handshake| on writing them will deadlock if clients are not draining
3065// the buffer. Test that we do not do this.
3066TEST_P(SSLVersionTest, SmallBuffer) {
3067 // DTLS is a datagram protocol and requires packet-sized buffers.
3068 if (is_dtls()) {
3069 return;
3070 }
3071
3072 // Test both flushing NewSessionTickets with a zero-sized write and
3073 // non-zero-sized write.
3074 for (bool use_zero_write : {false, true}) {
3075 SCOPED_TRACE(use_zero_write);
3076
3077 g_last_session = nullptr;
3078 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3079 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
3080
3081 bssl::UniquePtr<SSL> client(SSL_new(client_ctx_.get())),
3082 server(SSL_new(server_ctx_.get()));
3083 ASSERT_TRUE(client);
3084 ASSERT_TRUE(server);
3085 SSL_set_connect_state(client.get());
3086 SSL_set_accept_state(server.get());
3087
3088 // Use a tiny buffer.
3089 BIO *bio1, *bio2;
3090 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 1, &bio2, 1));
3091
3092 // SSL_set_bio takes ownership.
3093 SSL_set_bio(client.get(), bio1, bio1);
3094 SSL_set_bio(server.get(), bio2, bio2);
3095
3096 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
3097 if (version() >= TLS1_3_VERSION) {
3098 // The post-handshake ticket should not have been processed yet.
3099 EXPECT_FALSE(g_last_session);
3100 }
3101
3102 if (use_zero_write) {
3103 ASSERT_TRUE(FlushNewSessionTickets(client.get(), server.get()));
3104 EXPECT_TRUE(g_last_session);
3105 }
3106
3107 // Send some data from server to client. If |use_zero_write| is false, this
3108 // will also flush the NewSessionTickets.
3109 static const char kMessage[] = "hello world";
3110 char buf[sizeof(kMessage)];
3111 for (;;) {
3112 int server_ret = SSL_write(server.get(), kMessage, sizeof(kMessage));
3113 int server_err = SSL_get_error(server.get(), server_ret);
3114 int client_ret = SSL_read(client.get(), buf, sizeof(buf));
3115 int client_err = SSL_get_error(client.get(), client_ret);
3116
3117 // The server will write a single record, so every iteration should see
3118 // |SSL_ERROR_WANT_WRITE| and |SSL_ERROR_WANT_READ|, until the final
3119 // iteration, where both will complete.
3120 if (server_ret > 0) {
3121 EXPECT_EQ(server_ret, static_cast<int>(sizeof(kMessage)));
3122 EXPECT_EQ(client_ret, static_cast<int>(sizeof(kMessage)));
3123 EXPECT_EQ(Bytes(buf), Bytes(kMessage));
3124 break;
3125 }
3126
3127 ASSERT_EQ(server_ret, -1);
3128 ASSERT_EQ(server_err, SSL_ERROR_WANT_WRITE);
3129 ASSERT_EQ(client_ret, -1);
3130 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
3131 }
3132
3133 // The NewSessionTickets should have been flushed and processed.
3134 EXPECT_TRUE(g_last_session);
3135 }
3136}
3137
Adam Langleye1e78132017-01-31 15:24:31 -08003138TEST(SSLTest, AddChainCertHack) {
3139 // Ensure that we don't accidently break the hack that we have in place to
3140 // keep curl and serf happy when they use an |X509| even after transfering
3141 // ownership.
3142
3143 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3144 ASSERT_TRUE(ctx);
3145 X509 *cert = GetTestCertificate().release();
3146 ASSERT_TRUE(cert);
3147 SSL_CTX_add0_chain_cert(ctx.get(), cert);
3148
3149 // This should not trigger a use-after-free.
3150 X509_cmp(cert, cert);
3151}
3152
David Benjaminb2ff2622017-02-03 17:06:18 -05003153TEST(SSLTest, GetCertificate) {
3154 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3155 ASSERT_TRUE(ctx);
3156 bssl::UniquePtr<X509> cert = GetTestCertificate();
3157 ASSERT_TRUE(cert);
3158 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
3159 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3160 ASSERT_TRUE(ssl);
3161
3162 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
3163 ASSERT_TRUE(cert2);
3164 X509 *cert3 = SSL_get_certificate(ssl.get());
3165 ASSERT_TRUE(cert3);
3166
3167 // The old and new certificates must be identical.
3168 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
3169 EXPECT_EQ(0, X509_cmp(cert.get(), cert3));
3170
3171 uint8_t *der = nullptr;
3172 long der_len = i2d_X509(cert.get(), &der);
3173 ASSERT_LT(0, der_len);
3174 bssl::UniquePtr<uint8_t> free_der(der);
3175
3176 uint8_t *der2 = nullptr;
3177 long der2_len = i2d_X509(cert2, &der2);
3178 ASSERT_LT(0, der2_len);
3179 bssl::UniquePtr<uint8_t> free_der2(der2);
3180
3181 uint8_t *der3 = nullptr;
3182 long der3_len = i2d_X509(cert3, &der3);
3183 ASSERT_LT(0, der3_len);
3184 bssl::UniquePtr<uint8_t> free_der3(der3);
3185
3186 // They must also encode identically.
David Benjamin7d7554b2017-02-04 11:48:59 -05003187 EXPECT_EQ(Bytes(der, der_len), Bytes(der2, der2_len));
3188 EXPECT_EQ(Bytes(der, der_len), Bytes(der3, der3_len));
David Benjaminb2ff2622017-02-03 17:06:18 -05003189}
3190
Adam Langleyd04ca952017-02-28 11:26:51 -08003191TEST(SSLTest, SetChainAndKeyMismatch) {
3192 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_with_buffers_method()));
3193 ASSERT_TRUE(ctx);
3194
3195 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3196 ASSERT_TRUE(key);
3197 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3198 ASSERT_TRUE(leaf);
3199 std::vector<CRYPTO_BUFFER*> chain = {
3200 leaf.get(),
3201 };
3202
3203 // Should fail because |GetTestKey| doesn't match the chain-test certificate.
3204 ASSERT_FALSE(SSL_CTX_set_chain_and_key(ctx.get(), &chain[0], chain.size(),
3205 key.get(), nullptr));
3206 ERR_clear_error();
3207}
3208
3209TEST(SSLTest, SetChainAndKey) {
3210 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3211 ASSERT_TRUE(client_ctx);
3212 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3213 ASSERT_TRUE(server_ctx);
3214
3215 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3216 ASSERT_TRUE(key);
3217 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3218 ASSERT_TRUE(leaf);
3219 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3220 GetChainTestIntermediateBuffer();
3221 ASSERT_TRUE(intermediate);
3222 std::vector<CRYPTO_BUFFER*> chain = {
3223 leaf.get(), intermediate.get(),
3224 };
3225 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3226 chain.size(), key.get(), nullptr));
3227
David Benjamin3a1dd462017-07-11 16:13:10 -04003228 SSL_CTX_set_custom_verify(
3229 client_ctx.get(), SSL_VERIFY_PEER,
3230 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3231 return ssl_verify_ok;
3232 });
Adam Langleyd04ca952017-02-28 11:26:51 -08003233
3234 bssl::UniquePtr<SSL> client, server;
3235 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003236 server_ctx.get()));
Adam Langleyd04ca952017-02-28 11:26:51 -08003237}
3238
Matthew Braithwaite5301c102018-01-23 12:08:55 -08003239TEST(SSLTest, BuffersFailWithoutCustomVerify) {
3240 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3241 ASSERT_TRUE(client_ctx);
3242 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3243 ASSERT_TRUE(server_ctx);
3244
3245 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3246 ASSERT_TRUE(key);
3247 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3248 ASSERT_TRUE(leaf);
3249 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
3250 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3251 chain.size(), key.get(), nullptr));
3252
3253 // Without SSL_CTX_set_custom_verify(), i.e. with everything in the default
3254 // configuration, certificate verification should fail.
3255 bssl::UniquePtr<SSL> client, server;
3256 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3257 server_ctx.get()));
3258
3259 // Whereas with a verifier, the connection should succeed.
3260 SSL_CTX_set_custom_verify(
3261 client_ctx.get(), SSL_VERIFY_PEER,
3262 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3263 return ssl_verify_ok;
3264 });
3265 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3266 server_ctx.get()));
3267}
3268
3269TEST(SSLTest, CustomVerify) {
3270 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3271 ASSERT_TRUE(client_ctx);
3272 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3273 ASSERT_TRUE(server_ctx);
3274
3275 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3276 ASSERT_TRUE(key);
3277 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3278 ASSERT_TRUE(leaf);
3279 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
3280 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3281 chain.size(), key.get(), nullptr));
3282
3283 SSL_CTX_set_custom_verify(
3284 client_ctx.get(), SSL_VERIFY_PEER,
3285 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3286 return ssl_verify_ok;
3287 });
3288
3289 bssl::UniquePtr<SSL> client, server;
3290 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3291 server_ctx.get()));
3292
3293 // With SSL_VERIFY_PEER, ssl_verify_invalid should result in a dropped
3294 // connection.
3295 SSL_CTX_set_custom_verify(
3296 client_ctx.get(), SSL_VERIFY_PEER,
3297 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3298 return ssl_verify_invalid;
3299 });
3300
3301 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3302 server_ctx.get()));
3303
3304 // But with SSL_VERIFY_NONE, ssl_verify_invalid should not cause a dropped
3305 // connection.
3306 SSL_CTX_set_custom_verify(
3307 client_ctx.get(), SSL_VERIFY_NONE,
3308 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3309 return ssl_verify_invalid;
3310 });
3311
3312 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3313 server_ctx.get()));
3314}
3315
David Benjamin71dfad42017-07-16 17:27:39 -04003316TEST(SSLTest, ClientCABuffers) {
3317 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3318 ASSERT_TRUE(client_ctx);
3319 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3320 ASSERT_TRUE(server_ctx);
3321
3322 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3323 ASSERT_TRUE(key);
3324 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3325 ASSERT_TRUE(leaf);
3326 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3327 GetChainTestIntermediateBuffer();
3328 ASSERT_TRUE(intermediate);
3329 std::vector<CRYPTO_BUFFER *> chain = {
3330 leaf.get(),
3331 intermediate.get(),
3332 };
3333 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3334 chain.size(), key.get(), nullptr));
3335
3336 bssl::UniquePtr<CRYPTO_BUFFER> ca_name(
3337 CRYPTO_BUFFER_new(kTestName, sizeof(kTestName), nullptr));
3338 ASSERT_TRUE(ca_name);
3339 bssl::UniquePtr<STACK_OF(CRYPTO_BUFFER)> ca_names(
3340 sk_CRYPTO_BUFFER_new_null());
3341 ASSERT_TRUE(ca_names);
David Benjamin2908dd12018-06-29 17:46:42 -04003342 ASSERT_TRUE(PushToStack(ca_names.get(), std::move(ca_name)));
David Benjamin71dfad42017-07-16 17:27:39 -04003343 SSL_CTX_set0_client_CAs(server_ctx.get(), ca_names.release());
3344
3345 // Configure client and server to accept all certificates.
3346 SSL_CTX_set_custom_verify(
3347 client_ctx.get(), SSL_VERIFY_PEER,
3348 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3349 return ssl_verify_ok;
3350 });
3351 SSL_CTX_set_custom_verify(
3352 server_ctx.get(), SSL_VERIFY_PEER,
3353 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3354 return ssl_verify_ok;
3355 });
3356
3357 bool cert_cb_called = false;
3358 SSL_CTX_set_cert_cb(
3359 client_ctx.get(),
3360 [](SSL *ssl, void *arg) -> int {
David Benjamin5f001d12018-05-08 16:46:48 -04003361 const STACK_OF(CRYPTO_BUFFER) *peer_names =
David Benjamin71dfad42017-07-16 17:27:39 -04003362 SSL_get0_server_requested_CAs(ssl);
3363 EXPECT_EQ(1u, sk_CRYPTO_BUFFER_num(peer_names));
3364 CRYPTO_BUFFER *peer_name = sk_CRYPTO_BUFFER_value(peer_names, 0);
3365 EXPECT_EQ(Bytes(kTestName), Bytes(CRYPTO_BUFFER_data(peer_name),
3366 CRYPTO_BUFFER_len(peer_name)));
3367 *reinterpret_cast<bool *>(arg) = true;
3368 return 1;
3369 },
3370 &cert_cb_called);
3371
3372 bssl::UniquePtr<SSL> client, server;
3373 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003374 server_ctx.get()));
David Benjamin71dfad42017-07-16 17:27:39 -04003375 EXPECT_TRUE(cert_cb_called);
3376}
3377
David Benjamin91222b82017-03-09 20:10:56 -05003378// Configuring the empty cipher list, though an error, should still modify the
3379// configuration.
3380TEST(SSLTest, EmptyCipherList) {
3381 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3382 ASSERT_TRUE(ctx);
3383
3384 // Initially, the cipher list is not empty.
3385 EXPECT_NE(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3386
3387 // Configuring the empty cipher list fails.
3388 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), ""));
3389 ERR_clear_error();
3390
3391 // But the cipher list is still updated to empty.
3392 EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3393}
3394
Adam Langley4c341d02017-03-08 19:33:21 -08003395// ssl_test_ticket_aead_failure_mode enumerates the possible ways in which the
3396// test |SSL_TICKET_AEAD_METHOD| can fail.
3397enum ssl_test_ticket_aead_failure_mode {
3398 ssl_test_ticket_aead_ok = 0,
3399 ssl_test_ticket_aead_seal_fail,
3400 ssl_test_ticket_aead_open_soft_fail,
3401 ssl_test_ticket_aead_open_hard_fail,
3402};
3403
3404struct ssl_test_ticket_aead_state {
3405 unsigned retry_count;
3406 ssl_test_ticket_aead_failure_mode failure_mode;
3407};
3408
3409static int ssl_test_ticket_aead_ex_index_dup(CRYPTO_EX_DATA *to,
3410 const CRYPTO_EX_DATA *from,
3411 void **from_d, int index,
3412 long argl, void *argp) {
3413 abort();
3414}
3415
3416static void ssl_test_ticket_aead_ex_index_free(void *parent, void *ptr,
3417 CRYPTO_EX_DATA *ad, int index,
3418 long argl, void *argp) {
3419 auto state = reinterpret_cast<ssl_test_ticket_aead_state*>(ptr);
3420 if (state == nullptr) {
3421 return;
3422 }
3423
3424 OPENSSL_free(state);
3425}
3426
3427static CRYPTO_once_t g_ssl_test_ticket_aead_ex_index_once = CRYPTO_ONCE_INIT;
3428static int g_ssl_test_ticket_aead_ex_index;
3429
3430static int ssl_test_ticket_aead_get_ex_index() {
3431 CRYPTO_once(&g_ssl_test_ticket_aead_ex_index_once, [] {
3432 g_ssl_test_ticket_aead_ex_index = SSL_get_ex_new_index(
3433 0, nullptr, nullptr, ssl_test_ticket_aead_ex_index_dup,
3434 ssl_test_ticket_aead_ex_index_free);
3435 });
3436 return g_ssl_test_ticket_aead_ex_index;
3437}
3438
3439static size_t ssl_test_ticket_aead_max_overhead(SSL *ssl) {
3440 return 1;
3441}
3442
3443static int ssl_test_ticket_aead_seal(SSL *ssl, uint8_t *out, size_t *out_len,
3444 size_t max_out_len, const uint8_t *in,
3445 size_t in_len) {
3446 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3447 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3448
3449 if (state->failure_mode == ssl_test_ticket_aead_seal_fail ||
3450 max_out_len < in_len + 1) {
3451 return 0;
3452 }
3453
3454 OPENSSL_memmove(out, in, in_len);
3455 out[in_len] = 0xff;
3456 *out_len = in_len + 1;
3457
3458 return 1;
3459}
3460
3461static ssl_ticket_aead_result_t ssl_test_ticket_aead_open(
3462 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len,
3463 const uint8_t *in, size_t in_len) {
3464 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3465 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3466
3467 if (state->retry_count > 0) {
3468 state->retry_count--;
3469 return ssl_ticket_aead_retry;
3470 }
3471
3472 switch (state->failure_mode) {
3473 case ssl_test_ticket_aead_ok:
3474 break;
3475 case ssl_test_ticket_aead_seal_fail:
3476 // If |seal| failed then there shouldn't be any ticket to try and
3477 // decrypt.
3478 abort();
3479 break;
3480 case ssl_test_ticket_aead_open_soft_fail:
3481 return ssl_ticket_aead_ignore_ticket;
3482 case ssl_test_ticket_aead_open_hard_fail:
3483 return ssl_ticket_aead_error;
3484 }
3485
3486 if (in_len == 0 || in[in_len - 1] != 0xff) {
3487 return ssl_ticket_aead_ignore_ticket;
3488 }
3489
3490 if (max_out_len < in_len - 1) {
3491 return ssl_ticket_aead_error;
3492 }
3493
3494 OPENSSL_memmove(out, in, in_len - 1);
3495 *out_len = in_len - 1;
3496 return ssl_ticket_aead_success;
3497}
3498
3499static const SSL_TICKET_AEAD_METHOD kSSLTestTicketMethod = {
3500 ssl_test_ticket_aead_max_overhead,
3501 ssl_test_ticket_aead_seal,
3502 ssl_test_ticket_aead_open,
3503};
3504
3505static void ConnectClientAndServerWithTicketMethod(
3506 bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
3507 SSL_CTX *client_ctx, SSL_CTX *server_ctx, unsigned retry_count,
3508 ssl_test_ticket_aead_failure_mode failure_mode, SSL_SESSION *session) {
3509 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
3510 ASSERT_TRUE(client);
3511 ASSERT_TRUE(server);
3512 SSL_set_connect_state(client.get());
3513 SSL_set_accept_state(server.get());
3514
3515 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3516 OPENSSL_malloc(sizeof(ssl_test_ticket_aead_state)));
3517 ASSERT_TRUE(state);
3518 OPENSSL_memset(state, 0, sizeof(ssl_test_ticket_aead_state));
3519 state->retry_count = retry_count;
3520 state->failure_mode = failure_mode;
3521
3522 ASSERT_TRUE(SSL_set_ex_data(server.get(), ssl_test_ticket_aead_get_ex_index(),
3523 state));
3524
3525 SSL_set_session(client.get(), session);
3526
3527 BIO *bio1, *bio2;
3528 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
3529
3530 // SSL_set_bio takes ownership.
3531 SSL_set_bio(client.get(), bio1, bio1);
3532 SSL_set_bio(server.get(), bio2, bio2);
3533
3534 if (CompleteHandshakes(client.get(), server.get())) {
3535 *out_client = std::move(client);
3536 *out_server = std::move(server);
3537 } else {
3538 out_client->reset();
3539 out_server->reset();
3540 }
3541}
3542
David Benjaminc9775322018-04-13 16:39:12 -04003543using TicketAEADMethodParam =
3544 testing::tuple<uint16_t, unsigned, ssl_test_ticket_aead_failure_mode>;
3545
Adam Langley4c341d02017-03-08 19:33:21 -08003546class TicketAEADMethodTest
David Benjaminc9775322018-04-13 16:39:12 -04003547 : public ::testing::TestWithParam<TicketAEADMethodParam> {};
Adam Langley4c341d02017-03-08 19:33:21 -08003548
3549TEST_P(TicketAEADMethodTest, Resume) {
3550 bssl::UniquePtr<X509> cert = GetTestCertificate();
3551 ASSERT_TRUE(cert);
3552 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3553 ASSERT_TRUE(key);
3554
3555 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
3556 ASSERT_TRUE(server_ctx);
3557 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
3558 ASSERT_TRUE(client_ctx);
3559
3560 const uint16_t version = testing::get<0>(GetParam());
3561 const unsigned retry_count = testing::get<1>(GetParam());
3562 const ssl_test_ticket_aead_failure_mode failure_mode =
3563 testing::get<2>(GetParam());
3564
3565 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3566 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3567 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), version));
3568 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), version));
3569 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), version));
3570 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), version));
3571
3572 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
3573 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
3574 SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
3575 SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
David Benjamin707af292017-03-10 17:47:18 -05003576 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langley4c341d02017-03-08 19:33:21 -08003577
3578 SSL_CTX_set_ticket_aead_method(server_ctx.get(), &kSSLTestTicketMethod);
3579
3580 bssl::UniquePtr<SSL> client, server;
3581 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3582 server_ctx.get(), retry_count,
3583 failure_mode, nullptr);
3584 switch (failure_mode) {
3585 case ssl_test_ticket_aead_ok:
3586 case ssl_test_ticket_aead_open_hard_fail:
3587 case ssl_test_ticket_aead_open_soft_fail:
3588 ASSERT_TRUE(client);
3589 break;
3590 case ssl_test_ticket_aead_seal_fail:
3591 EXPECT_FALSE(client);
3592 return;
3593 }
3594 EXPECT_FALSE(SSL_session_reused(client.get()));
3595 EXPECT_FALSE(SSL_session_reused(server.get()));
3596
Steven Valdez777a2392019-02-21 11:30:47 -05003597 ASSERT_TRUE(FlushNewSessionTickets(client.get(), server.get()));
David Benjamin707af292017-03-10 17:47:18 -05003598 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
Adam Langley4c341d02017-03-08 19:33:21 -08003599 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3600 server_ctx.get(), retry_count,
David Benjamin707af292017-03-10 17:47:18 -05003601 failure_mode, session.get());
Adam Langley4c341d02017-03-08 19:33:21 -08003602 switch (failure_mode) {
3603 case ssl_test_ticket_aead_ok:
3604 ASSERT_TRUE(client);
3605 EXPECT_TRUE(SSL_session_reused(client.get()));
3606 EXPECT_TRUE(SSL_session_reused(server.get()));
3607 break;
3608 case ssl_test_ticket_aead_seal_fail:
3609 abort();
3610 break;
3611 case ssl_test_ticket_aead_open_hard_fail:
3612 EXPECT_FALSE(client);
3613 break;
3614 case ssl_test_ticket_aead_open_soft_fail:
3615 ASSERT_TRUE(client);
3616 EXPECT_FALSE(SSL_session_reused(client.get()));
3617 EXPECT_FALSE(SSL_session_reused(server.get()));
3618 }
3619}
3620
David Benjaminc9775322018-04-13 16:39:12 -04003621std::string TicketAEADMethodParamToString(
3622 const testing::TestParamInfo<TicketAEADMethodParam> &params) {
3623 std::string ret = GetVersionName(std::get<0>(params.param));
3624 // GTest only allows alphanumeric characters and '_' in the parameter
3625 // string. Additionally filter out the 'v' to get "TLS13" over "TLSv13".
3626 for (auto it = ret.begin(); it != ret.end();) {
3627 if (*it == '.' || *it == 'v') {
3628 it = ret.erase(it);
3629 } else {
3630 ++it;
3631 }
3632 }
3633 char retry_count[256];
3634 snprintf(retry_count, sizeof(retry_count), "%d", std::get<1>(params.param));
3635 ret += "_";
3636 ret += retry_count;
3637 ret += "Retries_";
3638 switch (std::get<2>(params.param)) {
3639 case ssl_test_ticket_aead_ok:
3640 ret += "OK";
3641 break;
3642 case ssl_test_ticket_aead_seal_fail:
3643 ret += "SealFail";
3644 break;
3645 case ssl_test_ticket_aead_open_soft_fail:
3646 ret += "OpenSoftFail";
3647 break;
3648 case ssl_test_ticket_aead_open_hard_fail:
3649 ret += "OpenHardFail";
3650 break;
3651 }
3652 return ret;
3653}
3654
David Benjaminbe7006a2019-04-09 18:05:02 -05003655INSTANTIATE_TEST_SUITE_P(
Adam Langley4c341d02017-03-08 19:33:21 -08003656 TicketAEADMethodTests, TicketAEADMethodTest,
David Benjaminc9775322018-04-13 16:39:12 -04003657 testing::Combine(testing::Values(TLS1_2_VERSION, TLS1_3_VERSION),
3658 testing::Values(0, 1, 2),
3659 testing::Values(ssl_test_ticket_aead_ok,
3660 ssl_test_ticket_aead_seal_fail,
3661 ssl_test_ticket_aead_open_soft_fail,
3662 ssl_test_ticket_aead_open_hard_fail)),
3663 TicketAEADMethodParamToString);
Adam Langley4c341d02017-03-08 19:33:21 -08003664
David Benjaminca743582017-06-15 17:51:35 -04003665TEST(SSLTest, SelectNextProto) {
3666 uint8_t *result;
3667 uint8_t result_len;
3668
3669 // If there is an overlap, it should be returned.
3670 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3671 SSL_select_next_proto(&result, &result_len,
3672 (const uint8_t *)"\1a\2bb\3ccc", 9,
3673 (const uint8_t *)"\1x\1y\1a\1z", 8));
3674 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
3675
3676 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3677 SSL_select_next_proto(&result, &result_len,
3678 (const uint8_t *)"\1a\2bb\3ccc", 9,
3679 (const uint8_t *)"\1x\1y\2bb\1z", 9));
3680 EXPECT_EQ(Bytes("bb"), Bytes(result, result_len));
3681
3682 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3683 SSL_select_next_proto(&result, &result_len,
3684 (const uint8_t *)"\1a\2bb\3ccc", 9,
3685 (const uint8_t *)"\1x\1y\3ccc\1z", 10));
3686 EXPECT_EQ(Bytes("ccc"), Bytes(result, result_len));
3687
3688 // Peer preference order takes precedence over local.
3689 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3690 SSL_select_next_proto(&result, &result_len,
3691 (const uint8_t *)"\1a\2bb\3ccc", 9,
3692 (const uint8_t *)"\3ccc\2bb\1a", 9));
3693 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
3694
3695 // If there is no overlap, return the first local protocol.
3696 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
3697 SSL_select_next_proto(&result, &result_len,
3698 (const uint8_t *)"\1a\2bb\3ccc", 9,
3699 (const uint8_t *)"\1x\2yy\3zzz", 9));
3700 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
3701
3702 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
3703 SSL_select_next_proto(&result, &result_len, nullptr, 0,
3704 (const uint8_t *)"\1x\2yy\3zzz", 9));
3705 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
3706}
3707
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003708TEST(SSLTest, SealRecord) {
3709 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3710 server_ctx(SSL_CTX_new(TLS_method()));
3711 ASSERT_TRUE(client_ctx);
3712 ASSERT_TRUE(server_ctx);
3713
3714 bssl::UniquePtr<X509> cert = GetTestCertificate();
3715 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3716 ASSERT_TRUE(cert);
3717 ASSERT_TRUE(key);
3718 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3719 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3720
3721 bssl::UniquePtr<SSL> client, server;
3722 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003723 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003724
3725 const std::vector<uint8_t> record = {1, 2, 3, 4, 5};
3726 std::vector<uint8_t> prefix(
3727 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003728 body(record.size()),
3729 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003730 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3731 bssl::MakeSpan(body), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003732 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003733
3734 std::vector<uint8_t> sealed;
3735 sealed.insert(sealed.end(), prefix.begin(), prefix.end());
3736 sealed.insert(sealed.end(), body.begin(), body.end());
3737 sealed.insert(sealed.end(), suffix.begin(), suffix.end());
3738 std::vector<uint8_t> sealed_copy = sealed;
3739
3740 bssl::Span<uint8_t> plaintext;
3741 size_t record_len;
3742 uint8_t alert = 255;
3743 EXPECT_EQ(bssl::OpenRecord(server.get(), &plaintext, &record_len, &alert,
3744 bssl::MakeSpan(sealed)),
3745 bssl::OpenRecordResult::kOK);
3746 EXPECT_EQ(record_len, sealed.size());
3747 EXPECT_EQ(plaintext, record);
3748 EXPECT_EQ(255, alert);
3749}
3750
3751TEST(SSLTest, SealRecordInPlace) {
3752 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3753 server_ctx(SSL_CTX_new(TLS_method()));
3754 ASSERT_TRUE(client_ctx);
3755 ASSERT_TRUE(server_ctx);
3756
3757 bssl::UniquePtr<X509> cert = GetTestCertificate();
3758 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3759 ASSERT_TRUE(cert);
3760 ASSERT_TRUE(key);
3761 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3762 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3763
3764 bssl::UniquePtr<SSL> client, server;
3765 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003766 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003767
3768 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
3769 std::vector<uint8_t> record = plaintext;
3770 std::vector<uint8_t> prefix(
3771 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003772 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003773 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3774 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003775 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003776 record.insert(record.begin(), prefix.begin(), prefix.end());
3777 record.insert(record.end(), suffix.begin(), suffix.end());
3778
3779 bssl::Span<uint8_t> result;
3780 size_t record_len;
3781 uint8_t alert;
3782 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
3783 bssl::MakeSpan(record)),
3784 bssl::OpenRecordResult::kOK);
3785 EXPECT_EQ(record_len, record.size());
3786 EXPECT_EQ(plaintext, result);
3787}
3788
3789TEST(SSLTest, SealRecordTrailingData) {
3790 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3791 server_ctx(SSL_CTX_new(TLS_method()));
3792 ASSERT_TRUE(client_ctx);
3793 ASSERT_TRUE(server_ctx);
3794
3795 bssl::UniquePtr<X509> cert = GetTestCertificate();
3796 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3797 ASSERT_TRUE(cert);
3798 ASSERT_TRUE(key);
3799 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3800 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3801
3802 bssl::UniquePtr<SSL> client, server;
3803 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003804 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003805
3806 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
3807 std::vector<uint8_t> record = plaintext;
3808 std::vector<uint8_t> prefix(
3809 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003810 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003811 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3812 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003813 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003814 record.insert(record.begin(), prefix.begin(), prefix.end());
3815 record.insert(record.end(), suffix.begin(), suffix.end());
3816 record.insert(record.end(), {5, 4, 3, 2, 1});
3817
3818 bssl::Span<uint8_t> result;
3819 size_t record_len;
3820 uint8_t alert;
3821 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
3822 bssl::MakeSpan(record)),
3823 bssl::OpenRecordResult::kOK);
3824 EXPECT_EQ(record_len, record.size() - 5);
3825 EXPECT_EQ(plaintext, result);
3826}
3827
3828TEST(SSLTest, SealRecordInvalidSpanSize) {
3829 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3830 server_ctx(SSL_CTX_new(TLS_method()));
3831 ASSERT_TRUE(client_ctx);
3832 ASSERT_TRUE(server_ctx);
3833
3834 bssl::UniquePtr<X509> cert = GetTestCertificate();
3835 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3836 ASSERT_TRUE(cert);
3837 ASSERT_TRUE(key);
3838 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3839 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3840
3841 bssl::UniquePtr<SSL> client, server;
3842 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003843 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003844
3845 std::vector<uint8_t> record = {1, 2, 3, 4, 5};
3846 std::vector<uint8_t> prefix(
3847 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003848 body(record.size()),
3849 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003850
3851 auto expect_err = []() {
3852 int err = ERR_get_error();
3853 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
3854 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_BUFFER_TOO_SMALL);
3855 ERR_clear_error();
3856 };
3857 EXPECT_FALSE(bssl::SealRecord(
3858 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003859 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003860 expect_err();
3861 EXPECT_FALSE(bssl::SealRecord(
3862 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003863 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003864 expect_err();
3865
3866 EXPECT_FALSE(
3867 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3868 bssl::MakeSpan(record.data(), record.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003869 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003870 expect_err();
3871 EXPECT_FALSE(
3872 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3873 bssl::MakeSpan(record.data(), record.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003874 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003875 expect_err();
3876
3877 EXPECT_FALSE(bssl::SealRecord(
3878 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003879 bssl::MakeSpan(suffix.data(), suffix.size() - 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003880 expect_err();
3881 EXPECT_FALSE(bssl::SealRecord(
3882 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003883 bssl::MakeSpan(suffix.data(), suffix.size() + 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003884 expect_err();
3885}
3886
David Benjamin617b8182017-08-29 15:33:10 -04003887// The client should gracefully handle no suitable ciphers being enabled.
3888TEST(SSLTest, NoCiphersAvailable) {
3889 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3890 ASSERT_TRUE(ctx);
3891
3892 // Configure |client_ctx| with a cipher list that does not intersect with its
3893 // version configuration.
3894 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
3895 ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
3896 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
3897
3898 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3899 ASSERT_TRUE(ssl);
3900 SSL_set_connect_state(ssl.get());
3901
3902 UniquePtr<BIO> rbio(BIO_new(BIO_s_mem())), wbio(BIO_new(BIO_s_mem()));
3903 ASSERT_TRUE(rbio);
3904 ASSERT_TRUE(wbio);
3905 SSL_set0_rbio(ssl.get(), rbio.release());
3906 SSL_set0_wbio(ssl.get(), wbio.release());
3907
3908 int ret = SSL_do_handshake(ssl.get());
3909 EXPECT_EQ(-1, ret);
3910 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), ret));
3911 uint32_t err = ERR_get_error();
3912 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
3913 EXPECT_EQ(SSL_R_NO_CIPHERS_AVAILABLE, ERR_GET_REASON(err));
3914}
3915
David Benjamina4bafd32017-10-03 15:06:29 -04003916TEST_P(SSLVersionTest, SessionVersion) {
3917 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3918 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3919
3920 bssl::UniquePtr<SSL_SESSION> session =
3921 CreateClientSession(client_ctx_.get(), server_ctx_.get());
3922 ASSERT_TRUE(session);
3923 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
3924
3925 // Sessions in TLS 1.3 and later should be single-use.
3926 EXPECT_EQ(version() == TLS1_3_VERSION,
3927 !!SSL_SESSION_should_be_single_use(session.get()));
3928
3929 // Making fake sessions for testing works.
3930 session.reset(SSL_SESSION_new(client_ctx_.get()));
3931 ASSERT_TRUE(session);
3932 ASSERT_TRUE(SSL_SESSION_set_protocol_version(session.get(), version()));
3933 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
3934}
3935
David Benjaminfdb7a352017-10-12 17:34:18 -04003936TEST_P(SSLVersionTest, SSLPending) {
3937 UniquePtr<SSL> ssl(SSL_new(client_ctx_.get()));
3938 ASSERT_TRUE(ssl);
3939 EXPECT_EQ(0, SSL_pending(ssl.get()));
3940
3941 ASSERT_TRUE(Connect());
3942 EXPECT_EQ(0, SSL_pending(client_.get()));
3943
3944 ASSERT_EQ(5, SSL_write(server_.get(), "hello", 5));
3945 ASSERT_EQ(5, SSL_write(server_.get(), "world", 5));
3946 EXPECT_EQ(0, SSL_pending(client_.get()));
3947
3948 char buf[10];
3949 ASSERT_EQ(1, SSL_peek(client_.get(), buf, 1));
3950 EXPECT_EQ(5, SSL_pending(client_.get()));
3951
3952 ASSERT_EQ(1, SSL_read(client_.get(), buf, 1));
3953 EXPECT_EQ(4, SSL_pending(client_.get()));
3954
3955 ASSERT_EQ(4, SSL_read(client_.get(), buf, 10));
3956 EXPECT_EQ(0, SSL_pending(client_.get()));
3957
3958 ASSERT_EQ(2, SSL_read(client_.get(), buf, 2));
3959 EXPECT_EQ(3, SSL_pending(client_.get()));
3960}
3961
David Benjamina031b612017-10-11 20:48:25 -04003962// Test that post-handshake tickets consumed by |SSL_shutdown| are ignored.
3963TEST(SSLTest, ShutdownIgnoresTickets) {
3964 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3965 ASSERT_TRUE(ctx);
3966 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_3_VERSION));
3967 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
3968
3969 bssl::UniquePtr<X509> cert = GetTestCertificate();
3970 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3971 ASSERT_TRUE(cert);
3972 ASSERT_TRUE(key);
3973 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
3974 ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
3975
3976 SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_BOTH);
3977
3978 bssl::UniquePtr<SSL> client, server;
3979 ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
3980
3981 SSL_CTX_sess_set_new_cb(ctx.get(), [](SSL *ssl, SSL_SESSION *session) -> int {
3982 ADD_FAILURE() << "New session callback called during SSL_shutdown";
3983 return 0;
3984 });
3985
3986 // Send close_notify.
3987 EXPECT_EQ(0, SSL_shutdown(server.get()));
3988 EXPECT_EQ(0, SSL_shutdown(client.get()));
3989
3990 // Receive close_notify.
3991 EXPECT_EQ(1, SSL_shutdown(server.get()));
3992 EXPECT_EQ(1, SSL_shutdown(client.get()));
3993}
3994
David Benjamin6cc352e2017-11-02 17:21:39 -04003995TEST(SSLTest, SignatureAlgorithmProperties) {
3996 EXPECT_EQ(EVP_PKEY_NONE, SSL_get_signature_algorithm_key_type(0x1234));
3997 EXPECT_EQ(nullptr, SSL_get_signature_algorithm_digest(0x1234));
3998 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(0x1234));
3999
4000 EXPECT_EQ(EVP_PKEY_RSA,
4001 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4002 EXPECT_EQ(EVP_md5_sha1(),
4003 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4004 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
4005
4006 EXPECT_EQ(EVP_PKEY_EC, SSL_get_signature_algorithm_key_type(
4007 SSL_SIGN_ECDSA_SECP256R1_SHA256));
4008 EXPECT_EQ(EVP_sha256(), SSL_get_signature_algorithm_digest(
4009 SSL_SIGN_ECDSA_SECP256R1_SHA256));
4010 EXPECT_FALSE(
4011 SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_ECDSA_SECP256R1_SHA256));
4012
4013 EXPECT_EQ(EVP_PKEY_RSA,
David Benjamin6879e192018-04-13 16:01:02 -04004014 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04004015 EXPECT_EQ(EVP_sha384(),
David Benjamin6879e192018-04-13 16:01:02 -04004016 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PSS_RSAE_SHA384));
4017 EXPECT_TRUE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04004018}
4019
Adam Langley85967952018-07-03 08:04:58 -07004020static int XORCompressFunc(SSL *ssl, CBB *out, const uint8_t *in,
4021 size_t in_len) {
4022 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07004023 if (!CBB_add_u8(out, in[i] ^ 0x55)) {
Adam Langley85967952018-07-03 08:04:58 -07004024 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07004025 }
4026 }
4027
4028 SSL_set_app_data(ssl, XORCompressFunc);
4029
Adam Langley85967952018-07-03 08:04:58 -07004030 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07004031}
4032
Adam Langley85967952018-07-03 08:04:58 -07004033static int XORDecompressFunc(SSL *ssl, CRYPTO_BUFFER **out,
4034 size_t uncompressed_len, const uint8_t *in,
4035 size_t in_len) {
4036 if (in_len != uncompressed_len) {
4037 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07004038 }
4039
4040 uint8_t *data;
Adam Langley85967952018-07-03 08:04:58 -07004041 *out = CRYPTO_BUFFER_alloc(&data, uncompressed_len);
4042 if (*out == nullptr) {
4043 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07004044 }
4045
Adam Langley85967952018-07-03 08:04:58 -07004046 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07004047 data[i] = in[i] ^ 0x55;
4048 }
4049
4050 SSL_set_app_data(ssl, XORDecompressFunc);
4051
Adam Langley85967952018-07-03 08:04:58 -07004052 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07004053}
4054
4055TEST(SSLTest, CertCompression) {
4056 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4057 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4058 ASSERT_TRUE(client_ctx);
4059 ASSERT_TRUE(server_ctx);
4060
4061 bssl::UniquePtr<X509> cert = GetTestCertificate();
4062 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4063 ASSERT_TRUE(cert);
4064 ASSERT_TRUE(key);
4065 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
4066 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
4067
4068 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
4069 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
4070 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
4071 client_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
4072 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
4073 server_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
4074
4075 bssl::UniquePtr<SSL> client, server;
4076 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4077 server_ctx.get()));
4078
4079 EXPECT_TRUE(SSL_get_app_data(client.get()) == XORDecompressFunc);
4080 EXPECT_TRUE(SSL_get_app_data(server.get()) == XORCompressFunc);
4081}
4082
Adam Langleyddb57cf2018-01-26 09:17:53 -08004083void MoveBIOs(SSL *dest, SSL *src) {
4084 BIO *rbio = SSL_get_rbio(src);
4085 BIO_up_ref(rbio);
4086 SSL_set0_rbio(dest, rbio);
4087
4088 BIO *wbio = SSL_get_wbio(src);
4089 BIO_up_ref(wbio);
4090 SSL_set0_wbio(dest, wbio);
4091
4092 SSL_set0_rbio(src, nullptr);
4093 SSL_set0_wbio(src, nullptr);
4094}
4095
4096TEST(SSLTest, Handoff) {
4097 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4098 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4099 bssl::UniquePtr<SSL_CTX> handshaker_ctx(SSL_CTX_new(TLS_method()));
4100 ASSERT_TRUE(client_ctx);
4101 ASSERT_TRUE(server_ctx);
4102 ASSERT_TRUE(handshaker_ctx);
4103
4104 SSL_CTX_set_handoff_mode(server_ctx.get(), 1);
4105 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
4106 ASSERT_TRUE(
4107 SSL_CTX_set_max_proto_version(handshaker_ctx.get(), TLS1_2_VERSION));
4108
4109 bssl::UniquePtr<X509> cert = GetTestCertificate();
4110 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4111 ASSERT_TRUE(cert);
4112 ASSERT_TRUE(key);
4113 ASSERT_TRUE(SSL_CTX_use_certificate(handshaker_ctx.get(), cert.get()));
4114 ASSERT_TRUE(SSL_CTX_use_PrivateKey(handshaker_ctx.get(), key.get()));
4115
4116 bssl::UniquePtr<SSL> client, server;
4117 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4118 server_ctx.get(), ClientConfig(),
4119 false /* don't handshake */));
4120
4121 int client_ret = SSL_do_handshake(client.get());
4122 int client_err = SSL_get_error(client.get(), client_ret);
4123 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4124
4125 int server_ret = SSL_do_handshake(server.get());
4126 int server_err = SSL_get_error(server.get(), server_ret);
4127 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
4128
4129 ScopedCBB cbb;
4130 Array<uint8_t> handoff;
Adam Langleyc9827e02019-04-12 14:46:50 -07004131 SSL_CLIENT_HELLO hello;
Adam Langleyddb57cf2018-01-26 09:17:53 -08004132 ASSERT_TRUE(CBB_init(cbb.get(), 256));
Adam Langleyc9827e02019-04-12 14:46:50 -07004133 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004134 ASSERT_TRUE(CBBFinishArray(cbb.get(), &handoff));
4135
4136 bssl::UniquePtr<SSL> handshaker(SSL_new(handshaker_ctx.get()));
4137 ASSERT_TRUE(SSL_apply_handoff(handshaker.get(), handoff));
4138
4139 MoveBIOs(handshaker.get(), server.get());
4140
4141 int handshake_ret = SSL_do_handshake(handshaker.get());
4142 int handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
Matthew Braithwaite56986f92018-03-22 11:48:33 -07004143 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
Adam Langleyddb57cf2018-01-26 09:17:53 -08004144
Matthew Braithwaite56986f92018-03-22 11:48:33 -07004145 // Double-check that additional calls to |SSL_do_handshake| continue
4146 // to get |SSL_ERRROR_HANDBACK|.
4147 handshake_ret = SSL_do_handshake(handshaker.get());
4148 handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
4149 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
Adam Langleyddb57cf2018-01-26 09:17:53 -08004150
4151 ScopedCBB cbb_handback;
4152 Array<uint8_t> handback;
4153 ASSERT_TRUE(CBB_init(cbb_handback.get(), 1024));
4154 ASSERT_TRUE(SSL_serialize_handback(handshaker.get(), cbb_handback.get()));
4155 ASSERT_TRUE(CBBFinishArray(cbb_handback.get(), &handback));
4156
4157 bssl::UniquePtr<SSL> server2(SSL_new(server_ctx.get()));
4158 ASSERT_TRUE(SSL_apply_handback(server2.get(), handback));
4159
4160 MoveBIOs(server2.get(), handshaker.get());
Matthew Braithwaite56986f92018-03-22 11:48:33 -07004161 ASSERT_TRUE(CompleteHandshakes(client.get(), server2.get()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004162
4163 uint8_t byte = 42;
4164 EXPECT_EQ(SSL_write(client.get(), &byte, 1), 1);
4165 EXPECT_EQ(SSL_read(server2.get(), &byte, 1), 1);
4166 EXPECT_EQ(42, byte);
4167
4168 byte = 43;
4169 EXPECT_EQ(SSL_write(server2.get(), &byte, 1), 1);
4170 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
4171 EXPECT_EQ(43, byte);
4172}
4173
4174TEST(SSLTest, HandoffDeclined) {
4175 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4176 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4177 ASSERT_TRUE(client_ctx);
4178 ASSERT_TRUE(server_ctx);
4179
4180 SSL_CTX_set_handoff_mode(server_ctx.get(), 1);
4181 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
4182
4183 bssl::UniquePtr<X509> cert = GetTestCertificate();
4184 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4185 ASSERT_TRUE(cert);
4186 ASSERT_TRUE(key);
4187 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
4188 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
4189
4190 bssl::UniquePtr<SSL> client, server;
4191 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4192 server_ctx.get(), ClientConfig(),
4193 false /* don't handshake */));
4194
4195 int client_ret = SSL_do_handshake(client.get());
4196 int client_err = SSL_get_error(client.get(), client_ret);
4197 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4198
4199 int server_ret = SSL_do_handshake(server.get());
4200 int server_err = SSL_get_error(server.get(), server_ret);
4201 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
4202
4203 ScopedCBB cbb;
Adam Langleyc9827e02019-04-12 14:46:50 -07004204 SSL_CLIENT_HELLO hello;
Adam Langleyddb57cf2018-01-26 09:17:53 -08004205 ASSERT_TRUE(CBB_init(cbb.get(), 256));
Adam Langleyc9827e02019-04-12 14:46:50 -07004206 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004207
4208 ASSERT_TRUE(SSL_decline_handoff(server.get()));
4209
4210 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
4211
4212 uint8_t byte = 42;
4213 EXPECT_EQ(SSL_write(client.get(), &byte, 1), 1);
4214 EXPECT_EQ(SSL_read(server.get(), &byte, 1), 1);
4215 EXPECT_EQ(42, byte);
4216
4217 byte = 43;
4218 EXPECT_EQ(SSL_write(server.get(), &byte, 1), 1);
4219 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
4220 EXPECT_EQ(43, byte);
4221}
4222
Adam Langley826ce152018-08-03 10:31:21 -07004223static std::string SigAlgsToString(Span<const uint16_t> sigalgs) {
4224 std::string ret = "{";
4225
4226 for (uint16_t v : sigalgs) {
4227 if (ret.size() > 1) {
4228 ret += ", ";
4229 }
4230
4231 char buf[8];
4232 snprintf(buf, sizeof(buf) - 1, "0x%02x", v);
4233 buf[sizeof(buf)-1] = 0;
4234 ret += std::string(buf);
4235 }
4236
4237 ret += "}";
4238 return ret;
4239}
4240
4241void ExpectSigAlgsEqual(Span<const uint16_t> expected,
4242 Span<const uint16_t> actual) {
4243 bool matches = false;
4244 if (expected.size() == actual.size()) {
4245 matches = true;
4246
4247 for (size_t i = 0; i < expected.size(); i++) {
4248 if (expected[i] != actual[i]) {
4249 matches = false;
4250 break;
4251 }
4252 }
4253 }
4254
4255 if (!matches) {
4256 ADD_FAILURE() << "expected: " << SigAlgsToString(expected)
4257 << " got: " << SigAlgsToString(actual);
4258 }
4259}
4260
4261TEST(SSLTest, SigAlgs) {
4262 static const struct {
4263 std::vector<int> input;
4264 bool ok;
4265 std::vector<uint16_t> expected;
4266 } kTests[] = {
4267 {{}, true, {}},
4268 {{1}, false, {}},
4269 {{1, 2, 3}, false, {}},
4270 {{NID_sha256, EVP_PKEY_ED25519}, false, {}},
4271 {{NID_sha256, EVP_PKEY_RSA, NID_sha256, EVP_PKEY_RSA}, false, {}},
4272
4273 {{NID_sha256, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA256}},
4274 {{NID_sha512, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA512}},
4275 {{NID_sha256, EVP_PKEY_RSA_PSS}, true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4276 {{NID_undef, EVP_PKEY_ED25519}, true, {SSL_SIGN_ED25519}},
4277 {{NID_undef, EVP_PKEY_ED25519, NID_sha384, EVP_PKEY_EC},
4278 true,
4279 {SSL_SIGN_ED25519, SSL_SIGN_ECDSA_SECP384R1_SHA384}},
4280 };
4281
4282 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4283
4284 unsigned n = 1;
4285 for (const auto &test : kTests) {
4286 SCOPED_TRACE(n++);
4287
4288 const bool ok =
4289 SSL_CTX_set1_sigalgs(ctx.get(), test.input.data(), test.input.size());
4290 EXPECT_EQ(ok, test.ok);
4291
4292 if (!ok) {
4293 ERR_clear_error();
4294 }
4295
4296 if (!test.ok) {
4297 continue;
4298 }
4299
4300 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
4301 }
4302}
4303
4304TEST(SSLTest, SigAlgsList) {
4305 static const struct {
4306 const char *input;
4307 bool ok;
4308 std::vector<uint16_t> expected;
4309 } kTests[] = {
4310 {"", false, {}},
4311 {":", false, {}},
4312 {"+", false, {}},
4313 {"RSA", false, {}},
4314 {"RSA+", false, {}},
4315 {"RSA+SHA256:", false, {}},
4316 {":RSA+SHA256:", false, {}},
4317 {":RSA+SHA256+:", false, {}},
4318 {"!", false, {}},
4319 {"\x01", false, {}},
4320 {"RSA+SHA256:RSA+SHA384:RSA+SHA256", false, {}},
4321 {"RSA-PSS+SHA256:rsa_pss_rsae_sha256", false, {}},
4322
4323 {"RSA+SHA256", true, {SSL_SIGN_RSA_PKCS1_SHA256}},
4324 {"RSA+SHA256:ed25519",
4325 true,
4326 {SSL_SIGN_RSA_PKCS1_SHA256, SSL_SIGN_ED25519}},
4327 {"ECDSA+SHA256:RSA+SHA512",
4328 true,
4329 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PKCS1_SHA512}},
4330 {"ecdsa_secp256r1_sha256:rsa_pss_rsae_sha256",
4331 true,
4332 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4333 {"RSA-PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4334 {"PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4335 };
4336
4337 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4338
4339 unsigned n = 1;
4340 for (const auto &test : kTests) {
4341 SCOPED_TRACE(n++);
4342
4343 const bool ok = SSL_CTX_set1_sigalgs_list(ctx.get(), test.input);
4344 EXPECT_EQ(ok, test.ok);
4345
4346 if (!ok) {
4347 if (test.ok) {
4348 ERR_print_errors_fp(stderr);
4349 }
4350 ERR_clear_error();
4351 }
4352
4353 if (!test.ok) {
4354 continue;
4355 }
4356
4357 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
4358 }
4359}
4360
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004361TEST(SSLTest, ApplyHandoffRemovesUnsupportedCiphers) {
4362 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4363 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
4364
4365 // handoff is a handoff message that has been artificially modified to pretend
4366 // that only cipher 0x0A is supported. When it is applied to |server|, all
4367 // ciphers but that one should be removed.
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004368 //
4369 // To make a new one of these, try sticking this in the |Handoff| test above:
4370 //
4371 // hexdump(stderr, "", handoff.data(), handoff.size());
4372 // sed -e 's/\(..\)/0x\1, /g'
4373 //
4374 // and modify serialize_features() to emit only cipher 0x0A.
4375
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004376 uint8_t handoff[] = {
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004377 0x30, 0x81, 0x9a, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
4378 0x00, 0x00, 0x7e, 0x03, 0x03, 0x30, 0x8e, 0x8f, 0x79, 0xd2, 0x87, 0x39,
4379 0xc2, 0x23, 0x23, 0x13, 0xca, 0x3c, 0x80, 0x44, 0xfd, 0x80, 0x83, 0x62,
4380 0x3c, 0xcc, 0xf8, 0x76, 0xd3, 0x62, 0xbb, 0x54, 0xe3, 0xc4, 0x39, 0x24,
4381 0xa5, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004382 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
4383 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004384 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
4385 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
4386 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
4387 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
4388 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x02, 0x00,
4389 0x0a, 0x04, 0x0a, 0x00, 0x15, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00,
4390 0x1d,
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07004391 };
4392
4393 EXPECT_EQ(20u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
4394 ASSERT_TRUE(
4395 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
4396 EXPECT_EQ(1u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
4397}
4398
Matthew Braithwaitec65eb2c2018-11-02 17:29:35 -07004399TEST(SSLTest, ApplyHandoffRemovesUnsupportedCurves) {
4400 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4401 bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
4402
4403 // handoff is a handoff message that has been artificially modified to pretend
4404 // that only one curve is supported. When it is applied to |server|, all
4405 // curves but that one should be removed.
4406 //
4407 // See |ApplyHandoffRemovesUnsupportedCiphers| for how to make a new one of
4408 // these.
4409 uint8_t handoff[] = {
4410 0x30, 0x81, 0xc0, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
4411 0x00, 0x00, 0x7e, 0x03, 0x03, 0x98, 0x30, 0xce, 0xd9, 0xb0, 0xdf, 0x5f,
4412 0x82, 0x05, 0x4a, 0x43, 0x67, 0x7e, 0xdb, 0x6a, 0x4f, 0x21, 0x18, 0x4e,
4413 0x0d, 0x94, 0x63, 0x18, 0x8b, 0x54, 0x89, 0xdb, 0x8b, 0x1d, 0x84, 0xbc,
4414 0x09, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
4415 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
4416 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
4417 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
4418 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
4419 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
4420 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
4421 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x30, 0x00,
4422 0x02, 0x00, 0x0a, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x8c, 0x00, 0x8d, 0x00,
4423 0x9c, 0x00, 0x9d, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xc0, 0x09, 0xc0,
4424 0x0a, 0xc0, 0x13, 0xc0, 0x14, 0xc0, 0x2b, 0xc0, 0x2c, 0xc0, 0x2f, 0xc0,
4425 0x30, 0xc0, 0x35, 0xc0, 0x36, 0xcc, 0xa8, 0xcc, 0xa9, 0xcc, 0xac, 0x04,
4426 0x02, 0x00, 0x17,
4427 };
4428
4429 // The zero length means that the default list of groups is used.
4430 EXPECT_EQ(0u, server->config->supported_group_list.size());
4431 ASSERT_TRUE(
4432 SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
4433 EXPECT_EQ(1u, server->config->supported_group_list.size());
4434}
4435
Adam Langleyba9ad662018-12-17 13:59:38 -08004436TEST(SSLTest, ZeroSizedWiteFlushesHandshakeMessages) {
4437 // If there are pending handshake mesages, an |SSL_write| of zero bytes should
4438 // flush them.
4439 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4440 EXPECT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
4441 EXPECT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
4442 bssl::UniquePtr<X509> cert = GetTestCertificate();
4443 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4444 ASSERT_TRUE(cert);
4445 ASSERT_TRUE(key);
4446 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
4447 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
4448
4449 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4450 EXPECT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
4451 EXPECT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
4452
4453 bssl::UniquePtr<SSL> client, server;
4454 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4455 server_ctx.get()));
4456
4457 BIO *client_wbio = SSL_get_wbio(client.get());
4458 EXPECT_EQ(0u, BIO_wpending(client_wbio));
4459 EXPECT_TRUE(SSL_key_update(client.get(), SSL_KEY_UPDATE_NOT_REQUESTED));
4460 EXPECT_EQ(0u, BIO_wpending(client_wbio));
4461 EXPECT_EQ(0, SSL_write(client.get(), nullptr, 0));
4462 EXPECT_NE(0u, BIO_wpending(client_wbio));
4463}
4464
David Benjamin5869eb32018-07-17 00:59:45 -04004465TEST_P(SSLVersionTest, VerifyBeforeCertRequest) {
4466 // Configure the server to request client certificates.
4467 SSL_CTX_set_custom_verify(
4468 server_ctx_.get(), SSL_VERIFY_PEER,
4469 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
4470
4471 // Configure the client to reject the server certificate.
4472 SSL_CTX_set_custom_verify(
4473 client_ctx_.get(), SSL_VERIFY_PEER,
4474 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_invalid; });
4475
4476 // cert_cb should not be called. Verification should fail first.
4477 SSL_CTX_set_cert_cb(client_ctx_.get(),
4478 [](SSL *ssl, void *arg) {
4479 ADD_FAILURE() << "cert_cb unexpectedly called";
4480 return 0;
4481 },
4482 nullptr);
4483
4484 bssl::UniquePtr<SSL> client, server;
4485 EXPECT_FALSE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
4486 server_ctx_.get()));
4487}
4488
David Benjamin492c9aa2018-08-31 16:35:22 -05004489// Test that ticket-based sessions on the client get fake session IDs.
4490TEST_P(SSLVersionTest, FakeIDsForTickets) {
4491 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4492 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4493
4494 bssl::UniquePtr<SSL_SESSION> session =
4495 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4496 ASSERT_TRUE(session);
4497
4498 EXPECT_TRUE(SSL_SESSION_has_ticket(session.get()));
4499 unsigned session_id_length;
4500 SSL_SESSION_get_id(session.get(), &session_id_length);
4501 EXPECT_NE(session_id_length, 0u);
4502}
4503
David Benjamin6c04bd12018-07-19 18:13:09 -04004504// These tests test multi-threaded behavior. They are intended to run with
4505// ThreadSanitizer.
David Benjamin5b33eff2018-09-22 16:52:48 -07004506#if defined(OPENSSL_THREADS)
David Benjamin6c04bd12018-07-19 18:13:09 -04004507TEST_P(SSLVersionTest, SessionCacheThreads) {
4508 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
4509 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4510 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4511
4512 if (version() == TLS1_3_VERSION) {
4513 // Our TLS 1.3 implementation does not support stateful resumption.
4514 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
4515 return;
4516 }
4517
4518 // Establish two client sessions to test with.
4519 bssl::UniquePtr<SSL_SESSION> session1 =
4520 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4521 ASSERT_TRUE(session1);
4522 bssl::UniquePtr<SSL_SESSION> session2 =
4523 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4524 ASSERT_TRUE(session2);
4525
4526 auto connect_with_session = [&](SSL_SESSION *session) {
4527 ClientConfig config;
4528 config.session = session;
4529 UniquePtr<SSL> client, server;
4530 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
4531 server_ctx_.get(), config));
4532 };
4533
4534 // Resume sessions in parallel with establishing new ones.
4535 {
4536 std::vector<std::thread> threads;
4537 threads.emplace_back([&] { connect_with_session(nullptr); });
4538 threads.emplace_back([&] { connect_with_session(nullptr); });
4539 threads.emplace_back([&] { connect_with_session(session1.get()); });
4540 threads.emplace_back([&] { connect_with_session(session1.get()); });
4541 threads.emplace_back([&] { connect_with_session(session2.get()); });
4542 threads.emplace_back([&] { connect_with_session(session2.get()); });
4543 for (auto &thread : threads) {
4544 thread.join();
4545 }
4546 }
4547
4548 // Hit the maximum session cache size across multiple threads
4549 size_t limit = SSL_CTX_sess_number(server_ctx_.get()) + 2;
4550 SSL_CTX_sess_set_cache_size(server_ctx_.get(), limit);
4551 {
4552 std::vector<std::thread> threads;
4553 for (int i = 0; i < 4; i++) {
4554 threads.emplace_back([&]() {
4555 connect_with_session(nullptr);
4556 EXPECT_LE(SSL_CTX_sess_number(server_ctx_.get()), limit);
4557 });
4558 }
4559 for (auto &thread : threads) {
4560 thread.join();
4561 }
4562 EXPECT_EQ(SSL_CTX_sess_number(server_ctx_.get()), limit);
4563 }
4564}
4565
4566TEST_P(SSLVersionTest, SessionTicketThreads) {
4567 for (bool renew_ticket : {false, true}) {
4568 SCOPED_TRACE(renew_ticket);
4569 ResetContexts();
4570 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4571 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4572 if (renew_ticket) {
4573 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
4574 }
4575
4576 // Establish two client sessions to test with.
4577 bssl::UniquePtr<SSL_SESSION> session1 =
4578 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4579 ASSERT_TRUE(session1);
4580 bssl::UniquePtr<SSL_SESSION> session2 =
4581 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4582 ASSERT_TRUE(session2);
4583
4584 auto connect_with_session = [&](SSL_SESSION *session) {
4585 ClientConfig config;
4586 config.session = session;
4587 UniquePtr<SSL> client, server;
4588 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
4589 server_ctx_.get(), config));
4590 };
4591
4592 // Resume sessions in parallel with establishing new ones.
4593 {
4594 std::vector<std::thread> threads;
4595 threads.emplace_back([&] { connect_with_session(nullptr); });
4596 threads.emplace_back([&] { connect_with_session(nullptr); });
4597 threads.emplace_back([&] { connect_with_session(session1.get()); });
4598 threads.emplace_back([&] { connect_with_session(session1.get()); });
4599 threads.emplace_back([&] { connect_with_session(session2.get()); });
4600 threads.emplace_back([&] { connect_with_session(session2.get()); });
4601 for (auto &thread : threads) {
4602 thread.join();
4603 }
4604 }
4605 }
4606}
4607
4608// SSL_CTX_get0_certificate needs to lock internally. Test this works.
4609TEST(SSLTest, GetCertificateThreads) {
4610 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4611 ASSERT_TRUE(ctx);
4612 bssl::UniquePtr<X509> cert = GetTestCertificate();
4613 ASSERT_TRUE(cert);
4614 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
4615
4616 // Existing code expects |SSL_CTX_get0_certificate| to be callable from two
4617 // threads concurrently. It originally was an immutable operation. Now we
4618 // implement it with a thread-safe cache, so it is worth testing.
4619 X509 *cert2_thread;
4620 std::thread thread(
4621 [&] { cert2_thread = SSL_CTX_get0_certificate(ctx.get()); });
4622 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
4623 thread.join();
4624
4625 EXPECT_EQ(cert2, cert2_thread);
4626 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
4627}
David Benjamin4cce9552018-12-13 12:20:54 -06004628
4629// Functions which access properties on the negotiated session are thread-safe
4630// where needed. Prior to TLS 1.3, clients resuming sessions and servers
4631// performing stateful resumption will share an underlying SSL_SESSION object,
4632// potentially across threads.
4633TEST_P(SSLVersionTest, SessionPropertiesThreads) {
4634 if (version() == TLS1_3_VERSION) {
4635 // Our TLS 1.3 implementation does not support stateful resumption.
4636 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
4637 return;
4638 }
4639
4640 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
4641 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4642 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4643
4644 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
4645 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
4646
4647 // Configure mutual authentication, so we have more session state.
4648 SSL_CTX_set_custom_verify(
4649 client_ctx_.get(), SSL_VERIFY_PEER,
4650 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
4651 SSL_CTX_set_custom_verify(
4652 server_ctx_.get(), SSL_VERIFY_PEER,
4653 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
4654
4655 // Establish a client session to test with.
4656 bssl::UniquePtr<SSL_SESSION> session =
4657 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4658 ASSERT_TRUE(session);
4659
4660 // Resume with it twice.
4661 UniquePtr<SSL> ssls[4];
4662 ClientConfig config;
4663 config.session = session.get();
4664 ASSERT_TRUE(ConnectClientAndServer(&ssls[0], &ssls[1], client_ctx_.get(),
4665 server_ctx_.get(), config));
4666 ASSERT_TRUE(ConnectClientAndServer(&ssls[2], &ssls[3], client_ctx_.get(),
4667 server_ctx_.get(), config));
4668
4669 // Read properties in parallel.
4670 auto read_properties = [](const SSL *ssl) {
4671 EXPECT_TRUE(SSL_get_peer_cert_chain(ssl));
4672 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(ssl));
4673 EXPECT_TRUE(peer);
4674 EXPECT_TRUE(SSL_get_current_cipher(ssl));
4675 EXPECT_TRUE(SSL_get_curve_id(ssl));
4676 };
4677
4678 std::vector<std::thread> threads;
4679 for (const auto &ssl_ptr : ssls) {
4680 const SSL *ssl = ssl_ptr.get();
4681 threads.emplace_back([=] { read_properties(ssl); });
4682 }
4683 for (auto &thread : threads) {
4684 thread.join();
4685 }
4686}
David Benjamina486c6c2019-03-28 18:32:38 -05004687#endif // OPENSSL_THREADS
David Benjamin6c04bd12018-07-19 18:13:09 -04004688
Steven Valdezc8e0f902018-07-14 11:23:01 -04004689constexpr size_t kNumQUICLevels = 4;
4690static_assert(ssl_encryption_initial < kNumQUICLevels,
4691 "kNumQUICLevels is wrong");
4692static_assert(ssl_encryption_early_data < kNumQUICLevels,
4693 "kNumQUICLevels is wrong");
4694static_assert(ssl_encryption_handshake < kNumQUICLevels,
4695 "kNumQUICLevels is wrong");
4696static_assert(ssl_encryption_application < kNumQUICLevels,
4697 "kNumQUICLevels is wrong");
4698
4699class MockQUICTransport {
4700 public:
4701 MockQUICTransport() {
4702 // The caller is expected to configure initial secrets.
4703 levels_[ssl_encryption_initial].write_secret = {1};
4704 levels_[ssl_encryption_initial].read_secret = {1};
4705 }
4706
4707 void set_peer(MockQUICTransport *peer) { peer_ = peer; }
4708
4709 bool has_alert() const { return has_alert_; }
4710 ssl_encryption_level_t alert_level() const { return alert_level_; }
4711 uint8_t alert() const { return alert_; }
4712
4713 bool PeerSecretsMatch(ssl_encryption_level_t level) const {
4714 return levels_[level].write_secret == peer_->levels_[level].read_secret &&
Steven Valdez384d0ea2018-11-06 10:45:36 -05004715 levels_[level].read_secret == peer_->levels_[level].write_secret &&
4716 levels_[level].cipher == peer_->levels_[level].cipher;
Steven Valdezc8e0f902018-07-14 11:23:01 -04004717 }
4718
4719 bool HasSecrets(ssl_encryption_level_t level) const {
4720 return !levels_[level].write_secret.empty() ||
4721 !levels_[level].read_secret.empty();
4722 }
4723
4724 bool SetEncryptionSecrets(ssl_encryption_level_t level,
4725 const uint8_t *read_secret,
Steven Valdez384d0ea2018-11-06 10:45:36 -05004726 const uint8_t *write_secret, size_t secret_len,
4727 const SSL_CIPHER *cipher) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04004728 if (HasSecrets(level)) {
4729 ADD_FAILURE() << "duplicate keys configured";
4730 return false;
4731 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05004732
4733 if (cipher == nullptr) {
4734 ADD_FAILURE() << "current cipher unavailable";
4735 return false;
4736 }
4737
Steven Valdezc8e0f902018-07-14 11:23:01 -04004738 if (level != ssl_encryption_early_data &&
4739 (read_secret == nullptr || write_secret == nullptr)) {
4740 ADD_FAILURE() << "key was unexpectedly null";
4741 return false;
4742 }
4743 if (read_secret != nullptr) {
4744 levels_[level].read_secret.assign(read_secret, read_secret + secret_len);
4745 }
4746 if (write_secret != nullptr) {
4747 levels_[level].write_secret.assign(write_secret,
4748 write_secret + secret_len);
4749 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05004750 levels_[level].cipher = SSL_CIPHER_get_id(cipher);
Steven Valdezc8e0f902018-07-14 11:23:01 -04004751 return true;
4752 }
4753
4754 bool WriteHandshakeData(ssl_encryption_level_t level,
4755 Span<const uint8_t> data) {
4756 if (levels_[level].write_secret.empty()) {
4757 ADD_FAILURE() << "data written before keys configured";
4758 return false;
4759 }
4760 levels_[level].write_data.insert(levels_[level].write_data.end(),
4761 data.begin(), data.end());
4762 return true;
4763 }
4764
4765 bool SendAlert(ssl_encryption_level_t level, uint8_t alert_value) {
4766 if (has_alert_) {
4767 ADD_FAILURE() << "duplicate alert sent";
4768 return false;
4769 }
4770
4771 if (levels_[level].write_secret.empty()) {
4772 ADD_FAILURE() << "alert sent before keys configured";
4773 return false;
4774 }
4775
4776 has_alert_ = true;
4777 alert_level_ = level;
4778 alert_ = alert_value;
4779 return true;
4780 }
4781
4782 bool ReadHandshakeData(std::vector<uint8_t> *out,
4783 ssl_encryption_level_t level,
4784 size_t num = std::numeric_limits<size_t>::max()) {
4785 if (levels_[level].read_secret.empty()) {
4786 ADD_FAILURE() << "data read before keys configured";
4787 return false;
4788 }
4789 // The peer may not have configured any keys yet.
4790 if (peer_->levels_[level].write_secret.empty()) {
4791 return true;
4792 }
4793 // Check the peer computed the same key.
4794 if (peer_->levels_[level].write_secret != levels_[level].read_secret) {
4795 ADD_FAILURE() << "peer write key does not match read key";
4796 return false;
4797 }
Steven Valdez384d0ea2018-11-06 10:45:36 -05004798 if (peer_->levels_[level].cipher != levels_[level].cipher) {
4799 ADD_FAILURE() << "peer cipher does not match";
4800 return false;
4801 }
Steven Valdezc8e0f902018-07-14 11:23:01 -04004802 std::vector<uint8_t> *peer_data = &peer_->levels_[level].write_data;
4803 num = std::min(num, peer_data->size());
4804 out->assign(peer_data->begin(), peer_data->begin() + num);
4805 peer_data->erase(peer_data->begin(), peer_data->begin() + num);
4806 return true;
4807 }
4808
4809 private:
4810 MockQUICTransport *peer_ = nullptr;
4811
4812 bool has_alert_ = false;
4813 ssl_encryption_level_t alert_level_ = ssl_encryption_initial;
4814 uint8_t alert_ = 0;
4815
4816 struct Level {
4817 std::vector<uint8_t> write_data;
4818 std::vector<uint8_t> write_secret;
4819 std::vector<uint8_t> read_secret;
Steven Valdez384d0ea2018-11-06 10:45:36 -05004820 uint32_t cipher = 0;
Steven Valdezc8e0f902018-07-14 11:23:01 -04004821 };
4822 Level levels_[kNumQUICLevels];
4823};
4824
4825class MockQUICTransportPair {
4826 public:
4827 MockQUICTransportPair() {
4828 server_.set_peer(&client_);
4829 client_.set_peer(&server_);
4830 }
4831
4832 ~MockQUICTransportPair() {
4833 server_.set_peer(nullptr);
4834 client_.set_peer(nullptr);
4835 }
4836
4837 MockQUICTransport *client() { return &client_; }
4838 MockQUICTransport *server() { return &server_; }
4839
4840 bool SecretsMatch(ssl_encryption_level_t level) const {
4841 return client_.PeerSecretsMatch(level);
4842 }
4843
4844 private:
4845 MockQUICTransport client_;
4846 MockQUICTransport server_;
4847};
4848
4849class QUICMethodTest : public testing::Test {
4850 protected:
4851 void SetUp() override {
4852 client_ctx_.reset(SSL_CTX_new(TLS_method()));
4853 server_ctx_.reset(SSL_CTX_new(TLS_method()));
4854 ASSERT_TRUE(client_ctx_);
4855 ASSERT_TRUE(server_ctx_);
4856
4857 bssl::UniquePtr<X509> cert = GetTestCertificate();
4858 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4859 ASSERT_TRUE(cert);
4860 ASSERT_TRUE(key);
4861 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx_.get(), cert.get()));
4862 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx_.get(), key.get()));
4863
4864 SSL_CTX_set_min_proto_version(server_ctx_.get(), TLS1_3_VERSION);
4865 SSL_CTX_set_max_proto_version(server_ctx_.get(), TLS1_3_VERSION);
4866 SSL_CTX_set_min_proto_version(client_ctx_.get(), TLS1_3_VERSION);
4867 SSL_CTX_set_max_proto_version(client_ctx_.get(), TLS1_3_VERSION);
4868 }
4869
4870 static MockQUICTransport *TransportFromSSL(const SSL *ssl) {
4871 return ex_data_.Get(ssl);
4872 }
4873
4874 static bool ProvideHandshakeData(
4875 SSL *ssl, size_t num = std::numeric_limits<size_t>::max()) {
4876 MockQUICTransport *transport = TransportFromSSL(ssl);
4877 ssl_encryption_level_t level = SSL_quic_read_level(ssl);
4878 std::vector<uint8_t> data;
4879 return transport->ReadHandshakeData(&data, level, num) &&
4880 SSL_provide_quic_data(ssl, level, data.data(), data.size());
4881 }
4882
4883 bool CreateClientAndServer() {
4884 client_.reset(SSL_new(client_ctx_.get()));
4885 server_.reset(SSL_new(server_ctx_.get()));
4886 if (!client_ || !server_) {
4887 return false;
4888 }
4889
4890 SSL_set_connect_state(client_.get());
4891 SSL_set_accept_state(server_.get());
4892
4893 ex_data_.Set(client_.get(), transport_.client());
4894 ex_data_.Set(server_.get(), transport_.server());
4895 return true;
4896 }
4897
Steven Valdeze6eef1c2018-11-09 13:32:34 -05004898 bool CreateSecondClientAndServer() {
4899 client_.reset(SSL_new(client_ctx_.get()));
4900 server_.reset(SSL_new(server_ctx_.get()));
4901 if (!client_ || !server_) {
4902 return false;
4903 }
4904
4905 SSL_set_connect_state(client_.get());
4906 SSL_set_accept_state(server_.get());
4907
4908 ex_data_.Set(client_.get(), second_transport_.client());
4909 ex_data_.Set(server_.get(), second_transport_.server());
4910 return true;
4911 }
4912
Steven Valdezc8e0f902018-07-14 11:23:01 -04004913 // The following functions may be configured on an |SSL_QUIC_METHOD| as
4914 // default implementations.
4915
4916 static int SetEncryptionSecretsCallback(SSL *ssl,
4917 ssl_encryption_level_t level,
4918 const uint8_t *read_key,
4919 const uint8_t *write_key,
4920 size_t key_len) {
Steven Valdez384d0ea2018-11-06 10:45:36 -05004921 return TransportFromSSL(ssl)->SetEncryptionSecrets(
4922 level, read_key, write_key, key_len, SSL_get_current_cipher(ssl));
Steven Valdezc8e0f902018-07-14 11:23:01 -04004923 }
4924
David Benjamincc9d9352018-10-30 19:45:22 -05004925 static int AddHandshakeDataCallback(SSL *ssl,
4926 enum ssl_encryption_level_t level,
4927 const uint8_t *data, size_t len) {
Steven Valdezc8e0f902018-07-14 11:23:01 -04004928 EXPECT_EQ(level, SSL_quic_write_level(ssl));
4929 return TransportFromSSL(ssl)->WriteHandshakeData(level,
4930 MakeConstSpan(data, len));
4931 }
4932
4933 static int FlushFlightCallback(SSL *ssl) { return 1; }
4934
4935 static int SendAlertCallback(SSL *ssl, ssl_encryption_level_t level,
4936 uint8_t alert) {
4937 EXPECT_EQ(level, SSL_quic_write_level(ssl));
4938 return TransportFromSSL(ssl)->SendAlert(level, alert);
4939 }
4940
4941 bssl::UniquePtr<SSL_CTX> client_ctx_;
4942 bssl::UniquePtr<SSL_CTX> server_ctx_;
4943
4944 static UnownedSSLExData<MockQUICTransport> ex_data_;
4945 MockQUICTransportPair transport_;
Steven Valdeze6eef1c2018-11-09 13:32:34 -05004946 MockQUICTransportPair second_transport_;
Steven Valdezc8e0f902018-07-14 11:23:01 -04004947
4948 bssl::UniquePtr<SSL> client_;
4949 bssl::UniquePtr<SSL> server_;
4950};
4951
4952UnownedSSLExData<MockQUICTransport> QUICMethodTest::ex_data_;
4953
4954// Test a full handshake works.
4955TEST_F(QUICMethodTest, Basic) {
4956 const SSL_QUIC_METHOD quic_method = {
4957 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05004958 AddHandshakeDataCallback,
Steven Valdezc8e0f902018-07-14 11:23:01 -04004959 FlushFlightCallback,
4960 SendAlertCallback,
4961 };
4962
Steven Valdeze6eef1c2018-11-09 13:32:34 -05004963 g_last_session = nullptr;
4964
4965 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4966 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
Steven Valdezc8e0f902018-07-14 11:23:01 -04004967 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
4968 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
4969 ASSERT_TRUE(CreateClientAndServer());
4970
4971 for (;;) {
4972 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
4973 int client_ret = SSL_do_handshake(client_.get());
4974 if (client_ret != 1) {
4975 ASSERT_EQ(client_ret, -1);
4976 ASSERT_EQ(SSL_get_error(client_.get(), client_ret), SSL_ERROR_WANT_READ);
4977 }
4978
4979 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
4980 int server_ret = SSL_do_handshake(server_.get());
4981 if (server_ret != 1) {
4982 ASSERT_EQ(server_ret, -1);
4983 ASSERT_EQ(SSL_get_error(server_.get(), server_ret), SSL_ERROR_WANT_READ);
4984 }
4985
4986 if (client_ret == 1 && server_ret == 1) {
4987 break;
4988 }
4989 }
4990
4991 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
4992 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
4993 EXPECT_TRUE(transport_.SecretsMatch(ssl_encryption_application));
4994 EXPECT_FALSE(transport_.client()->has_alert());
4995 EXPECT_FALSE(transport_.server()->has_alert());
4996
4997 // The server sent NewSessionTicket messages in the handshake.
Steven Valdeze6eef1c2018-11-09 13:32:34 -05004998 EXPECT_FALSE(g_last_session);
4999 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5000 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
5001 EXPECT_TRUE(g_last_session);
5002
5003 // Create a second connection to verify resumption works.
5004 ASSERT_TRUE(CreateSecondClientAndServer());
5005 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
5006 SSL_set_session(client_.get(), session.get());
5007
5008 for (;;) {
5009 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5010 int client_ret = SSL_do_handshake(client_.get());
5011 if (client_ret != 1) {
5012 ASSERT_EQ(client_ret, -1);
5013 ASSERT_EQ(SSL_get_error(client_.get(), client_ret), SSL_ERROR_WANT_READ);
5014 }
5015
5016 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5017 int server_ret = SSL_do_handshake(server_.get());
5018 if (server_ret != 1) {
5019 ASSERT_EQ(server_ret, -1);
5020 ASSERT_EQ(SSL_get_error(server_.get(), server_ret), SSL_ERROR_WANT_READ);
5021 }
5022
5023 if (client_ret == 1 && server_ret == 1) {
5024 break;
5025 }
5026 }
5027
5028 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
5029 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
5030 EXPECT_TRUE(transport_.SecretsMatch(ssl_encryption_application));
5031 EXPECT_FALSE(transport_.client()->has_alert());
5032 EXPECT_FALSE(transport_.server()->has_alert());
5033 EXPECT_TRUE(SSL_session_reused(client_.get()));
5034 EXPECT_TRUE(SSL_session_reused(server_.get()));
Steven Valdezc8e0f902018-07-14 11:23:01 -04005035}
5036
5037// Test only releasing data to QUIC one byte at a time on request, to maximize
5038// state machine pauses. Additionally, test that existing asynchronous callbacks
5039// still work.
5040TEST_F(QUICMethodTest, Async) {
5041 const SSL_QUIC_METHOD quic_method = {
5042 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05005043 AddHandshakeDataCallback,
Steven Valdezc8e0f902018-07-14 11:23:01 -04005044 FlushFlightCallback,
5045 SendAlertCallback,
5046 };
5047
5048 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5049 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5050 ASSERT_TRUE(CreateClientAndServer());
5051
5052 // Install an asynchronous certificate callback.
5053 bool cert_cb_ok = false;
5054 SSL_set_cert_cb(server_.get(),
5055 [](SSL *, void *arg) -> int {
5056 return *static_cast<bool *>(arg) ? 1 : -1;
5057 },
5058 &cert_cb_ok);
5059
5060 for (;;) {
5061 int client_ret = SSL_do_handshake(client_.get());
5062 if (client_ret != 1) {
5063 ASSERT_EQ(client_ret, -1);
5064 ASSERT_EQ(SSL_get_error(client_.get(), client_ret), SSL_ERROR_WANT_READ);
5065 ASSERT_TRUE(ProvideHandshakeData(client_.get(), 1));
5066 }
5067
5068 int server_ret = SSL_do_handshake(server_.get());
5069 if (server_ret != 1) {
5070 ASSERT_EQ(server_ret, -1);
5071 int ssl_err = SSL_get_error(server_.get(), server_ret);
5072 switch (ssl_err) {
5073 case SSL_ERROR_WANT_READ:
5074 ASSERT_TRUE(ProvideHandshakeData(server_.get(), 1));
5075 break;
5076 case SSL_ERROR_WANT_X509_LOOKUP:
5077 ASSERT_FALSE(cert_cb_ok);
5078 cert_cb_ok = true;
5079 break;
5080 default:
5081 FAIL() << "Unexpected SSL_get_error result: " << ssl_err;
5082 }
5083 }
5084
5085 if (client_ret == 1 && server_ret == 1) {
5086 break;
5087 }
5088 }
5089
5090 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
5091 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
5092 EXPECT_TRUE(transport_.SecretsMatch(ssl_encryption_application));
5093 EXPECT_FALSE(transport_.client()->has_alert());
5094 EXPECT_FALSE(transport_.server()->has_alert());
5095}
5096
5097// Test buffering write data until explicit flushes.
5098TEST_F(QUICMethodTest, Buffered) {
5099 struct BufferedFlight {
5100 std::vector<uint8_t> data[kNumQUICLevels];
5101 };
5102 static UnownedSSLExData<BufferedFlight> buffered_flights;
5103
David Benjamincc9d9352018-10-30 19:45:22 -05005104 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
5105 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005106 BufferedFlight *flight = buffered_flights.Get(ssl);
5107 flight->data[level].insert(flight->data[level].end(), data, data + len);
5108 return 1;
5109 };
5110
5111 auto flush_flight = [](SSL *ssl) -> int {
5112 BufferedFlight *flight = buffered_flights.Get(ssl);
5113 for (size_t level = 0; level < kNumQUICLevels; level++) {
5114 if (!flight->data[level].empty()) {
5115 if (!TransportFromSSL(ssl)->WriteHandshakeData(
5116 static_cast<ssl_encryption_level_t>(level),
5117 flight->data[level])) {
5118 return 0;
5119 }
5120 flight->data[level].clear();
5121 }
5122 }
5123 return 1;
5124 };
5125
5126 const SSL_QUIC_METHOD quic_method = {
5127 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05005128 add_handshake_data,
Steven Valdezc8e0f902018-07-14 11:23:01 -04005129 flush_flight,
5130 SendAlertCallback,
5131 };
5132
5133 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5134 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5135 ASSERT_TRUE(CreateClientAndServer());
5136
5137 BufferedFlight client_flight, server_flight;
5138 buffered_flights.Set(client_.get(), &client_flight);
5139 buffered_flights.Set(server_.get(), &server_flight);
5140
5141 for (;;) {
5142 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5143 int client_ret = SSL_do_handshake(client_.get());
5144 if (client_ret != 1) {
5145 ASSERT_EQ(client_ret, -1);
5146 ASSERT_EQ(SSL_get_error(client_.get(), client_ret), SSL_ERROR_WANT_READ);
5147 }
5148
5149 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5150 int server_ret = SSL_do_handshake(server_.get());
5151 if (server_ret != 1) {
5152 ASSERT_EQ(server_ret, -1);
5153 ASSERT_EQ(SSL_get_error(server_.get(), server_ret), SSL_ERROR_WANT_READ);
5154 }
5155
5156 if (client_ret == 1 && server_ret == 1) {
5157 break;
5158 }
5159 }
5160
5161 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
5162 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
5163 EXPECT_TRUE(transport_.SecretsMatch(ssl_encryption_application));
5164 EXPECT_FALSE(transport_.client()->has_alert());
5165 EXPECT_FALSE(transport_.server()->has_alert());
5166}
5167
5168// Test that excess data at one level is rejected. That is, if a single
5169// |SSL_provide_quic_data| call included both ServerHello and
5170// EncryptedExtensions in a single chunk, BoringSSL notices and rejects this on
5171// key change.
5172TEST_F(QUICMethodTest, ExcessProvidedData) {
David Benjamincc9d9352018-10-30 19:45:22 -05005173 auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
5174 const uint8_t *data, size_t len) -> int {
Steven Valdezc8e0f902018-07-14 11:23:01 -04005175 // Switch everything to the initial level.
5176 return TransportFromSSL(ssl)->WriteHandshakeData(ssl_encryption_initial,
5177 MakeConstSpan(data, len));
5178 };
5179
5180 const SSL_QUIC_METHOD quic_method = {
5181 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05005182 add_handshake_data,
Steven Valdezc8e0f902018-07-14 11:23:01 -04005183 FlushFlightCallback,
5184 SendAlertCallback,
5185 };
5186
5187 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5188 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5189 ASSERT_TRUE(CreateClientAndServer());
5190
5191 // Send the ClientHello and ServerHello through Finished.
5192 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5193 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
5194 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5195 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
5196 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
5197
5198 // The client is still waiting for the ServerHello at initial
5199 // encryption.
5200 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
5201
David Benjamincc9d9352018-10-30 19:45:22 -05005202 // |add_handshake_data| incorrectly wrote everything at the initial level, so
5203 // this queues up ServerHello through Finished in one chunk.
Steven Valdezc8e0f902018-07-14 11:23:01 -04005204 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5205
5206 // The client reads ServerHello successfully, but then rejects the buffered
5207 // EncryptedExtensions on key change.
5208 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5209 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_SSL);
5210 uint32_t err = ERR_get_error();
5211 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
5212 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_BUFFERED_MESSAGES_ON_CIPHER_CHANGE);
5213
5214 // The client sends an alert in response to this.
5215 ASSERT_TRUE(transport_.client()->has_alert());
5216 EXPECT_EQ(transport_.client()->alert_level(), ssl_encryption_initial);
5217 EXPECT_EQ(transport_.client()->alert(), SSL_AD_UNEXPECTED_MESSAGE);
5218
5219 // Sanity-check client did get far enough to process the ServerHello and
5220 // install keys.
5221 EXPECT_TRUE(transport_.client()->HasSecrets(ssl_encryption_handshake));
5222}
5223
5224// Test that |SSL_provide_quic_data| will reject data at the wrong level.
5225TEST_F(QUICMethodTest, ProvideWrongLevel) {
5226 const SSL_QUIC_METHOD quic_method = {
5227 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05005228 AddHandshakeDataCallback,
Steven Valdezc8e0f902018-07-14 11:23:01 -04005229 FlushFlightCallback,
5230 SendAlertCallback,
5231 };
5232
5233 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5234 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5235 ASSERT_TRUE(CreateClientAndServer());
5236
5237 // Send the ClientHello and ServerHello through Finished.
5238 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5239 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
5240 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5241 ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
5242 ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
5243
5244 // The client is still waiting for the ServerHello at initial
5245 // encryption.
5246 ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
5247
5248 // Data cannot be provided at the next level.
5249 std::vector<uint8_t> data;
5250 ASSERT_TRUE(
5251 transport_.client()->ReadHandshakeData(&data, ssl_encryption_initial));
5252 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_handshake,
5253 data.data(), data.size()));
5254 ERR_clear_error();
5255
5256 // Progress to EncryptedExtensions.
5257 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
5258 data.data(), data.size()));
5259 ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
5260 ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
5261 ASSERT_EQ(ssl_encryption_handshake, SSL_quic_read_level(client_.get()));
5262
5263 // Data cannot be provided at the previous level.
5264 ASSERT_TRUE(
5265 transport_.client()->ReadHandshakeData(&data, ssl_encryption_handshake));
5266 ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
5267 data.data(), data.size()));
5268}
5269
5270TEST_F(QUICMethodTest, TooMuchData) {
5271 const SSL_QUIC_METHOD quic_method = {
5272 SetEncryptionSecretsCallback,
David Benjamincc9d9352018-10-30 19:45:22 -05005273 AddHandshakeDataCallback,
Steven Valdezc8e0f902018-07-14 11:23:01 -04005274 FlushFlightCallback,
5275 SendAlertCallback,
5276 };
5277
5278 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5279 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5280 ASSERT_TRUE(CreateClientAndServer());
5281
5282 size_t limit =
5283 SSL_quic_max_handshake_flight_len(client_.get(), ssl_encryption_initial);
5284 uint8_t b = 0;
5285 for (size_t i = 0; i < limit; i++) {
5286 ASSERT_TRUE(
5287 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
5288 }
5289
5290 EXPECT_FALSE(
5291 SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
5292}
5293
Steven Valdeze6eef1c2018-11-09 13:32:34 -05005294// Provide invalid post-handshake data.
5295TEST_F(QUICMethodTest, BadPostHandshake) {
5296 const SSL_QUIC_METHOD quic_method = {
5297 SetEncryptionSecretsCallback,
5298 AddHandshakeDataCallback,
5299 FlushFlightCallback,
5300 SendAlertCallback,
5301 };
5302
5303 g_last_session = nullptr;
5304
5305 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5306 SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
5307 ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
5308 ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
5309 ASSERT_TRUE(CreateClientAndServer());
5310
5311 for (;;) {
5312 ASSERT_TRUE(ProvideHandshakeData(client_.get()));
5313 int client_ret = SSL_do_handshake(client_.get());
5314 if (client_ret != 1) {
5315 ASSERT_EQ(client_ret, -1);
5316 ASSERT_EQ(SSL_get_error(client_.get(), client_ret), SSL_ERROR_WANT_READ);
5317 }
5318
5319 ASSERT_TRUE(ProvideHandshakeData(server_.get()));
5320 int server_ret = SSL_do_handshake(server_.get());
5321 if (server_ret != 1) {
5322 ASSERT_EQ(server_ret, -1);
5323 ASSERT_EQ(SSL_get_error(server_.get(), server_ret), SSL_ERROR_WANT_READ);
5324 }
5325
5326 if (client_ret == 1 && server_ret == 1) {
5327 break;
5328 }
5329 }
5330
5331 EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
5332 EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
5333 EXPECT_TRUE(transport_.SecretsMatch(ssl_encryption_application));
5334 EXPECT_FALSE(transport_.client()->has_alert());
5335 EXPECT_FALSE(transport_.server()->has_alert());
5336
5337 // Junk sent as part of post-handshake data should cause an error.
5338 uint8_t kJunk[] = {0x17, 0x0, 0x0, 0x4, 0xB, 0xE, 0xE, 0xF};
5339 ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_application,
5340 kJunk, sizeof(kJunk)));
5341 EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 0);
5342}
5343
Adam Langley7540cc22019-04-18 09:56:13 -07005344extern "C" {
5345int BORINGSSL_enum_c_type_test(void);
5346}
5347
5348TEST(SSLTest, EnumTypes) {
5349 EXPECT_EQ(sizeof(int), sizeof(ssl_private_key_result_t));
5350 EXPECT_EQ(1, BORINGSSL_enum_c_type_test());
5351}
5352
David Benjaminb29e1e12019-05-06 14:44:46 -05005353TEST_P(SSLVersionTest, DoubleSSLError) {
5354 // Connect the inner SSL connections.
5355 ASSERT_TRUE(Connect());
5356
5357 // Make a pair of |BIO|s which wrap |client_| and |server_|.
5358 UniquePtr<BIO_METHOD> bio_method(BIO_meth_new(0, nullptr));
5359 ASSERT_TRUE(bio_method);
5360 ASSERT_TRUE(BIO_meth_set_read(
5361 bio_method.get(), [](BIO *bio, char *out, int len) -> int {
5362 SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
5363 int ret = SSL_read(ssl, out, len);
5364 int ssl_ret = SSL_get_error(ssl, ret);
5365 if (ssl_ret == SSL_ERROR_WANT_READ) {
5366 BIO_set_retry_read(bio);
5367 }
5368 return ret;
5369 }));
5370 ASSERT_TRUE(BIO_meth_set_write(
5371 bio_method.get(), [](BIO *bio, const char *in, int len) -> int {
5372 SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
5373 int ret = SSL_write(ssl, in, len);
5374 int ssl_ret = SSL_get_error(ssl, ret);
5375 if (ssl_ret == SSL_ERROR_WANT_WRITE) {
5376 BIO_set_retry_write(bio);
5377 }
5378 return ret;
5379 }));
5380 ASSERT_TRUE(BIO_meth_set_ctrl(
5381 bio_method.get(), [](BIO *bio, int cmd, long larg, void *parg) -> long {
5382 // |SSL| objects require |BIO_flush| support.
5383 if (cmd == BIO_CTRL_FLUSH) {
5384 return 1;
5385 }
5386 return 0;
5387 }));
5388
5389 UniquePtr<BIO> client_bio(BIO_new(bio_method.get()));
5390 ASSERT_TRUE(client_bio);
5391 BIO_set_data(client_bio.get(), client_.get());
5392 BIO_set_init(client_bio.get(), 1);
5393
5394 UniquePtr<BIO> server_bio(BIO_new(bio_method.get()));
5395 ASSERT_TRUE(server_bio);
5396 BIO_set_data(server_bio.get(), server_.get());
5397 BIO_set_init(server_bio.get(), 1);
5398
5399 // Wrap the inner connections in another layer of SSL.
5400 UniquePtr<SSL> client_outer(SSL_new(client_ctx_.get()));
5401 ASSERT_TRUE(client_outer);
5402 SSL_set_connect_state(client_outer.get());
5403 SSL_set_bio(client_outer.get(), client_bio.get(), client_bio.get());
5404 client_bio.release(); // |SSL_set_bio| takes ownership.
5405
5406 UniquePtr<SSL> server_outer(SSL_new(server_ctx_.get()));
5407 ASSERT_TRUE(server_outer);
5408 SSL_set_accept_state(server_outer.get());
5409 SSL_set_bio(server_outer.get(), server_bio.get(), server_bio.get());
5410 server_bio.release(); // |SSL_set_bio| takes ownership.
5411
5412 // Configure |client_outer| to reject the server certificate.
5413 SSL_set_custom_verify(
5414 client_outer.get(), SSL_VERIFY_PEER,
5415 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
5416 return ssl_verify_invalid;
5417 });
5418
5419 for (;;) {
5420 int client_ret = SSL_do_handshake(client_outer.get());
5421 int client_err = SSL_get_error(client_outer.get(), client_ret);
5422 if (client_err != SSL_ERROR_WANT_READ &&
5423 client_err != SSL_ERROR_WANT_WRITE) {
5424 // The client handshake should terminate on a certificate verification
5425 // error.
5426 EXPECT_EQ(SSL_ERROR_SSL, client_err);
5427 uint32_t err = ERR_peek_error();
5428 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
5429 EXPECT_EQ(SSL_R_CERTIFICATE_VERIFY_FAILED, ERR_GET_REASON(err));
5430 break;
5431 }
5432
5433 // Run the server handshake and continue.
5434 int server_ret = SSL_do_handshake(server_outer.get());
5435 int server_err = SSL_get_error(server_outer.get(), server_ret);
5436 ASSERT_TRUE(server_err == SSL_ERROR_NONE ||
5437 server_err == SSL_ERROR_WANT_READ ||
5438 server_err == SSL_ERROR_WANT_WRITE);
5439 }
5440}
5441
Martin Kreichgauer72912d22017-08-04 12:06:43 -07005442} // namespace
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -07005443BSSL_NAMESPACE_END