blob: a2a53f63173510a22e474ec7a58807083e386ce2 [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>
David Benjamin1d77e562015-03-22 17:22:08 -040020#include <string>
David Benjamin4f6acaf2015-11-21 03:00:50 -050021#include <utility>
David Benjamin1d77e562015-03-22 17:22:08 -040022#include <vector>
23
David Benjamin96628432017-01-19 19:05:47 -050024#include <gtest/gtest.h>
25
David Benjamin751e8892014-10-19 00:59:36 -040026#include <openssl/base64.h>
27#include <openssl/bio.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040028#include <openssl/cipher.h>
David Benjamin7a1eefd2015-10-17 23:39:22 -040029#include <openssl/crypto.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040030#include <openssl/err.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040031#include <openssl/hmac.h>
David Benjaminde942382016-02-11 12:02:01 -050032#include <openssl/pem.h>
David Benjamin25490f22016-07-14 00:22:54 -040033#include <openssl/sha.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040034#include <openssl/ssl.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040035#include <openssl/rand.h>
David Benjaminde942382016-02-11 12:02:01 -050036#include <openssl/x509.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040037
Steven Valdez87eab492016-06-27 16:34:59 -040038#include "internal.h"
Steven Valdezcb966542016-08-17 16:56:14 -040039#include "../crypto/internal.h"
Sigbjorn Vik2b23d242015-06-29 15:07:26 +020040#include "../crypto/test/test_util.h"
41
David Benjamin721e8b72016-08-03 13:13:17 -040042#if defined(OPENSSL_WINDOWS)
David Benjaminc11ea9422017-08-29 16:33:21 -040043// Windows defines struct timeval in winsock2.h.
David Benjamin721e8b72016-08-03 13:13:17 -040044OPENSSL_MSVC_PRAGMA(warning(push, 3))
45#include <winsock2.h>
46OPENSSL_MSVC_PRAGMA(warning(pop))
47#else
48#include <sys/time.h>
49#endif
50
David Benjamin1d77e562015-03-22 17:22:08 -040051
Martin Kreichgauer72912d22017-08-04 12:06:43 -070052namespace bssl {
53
54namespace {
55
Martin Kreichgauer1a663262017-08-16 14:54:04 -070056#define TRACED_CALL(code) \
57 do { \
58 SCOPED_TRACE("<- called from here"); \
59 code; \
60 if (::testing::Test::HasFatalFailure()) { \
61 return; \
62 } \
63 } while (false)
64
Martin Kreichgauer72912d22017-08-04 12:06:43 -070065struct VersionParam {
66 uint16_t version;
67 enum { is_tls, is_dtls } ssl_method;
68 const char name[8];
69};
70
71static const size_t kTicketKeyLen = 48;
72
73static const VersionParam kAllVersions[] = {
74 {SSL3_VERSION, VersionParam::is_tls, "SSL3"},
75 {TLS1_VERSION, VersionParam::is_tls, "TLS1"},
76 {TLS1_1_VERSION, VersionParam::is_tls, "TLS1_1"},
77 {TLS1_2_VERSION, VersionParam::is_tls, "TLS1_2"},
Martin Kreichgauer72912d22017-08-04 12:06:43 -070078 {TLS1_3_VERSION, VersionParam::is_tls, "TLS1_3"},
Martin Kreichgauer72912d22017-08-04 12:06:43 -070079 {DTLS1_VERSION, VersionParam::is_dtls, "DTLS1"},
80 {DTLS1_2_VERSION, VersionParam::is_dtls, "DTLS1_2"},
81};
82
David Benjamin1d77e562015-03-22 17:22:08 -040083struct ExpectedCipher {
84 unsigned long id;
David Benjaminbb0a17c2014-09-20 15:35:39 -040085 int in_group_flag;
David Benjamin1d77e562015-03-22 17:22:08 -040086};
David Benjaminbb0a17c2014-09-20 15:35:39 -040087
David Benjamin1d77e562015-03-22 17:22:08 -040088struct CipherTest {
89 // The rule string to apply.
David Benjaminbb0a17c2014-09-20 15:35:39 -040090 const char *rule;
David Benjaminfb974e62015-12-16 19:34:22 -050091 // The list of expected ciphers, in order.
92 std::vector<ExpectedCipher> expected;
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -080093 // True if this cipher list should fail in strict mode.
94 bool strict_fail;
David Benjamin1d77e562015-03-22 17:22:08 -040095};
David Benjaminbb0a17c2014-09-20 15:35:39 -040096
Alessandro Ghedini5fd18072016-09-28 21:04:25 +010097struct CurveTest {
98 // The rule string to apply.
99 const char *rule;
100 // The list of expected curves, in order.
101 std::vector<uint16_t> expected;
102};
103
David Benjaminfb974e62015-12-16 19:34:22 -0500104static const CipherTest kCipherTests[] = {
105 // Selecting individual ciphers should work.
106 {
107 "ECDHE-ECDSA-CHACHA20-POLY1305:"
108 "ECDHE-RSA-CHACHA20-POLY1305:"
109 "ECDHE-ECDSA-AES128-GCM-SHA256:"
110 "ECDHE-RSA-AES128-GCM-SHA256",
111 {
112 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500113 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500114 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
115 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
116 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800117 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500118 },
119 // + reorders selected ciphers to the end, keeping their relative order.
120 {
121 "ECDHE-ECDSA-CHACHA20-POLY1305:"
122 "ECDHE-RSA-CHACHA20-POLY1305:"
123 "ECDHE-ECDSA-AES128-GCM-SHA256:"
124 "ECDHE-RSA-AES128-GCM-SHA256:"
125 "+aRSA",
126 {
127 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500128 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
129 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500130 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
131 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800132 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500133 },
134 // ! banishes ciphers from future selections.
135 {
136 "!aRSA:"
137 "ECDHE-ECDSA-CHACHA20-POLY1305:"
138 "ECDHE-RSA-CHACHA20-POLY1305:"
139 "ECDHE-ECDSA-AES128-GCM-SHA256:"
140 "ECDHE-RSA-AES128-GCM-SHA256",
141 {
142 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500143 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
144 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800145 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500146 },
147 // Multiple masks can be ANDed in a single rule.
148 {
149 "kRSA+AESGCM+AES128",
150 {
151 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
152 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800153 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500154 },
155 // - removes selected ciphers, but preserves their order for future
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700156 // selections. Select AES_128_GCM, but order the key exchanges RSA,
David Benjaminfb974e62015-12-16 19:34:22 -0500157 // ECDHE_RSA.
158 {
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700159 "ALL:-kECDHE:"
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700160 "-kRSA:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500161 "AESGCM+AES128+aRSA",
162 {
163 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500164 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
165 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800166 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500167 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800168 // Unknown selectors are no-ops, except in strict mode.
David Benjaminfb974e62015-12-16 19:34:22 -0500169 {
170 "ECDHE-ECDSA-CHACHA20-POLY1305:"
171 "ECDHE-RSA-CHACHA20-POLY1305:"
172 "ECDHE-ECDSA-AES128-GCM-SHA256:"
173 "ECDHE-RSA-AES128-GCM-SHA256:"
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800174 "BOGUS1",
David Benjaminfb974e62015-12-16 19:34:22 -0500175 {
176 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500177 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500178 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
179 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
180 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800181 true,
182 },
183 // Unknown selectors are no-ops, except in strict mode.
184 {
185 "ECDHE-ECDSA-CHACHA20-POLY1305:"
186 "ECDHE-RSA-CHACHA20-POLY1305:"
187 "ECDHE-ECDSA-AES128-GCM-SHA256:"
188 "ECDHE-RSA-AES128-GCM-SHA256:"
189 "-BOGUS2:+BOGUS3:!BOGUS4",
190 {
191 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
192 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
193 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
194 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
195 },
196 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500197 },
198 // Square brackets specify equi-preference groups.
199 {
200 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
201 "[ECDHE-RSA-CHACHA20-POLY1305]:"
202 "ECDHE-RSA-AES128-GCM-SHA256",
203 {
204 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
David Benjaminfb974e62015-12-16 19:34:22 -0500205 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley2e839242017-01-19 15:12:44 -0800206 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500207 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
208 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800209 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500210 },
David Benjamin6fff3862017-06-21 21:07:04 -0400211 // Standard names may be used instead of OpenSSL names.
212 {
213 "[TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256|"
David Benjaminbf5f1922017-07-01 11:13:53 -0400214 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256]:"
David Benjamin6fff3862017-06-21 21:07:04 -0400215 "[TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256]:"
216 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
217 {
218 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
219 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
220 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
221 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
222 },
223 false,
224 },
David Benjaminfb974e62015-12-16 19:34:22 -0500225 // @STRENGTH performs a stable strength-sort of the selected ciphers and
226 // only the selected ciphers.
227 {
228 // To simplify things, banish all but {ECDHE_RSA,RSA} x
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700229 // {CHACHA20,AES_256_CBC,AES_128_CBC} x SHA1.
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700230 "!AESGCM:!3DES:!SHA256:!SHA384:"
David Benjaminfb974e62015-12-16 19:34:22 -0500231 // Order some ciphers backwards by strength.
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700232 "ALL:-CHACHA20:-AES256:-AES128:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500233 // Select ECDHE ones and sort them by strength. Ties should resolve
234 // based on the order above.
235 "kECDHE:@STRENGTH:-ALL:"
236 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
237 // by strength. Then RSA, backwards by strength.
238 "aRSA",
239 {
240 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
241 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500242 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500243 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
244 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
245 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800246 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500247 },
David Benjaminbf5f1922017-07-01 11:13:53 -0400248 // Additional masks after @STRENGTH get silently discarded.
249 //
250 // TODO(davidben): Make this an error. If not silently discarded, they get
251 // interpreted as + opcodes which are very different.
252 {
253 "ECDHE-RSA-AES128-GCM-SHA256:"
254 "ECDHE-RSA-AES256-GCM-SHA384:"
255 "@STRENGTH+AES256",
256 {
257 {TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
258 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
259 },
260 false,
261 },
262 {
263 "ECDHE-RSA-AES128-GCM-SHA256:"
264 "ECDHE-RSA-AES256-GCM-SHA384:"
265 "@STRENGTH+AES256:"
266 "ECDHE-RSA-CHACHA20-POLY1305",
267 {
268 {TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
269 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
270 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
271 },
272 false,
273 },
David Benjaminfb974e62015-12-16 19:34:22 -0500274 // Exact ciphers may not be used in multi-part rules; they are treated
275 // as unknown aliases.
276 {
277 "ECDHE-ECDSA-AES128-GCM-SHA256:"
278 "ECDHE-RSA-AES128-GCM-SHA256:"
279 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
280 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
281 {
282 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
283 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
284 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800285 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500286 },
287 // SSLv3 matches everything that existed before TLS 1.2.
288 {
289 "AES128-SHA:AES128-SHA256:!SSLv3",
290 {
291 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
292 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800293 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500294 },
295 // TLSv1.2 matches everything added in TLS 1.2.
296 {
297 "AES128-SHA:AES128-SHA256:!TLSv1.2",
298 {
299 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
300 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800301 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500302 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800303 // The two directives have no intersection. But each component is valid, so
304 // even in strict mode it is accepted.
David Benjaminfb974e62015-12-16 19:34:22 -0500305 {
306 "AES128-SHA:AES128-SHA256:!TLSv1.2+SSLv3",
307 {
308 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
309 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
310 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800311 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500312 },
Adam Langley22df6912017-07-25 12:27:37 -0700313 // Spaces, semi-colons and commas are separators.
314 {
315 "AES128-SHA: AES128-SHA256 AES256-SHA ,AES256-SHA256 ; AES128-GCM-SHA256",
316 {
317 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
318 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
319 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
320 {TLS1_CK_RSA_WITH_AES_256_SHA256, 0},
321 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
322 },
323 // …but not in strict mode.
324 true,
325 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400326};
327
328static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400329 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400330 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
331 "RSA]",
332 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400333 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400334 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400335 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400336 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400337 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400338 "",
339 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400340 // COMPLEMENTOFDEFAULT is empty.
341 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400342 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400343 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400344 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400345 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
346 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
347 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
348 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
Adam Langleyf99f2442016-10-02 09:53:38 -0700349 // Opcode supplied, but missing selector.
350 "+",
Adam Langley22df6912017-07-25 12:27:37 -0700351 // Spaces are forbidden in equal-preference groups.
352 "[AES128-SHA | AES128-SHA256]",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400353};
354
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700355static const char *kMustNotIncludeNull[] = {
356 "ALL",
357 "DEFAULT",
David Benjamind6e9eec2015-11-18 09:48:55 -0500358 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700359 "FIPS",
360 "SHA",
361 "SHA1",
362 "RSA",
363 "SSLv3",
364 "TLSv1",
365 "TLSv1.2",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700366};
367
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100368static const CurveTest kCurveTests[] = {
369 {
370 "P-256",
371 { SSL_CURVE_SECP256R1 },
372 },
373 {
374 "P-256:P-384:P-521:X25519",
375 {
376 SSL_CURVE_SECP256R1,
377 SSL_CURVE_SECP384R1,
378 SSL_CURVE_SECP521R1,
379 SSL_CURVE_X25519,
380 },
381 },
David Benjamin6dda1662017-11-02 20:44:26 -0400382 {
383 "prime256v1:secp384r1:secp521r1:x25519",
384 {
385 SSL_CURVE_SECP256R1,
386 SSL_CURVE_SECP384R1,
387 SSL_CURVE_SECP521R1,
388 SSL_CURVE_X25519,
389 },
390 },
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100391};
392
393static const char *kBadCurvesLists[] = {
394 "",
395 ":",
396 "::",
397 "P-256::X25519",
398 "RSA:P-256",
399 "P-256:RSA",
400 "X25519:P-256:",
401 ":X25519:P-256",
402};
403
David Benjamin70dbf042017-08-08 18:51:37 -0400404static std::string CipherListToString(SSL_CTX *ctx) {
David Benjamin1d77e562015-03-22 17:22:08 -0400405 bool in_group = false;
David Benjamine11726a2017-04-23 12:14:28 -0400406 std::string ret;
David Benjamin70dbf042017-08-08 18:51:37 -0400407 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
408 for (size_t i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
409 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
410 if (!in_group && SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400411 ret += "\t[\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400412 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400413 }
David Benjamine11726a2017-04-23 12:14:28 -0400414 ret += "\t";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400415 if (in_group) {
David Benjamine11726a2017-04-23 12:14:28 -0400416 ret += " ";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400417 }
David Benjamine11726a2017-04-23 12:14:28 -0400418 ret += SSL_CIPHER_get_name(cipher);
419 ret += "\n";
David Benjamin70dbf042017-08-08 18:51:37 -0400420 if (in_group && !SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400421 ret += "\t]\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400422 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400423 }
424 }
David Benjamine11726a2017-04-23 12:14:28 -0400425 return ret;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400426}
427
David Benjamin70dbf042017-08-08 18:51:37 -0400428static bool CipherListsEqual(SSL_CTX *ctx,
David Benjamine11726a2017-04-23 12:14:28 -0400429 const std::vector<ExpectedCipher> &expected) {
David Benjamin70dbf042017-08-08 18:51:37 -0400430 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
431 if (sk_SSL_CIPHER_num(ciphers) != expected.size()) {
David Benjamin1d77e562015-03-22 17:22:08 -0400432 return false;
David Benjamin65226252015-02-05 16:49:47 -0500433 }
434
David Benjamine11726a2017-04-23 12:14:28 -0400435 for (size_t i = 0; i < expected.size(); i++) {
David Benjamin70dbf042017-08-08 18:51:37 -0400436 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
David Benjamine11726a2017-04-23 12:14:28 -0400437 if (expected[i].id != SSL_CIPHER_get_id(cipher) ||
David Benjamin70dbf042017-08-08 18:51:37 -0400438 expected[i].in_group_flag != !!SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400439 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400440 }
441 }
442
David Benjamin1d77e562015-03-22 17:22:08 -0400443 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400444}
445
David Benjamine11726a2017-04-23 12:14:28 -0400446TEST(SSLTest, CipherRules) {
447 for (const CipherTest &t : kCipherTests) {
448 SCOPED_TRACE(t.rule);
449 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
450 ASSERT_TRUE(ctx);
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700451
David Benjamine11726a2017-04-23 12:14:28 -0400452 // Test lax mode.
453 ASSERT_TRUE(SSL_CTX_set_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400454 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400455 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400456 << CipherListToString(ctx.get());
David Benjamine11726a2017-04-23 12:14:28 -0400457
458 // Test strict mode.
459 if (t.strict_fail) {
460 EXPECT_FALSE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
461 } else {
462 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400463 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400464 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400465 << CipherListToString(ctx.get());
David Benjaminbb0a17c2014-09-20 15:35:39 -0400466 }
467 }
468
David Benjaminfb974e62015-12-16 19:34:22 -0500469 for (const char *rule : kBadRules) {
David Benjamine11726a2017-04-23 12:14:28 -0400470 SCOPED_TRACE(rule);
471 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
472 ASSERT_TRUE(ctx);
473
474 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), rule));
David Benjaminbb0a17c2014-09-20 15:35:39 -0400475 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400476 }
477
David Benjaminfb974e62015-12-16 19:34:22 -0500478 for (const char *rule : kMustNotIncludeNull) {
David Benjamine11726a2017-04-23 12:14:28 -0400479 SCOPED_TRACE(rule);
480 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
481 ASSERT_TRUE(ctx);
482
483 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400484 for (const SSL_CIPHER *cipher : SSL_CTX_get_ciphers(ctx.get())) {
David Benjamine3bb51c2017-08-22 23:16:02 -0700485 EXPECT_NE(NID_undef, SSL_CIPHER_get_cipher_nid(cipher));
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700486 }
487 }
David Benjaminbb0a17c2014-09-20 15:35:39 -0400488}
David Benjamin2e521212014-07-16 14:37:51 -0400489
David Benjamine11726a2017-04-23 12:14:28 -0400490TEST(SSLTest, CurveRules) {
491 for (const CurveTest &t : kCurveTests) {
492 SCOPED_TRACE(t.rule);
493 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
494 ASSERT_TRUE(ctx);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100495
David Benjamine11726a2017-04-23 12:14:28 -0400496 ASSERT_TRUE(SSL_CTX_set1_curves_list(ctx.get(), t.rule));
497 ASSERT_EQ(t.expected.size(), ctx->supported_group_list_len);
498 for (size_t i = 0; i < t.expected.size(); i++) {
499 EXPECT_EQ(t.expected[i], ctx->supported_group_list[i]);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100500 }
501 }
502
503 for (const char *rule : kBadCurvesLists) {
David Benjamine11726a2017-04-23 12:14:28 -0400504 SCOPED_TRACE(rule);
505 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
506 ASSERT_TRUE(ctx);
507
508 EXPECT_FALSE(SSL_CTX_set1_curves_list(ctx.get(), rule));
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100509 ERR_clear_error();
510 }
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100511}
512
Adam Langley364f7a62016-12-12 10:51:00 -0800513// kOpenSSLSession is a serialized SSL_SESSION.
Adam Langley10f97f32016-07-12 08:09:33 -0700514static const char kOpenSSLSession[] =
Adam Langley364f7a62016-12-12 10:51:00 -0800515 "MIIFqgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700516 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
517 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
518 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
519 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
520 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
521 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
522 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
523 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
524 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
525 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
526 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
527 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
528 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
529 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
530 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
531 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
532 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
533 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
534 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
535 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
536 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
537 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
538 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
539 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
540 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
541 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
542 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
543 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
544 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
Adam Langley364f7a62016-12-12 10:51:00 -0800545 "i4gv7Y5oliyntgMBAQA=";
Adam Langley10f97f32016-07-12 08:09:33 -0700546
547// kCustomSession is a custom serialized SSL_SESSION generated by
548// filling in missing fields from |kOpenSSLSession|. This includes
549// providing |peer_sha256|, so |peer| is not serialized.
550static const char kCustomSession[] =
David Benjamina8614602017-09-06 15:40:19 -0400551 "MIIBZAIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700552 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
David Benjamina8614602017-09-06 15:40:19 -0400553 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUqAcEBXdvcmxkqQUCAwGJwKqBpwSB"
554 "pBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38"
555 "VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd"
556 "3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hg"
557 "b+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYGBgYGBgYGBgYGBgYGBgYGBgYG"
558 "BgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
Adam Langley10f97f32016-07-12 08:09:33 -0700559
560// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
561static const char kBoringSSLSession[] =
562 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
563 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
564 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
565 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
566 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
567 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
568 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
569 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
570 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
571 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
572 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
573 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
574 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
575 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
576 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
577 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
578 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
579 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
580 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
581 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
582 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
583 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
584 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
585 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
586 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
587 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
588 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
589 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
590 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
591 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
592 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
593 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
594 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
595 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
596 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
597 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
598 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
599 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
600 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
601 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
602 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
603 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
604 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
605 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
606 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
607 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
608 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
609 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
610 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
611 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
612 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
613 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
614 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
615 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
616 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
617 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
618 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
619 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
620 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
621 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
622 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
623 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
624 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
625 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
626 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
627 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
628 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
629 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
630 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
631 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
632 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
633 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
634 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
635 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
636 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
637 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
638 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
639 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
640 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
641 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
642 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
643 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
644 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
645 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
646 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
647 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
648 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
649 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
650 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
651 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
652 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
653 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
654 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
655 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
656 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
657
658// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
659// the final (optional) element of |kCustomSession| with tag number 30.
660static const char kBadSessionExtraField[] =
661 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
662 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
663 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
664 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
665 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
666 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
667 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
668 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
669
670// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
671// the version of |kCustomSession| with 2.
672static const char kBadSessionVersion[] =
673 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
674 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
675 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
676 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
677 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
678 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
679 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
680 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
681
682// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
683// appended.
684static const char kBadSessionTrailingData[] =
685 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
686 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
687 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
688 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
689 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
690 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
691 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
692 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
693
David Benjamin1d77e562015-03-22 17:22:08 -0400694static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400695 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400696 if (!EVP_DecodedLength(&len, strlen(in))) {
697 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400698 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400699 }
700
David Benjamin1d77e562015-03-22 17:22:08 -0400701 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800702 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400703 strlen(in))) {
704 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400705 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400706 }
David Benjamin1d77e562015-03-22 17:22:08 -0400707 out->resize(len);
708 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400709}
710
David Benjamin1d77e562015-03-22 17:22:08 -0400711static bool TestSSL_SESSIONEncoding(const char *input_b64) {
David Benjamin751e8892014-10-19 00:59:36 -0400712 const uint8_t *cptr;
713 uint8_t *ptr;
David Benjamin751e8892014-10-19 00:59:36 -0400714
David Benjamin1d77e562015-03-22 17:22:08 -0400715 // Decode the input.
716 std::vector<uint8_t> input;
717 if (!DecodeBase64(&input, input_b64)) {
718 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400719 }
720
David Benjamin1d77e562015-03-22 17:22:08 -0400721 // Verify the SSL_SESSION decodes.
Adam Langley46db7af2017-02-01 15:49:37 -0800722 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
723 if (!ssl_ctx) {
724 return false;
725 }
726 bssl::UniquePtr<SSL_SESSION> session(
727 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
David Benjaminfd67aa82015-06-15 19:41:48 -0400728 if (!session) {
729 fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400730 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400731 }
732
David Benjamin1d77e562015-03-22 17:22:08 -0400733 // Verify the SSL_SESSION encoding round-trips.
734 size_t encoded_len;
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700735 bssl::UniquePtr<uint8_t> encoded;
David Benjamin1d77e562015-03-22 17:22:08 -0400736 uint8_t *encoded_raw;
737 if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
David Benjamin3cac4502014-10-21 01:46:30 -0400738 fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400739 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400740 }
David Benjamin1d77e562015-03-22 17:22:08 -0400741 encoded.reset(encoded_raw);
742 if (encoded_len != input.size() ||
David Benjamin17cf2cb2016-12-13 01:07:13 -0500743 OPENSSL_memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin3cac4502014-10-21 01:46:30 -0400744 fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
Sigbjorn Vik2b23d242015-06-29 15:07:26 +0200745 hexdump(stderr, "Before: ", input.data(), input.size());
746 hexdump(stderr, "After: ", encoded_raw, encoded_len);
David Benjamin1d77e562015-03-22 17:22:08 -0400747 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400748 }
David Benjamin3cac4502014-10-21 01:46:30 -0400749
David Benjaminfd67aa82015-06-15 19:41:48 -0400750 // Verify the SSL_SESSION also decodes with the legacy API.
David Benjaminef14b2d2015-11-11 14:01:27 -0800751 cptr = input.data();
David Benjaminfd67aa82015-06-15 19:41:48 -0400752 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
David Benjaminef14b2d2015-11-11 14:01:27 -0800753 if (!session || cptr != input.data() + input.size()) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400754 fprintf(stderr, "d2i_SSL_SESSION failed\n");
755 return false;
756 }
757
David Benjamin1d77e562015-03-22 17:22:08 -0400758 // Verify the SSL_SESSION encoding round-trips via the legacy API.
759 int len = i2d_SSL_SESSION(session.get(), NULL);
760 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400761 fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400762 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400763 }
764
David Benjamin1d77e562015-03-22 17:22:08 -0400765 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
766 if (!encoded) {
David Benjamin751e8892014-10-19 00:59:36 -0400767 fprintf(stderr, "malloc failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400768 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400769 }
David Benjamin1d77e562015-03-22 17:22:08 -0400770
771 ptr = encoded.get();
772 len = i2d_SSL_SESSION(session.get(), &ptr);
773 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400774 fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400775 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400776 }
David Benjamin1d77e562015-03-22 17:22:08 -0400777 if (ptr != encoded.get() + input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400778 fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400779 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400780 }
David Benjamin17cf2cb2016-12-13 01:07:13 -0500781 if (OPENSSL_memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin751e8892014-10-19 00:59:36 -0400782 fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400783 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400784 }
785
David Benjamin1d77e562015-03-22 17:22:08 -0400786 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400787}
788
David Benjaminf297e022015-05-28 19:55:29 -0400789static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
790 std::vector<uint8_t> input;
791 if (!DecodeBase64(&input, input_b64)) {
792 return false;
793 }
794
795 // Verify that the SSL_SESSION fails to decode.
Adam Langley46db7af2017-02-01 15:49:37 -0800796 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
797 if (!ssl_ctx) {
798 return false;
799 }
800 bssl::UniquePtr<SSL_SESSION> session(
801 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
David Benjaminf297e022015-05-28 19:55:29 -0400802 if (session) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400803 fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
David Benjaminf297e022015-05-28 19:55:29 -0400804 return false;
805 }
806 ERR_clear_error();
807 return true;
808}
809
David Benjamin321fcdc2017-04-24 11:42:42 -0400810static void ExpectDefaultVersion(uint16_t min_version, uint16_t max_version,
811 const SSL_METHOD *(*method)(void)) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700812 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
David Benjamin321fcdc2017-04-24 11:42:42 -0400813 ASSERT_TRUE(ctx);
David Benjaminfc08dfc2017-06-20 14:39:32 -0400814 EXPECT_EQ(min_version, ctx->conf_min_version);
815 EXPECT_EQ(max_version, ctx->conf_max_version);
David Benjamin321fcdc2017-04-24 11:42:42 -0400816}
817
818TEST(SSLTest, DefaultVersion) {
819 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
820 ExpectDefaultVersion(TLS1_VERSION, TLS1_2_VERSION, &TLS_method);
821 ExpectDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method);
822 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method);
823 ExpectDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method);
824 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method);
825 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method);
826 ExpectDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method);
David Benjamin82c9e902014-12-12 15:55:27 -0500827}
828
David Benjamin348f0d82017-08-10 16:06:27 -0400829TEST(SSLTest, CipherProperties) {
David Benjamin6fff3862017-06-21 21:07:04 -0400830 static const struct {
831 int id;
832 const char *standard_name;
David Benjamin348f0d82017-08-10 16:06:27 -0400833 int cipher_nid;
834 int digest_nid;
835 int kx_nid;
836 int auth_nid;
David Benjaminb1b76ae2017-09-21 17:03:34 -0400837 int prf_nid;
David Benjamin6fff3862017-06-21 21:07:04 -0400838 } kTests[] = {
David Benjamin348f0d82017-08-10 16:06:27 -0400839 {
840 SSL3_CK_RSA_DES_192_CBC3_SHA,
841 "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
842 NID_des_ede3_cbc,
843 NID_sha1,
844 NID_kx_rsa,
845 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400846 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400847 },
848 {
849 TLS1_CK_RSA_WITH_AES_128_SHA,
850 "TLS_RSA_WITH_AES_128_CBC_SHA",
851 NID_aes_128_cbc,
852 NID_sha1,
853 NID_kx_rsa,
854 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400855 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400856 },
857 {
858 TLS1_CK_PSK_WITH_AES_256_CBC_SHA,
859 "TLS_PSK_WITH_AES_256_CBC_SHA",
860 NID_aes_256_cbc,
861 NID_sha1,
862 NID_kx_psk,
863 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400864 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400865 },
866 {
867 TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
868 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
869 NID_aes_128_cbc,
870 NID_sha256,
871 NID_kx_ecdhe,
872 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400873 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400874 },
875 {
876 TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
877 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
878 NID_aes_256_cbc,
879 NID_sha384,
880 NID_kx_ecdhe,
881 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400882 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -0400883 },
884 {
885 TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
886 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
887 NID_aes_128_gcm,
888 NID_undef,
889 NID_kx_ecdhe,
890 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400891 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400892 },
893 {
894 TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
895 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
896 NID_aes_128_gcm,
897 NID_undef,
898 NID_kx_ecdhe,
899 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400900 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400901 },
902 {
903 TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
904 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
905 NID_aes_256_gcm,
906 NID_undef,
907 NID_kx_ecdhe,
908 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400909 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -0400910 },
911 {
912 TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
913 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
914 NID_aes_128_cbc,
915 NID_sha1,
916 NID_kx_ecdhe,
917 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400918 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400919 },
920 {
921 TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
922 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
923 NID_chacha20_poly1305,
924 NID_undef,
925 NID_kx_ecdhe,
926 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400927 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400928 },
929 {
930 TLS1_CK_AES_256_GCM_SHA384,
931 "TLS_AES_256_GCM_SHA384",
932 NID_aes_256_gcm,
933 NID_undef,
934 NID_kx_any,
935 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400936 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -0400937 },
938 {
939 TLS1_CK_AES_128_GCM_SHA256,
940 "TLS_AES_128_GCM_SHA256",
941 NID_aes_128_gcm,
942 NID_undef,
943 NID_kx_any,
944 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400945 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400946 },
947 {
948 TLS1_CK_CHACHA20_POLY1305_SHA256,
949 "TLS_CHACHA20_POLY1305_SHA256",
950 NID_chacha20_poly1305,
951 NID_undef,
952 NID_kx_any,
953 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400954 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400955 },
David Benjamin6fff3862017-06-21 21:07:04 -0400956 };
David Benjamin65226252015-02-05 16:49:47 -0500957
David Benjamin6fff3862017-06-21 21:07:04 -0400958 for (const auto &t : kTests) {
959 SCOPED_TRACE(t.standard_name);
David Benjamine11726a2017-04-23 12:14:28 -0400960
961 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(t.id & 0xffff);
962 ASSERT_TRUE(cipher);
David Benjamin6fff3862017-06-21 21:07:04 -0400963 EXPECT_STREQ(t.standard_name, SSL_CIPHER_standard_name(cipher));
964
David Benjamine11726a2017-04-23 12:14:28 -0400965 bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
966 ASSERT_TRUE(rfc_name);
David Benjamin6fff3862017-06-21 21:07:04 -0400967 EXPECT_STREQ(t.standard_name, rfc_name.get());
David Benjamin348f0d82017-08-10 16:06:27 -0400968
969 EXPECT_EQ(t.cipher_nid, SSL_CIPHER_get_cipher_nid(cipher));
970 EXPECT_EQ(t.digest_nid, SSL_CIPHER_get_digest_nid(cipher));
971 EXPECT_EQ(t.kx_nid, SSL_CIPHER_get_kx_nid(cipher));
972 EXPECT_EQ(t.auth_nid, SSL_CIPHER_get_auth_nid(cipher));
David Benjaminb1b76ae2017-09-21 17:03:34 -0400973 EXPECT_EQ(t.prf_nid, SSL_CIPHER_get_prf_nid(cipher));
David Benjamin65226252015-02-05 16:49:47 -0500974 }
David Benjamin65226252015-02-05 16:49:47 -0500975}
976
Steven Valdeza833c352016-11-01 13:39:36 -0400977// CreateSessionWithTicket returns a sample |SSL_SESSION| with the specified
978// version and ticket length or nullptr on failure.
979static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(uint16_t version,
980 size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -0400981 std::vector<uint8_t> der;
982 if (!DecodeBase64(&der, kOpenSSLSession)) {
983 return nullptr;
984 }
Adam Langley46db7af2017-02-01 15:49:37 -0800985
986 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
987 if (!ssl_ctx) {
988 return nullptr;
989 }
Steven Valdeza833c352016-11-01 13:39:36 -0400990 bssl::UniquePtr<SSL_SESSION> session(
Adam Langley46db7af2017-02-01 15:49:37 -0800991 SSL_SESSION_from_bytes(der.data(), der.size(), ssl_ctx.get()));
David Benjamin422fe082015-07-21 22:03:43 -0400992 if (!session) {
993 return nullptr;
994 }
995
Steven Valdeza833c352016-11-01 13:39:36 -0400996 session->ssl_version = version;
997
David Benjamin422fe082015-07-21 22:03:43 -0400998 // Swap out the ticket for a garbage one.
999 OPENSSL_free(session->tlsext_tick);
1000 session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len));
1001 if (session->tlsext_tick == nullptr) {
1002 return nullptr;
1003 }
David Benjamin17cf2cb2016-12-13 01:07:13 -05001004 OPENSSL_memset(session->tlsext_tick, 'a', ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -04001005 session->tlsext_ticklen = ticket_len;
David Benjamin1269ddd2015-10-18 15:18:55 -04001006
1007 // Fix up the timeout.
David Benjamin9b63f292016-11-15 00:44:05 -05001008#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
1009 session->time = 1234;
1010#else
David Benjamin1269ddd2015-10-18 15:18:55 -04001011 session->time = time(NULL);
David Benjamin9b63f292016-11-15 00:44:05 -05001012#endif
David Benjamin422fe082015-07-21 22:03:43 -04001013 return session;
1014}
1015
David Benjaminafc64de2016-07-19 17:12:41 +02001016static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001017 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +02001018 if (!bio) {
1019 return false;
1020 }
1021 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -04001022 BIO_up_ref(bio.get());
1023 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +02001024 int ret = SSL_connect(ssl);
1025 if (ret > 0) {
1026 // SSL_connect should fail without a BIO to write to.
1027 return false;
1028 }
1029 ERR_clear_error();
1030
1031 const uint8_t *client_hello;
1032 size_t client_hello_len;
1033 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
1034 return false;
1035 }
1036 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
1037 return true;
1038}
1039
Steven Valdeza833c352016-11-01 13:39:36 -04001040// GetClientHelloLen creates a client SSL connection with the specified version
1041// and ticket length. It returns the length of the ClientHello, not including
1042// the record header, on success and zero on error.
1043static size_t GetClientHelloLen(uint16_t max_version, uint16_t session_version,
1044 size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001045 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Steven Valdeza833c352016-11-01 13:39:36 -04001046 bssl::UniquePtr<SSL_SESSION> session =
1047 CreateSessionWithTicket(session_version, ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -04001048 if (!ctx || !session) {
1049 return 0;
1050 }
Steven Valdeza833c352016-11-01 13:39:36 -04001051
1052 // Set a one-element cipher list so the baseline ClientHello is unpadded.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001053 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
Steven Valdez2c62fe92016-10-14 12:08:12 -04001054 if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -08001055 !SSL_set_strict_cipher_list(ssl.get(), "ECDHE-RSA-AES128-GCM-SHA256") ||
Steven Valdeza833c352016-11-01 13:39:36 -04001056 !SSL_set_max_proto_version(ssl.get(), max_version)) {
David Benjamin422fe082015-07-21 22:03:43 -04001057 return 0;
1058 }
Steven Valdeza833c352016-11-01 13:39:36 -04001059
David Benjaminafc64de2016-07-19 17:12:41 +02001060 std::vector<uint8_t> client_hello;
1061 if (!GetClientHello(ssl.get(), &client_hello) ||
1062 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -04001063 return 0;
1064 }
Steven Valdeza833c352016-11-01 13:39:36 -04001065
David Benjaminafc64de2016-07-19 17:12:41 +02001066 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -04001067}
1068
1069struct PaddingTest {
1070 size_t input_len, padded_len;
1071};
1072
1073static const PaddingTest kPaddingTests[] = {
1074 // ClientHellos of length below 0x100 do not require padding.
1075 {0xfe, 0xfe},
1076 {0xff, 0xff},
1077 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
1078 {0x100, 0x200},
1079 {0x123, 0x200},
1080 {0x1fb, 0x200},
1081 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
1082 // padding extension takes a minimum of four bytes plus one required content
1083 // byte. (To work around yet more server bugs, we avoid empty final
1084 // extensions.)
1085 {0x1fc, 0x201},
1086 {0x1fd, 0x202},
1087 {0x1fe, 0x203},
1088 {0x1ff, 0x204},
1089 // Finally, larger ClientHellos need no padding.
1090 {0x200, 0x200},
1091 {0x201, 0x201},
1092};
1093
Steven Valdeza833c352016-11-01 13:39:36 -04001094static bool TestPaddingExtension(uint16_t max_version,
1095 uint16_t session_version) {
David Benjamin422fe082015-07-21 22:03:43 -04001096 // Sample a baseline length.
Steven Valdeza833c352016-11-01 13:39:36 -04001097 size_t base_len = GetClientHelloLen(max_version, session_version, 1);
David Benjamin422fe082015-07-21 22:03:43 -04001098 if (base_len == 0) {
1099 return false;
1100 }
1101
1102 for (const PaddingTest &test : kPaddingTests) {
1103 if (base_len > test.input_len) {
Steven Valdeza833c352016-11-01 13:39:36 -04001104 fprintf(stderr,
1105 "Baseline ClientHello too long (max_version = %04x, "
1106 "session_version = %04x).\n",
1107 max_version, session_version);
David Benjamin422fe082015-07-21 22:03:43 -04001108 return false;
1109 }
1110
Steven Valdeza833c352016-11-01 13:39:36 -04001111 size_t padded_len = GetClientHelloLen(max_version, session_version,
1112 1 + test.input_len - base_len);
David Benjamin422fe082015-07-21 22:03:43 -04001113 if (padded_len != test.padded_len) {
Steven Valdeza833c352016-11-01 13:39:36 -04001114 fprintf(stderr,
1115 "%u-byte ClientHello padded to %u bytes, not %u (max_version = "
1116 "%04x, session_version = %04x).\n",
David Benjamin422fe082015-07-21 22:03:43 -04001117 static_cast<unsigned>(test.input_len),
1118 static_cast<unsigned>(padded_len),
Steven Valdeza833c352016-11-01 13:39:36 -04001119 static_cast<unsigned>(test.padded_len), max_version,
1120 session_version);
David Benjamin422fe082015-07-21 22:03:43 -04001121 return false;
1122 }
1123 }
Steven Valdeza833c352016-11-01 13:39:36 -04001124
David Benjamin422fe082015-07-21 22:03:43 -04001125 return true;
1126}
1127
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001128static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001129 static const char kCertPEM[] =
1130 "-----BEGIN CERTIFICATE-----\n"
1131 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1132 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1133 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1134 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1135 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1136 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1137 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1138 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1139 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1140 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1141 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1142 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1143 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1144 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001145 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
David Benjamin1444c3a2016-12-20 17:23:11 -05001146 return bssl::UniquePtr<X509>(
1147 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjaminde942382016-02-11 12:02:01 -05001148}
1149
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001150static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001151 static const char kKeyPEM[] =
1152 "-----BEGIN RSA PRIVATE KEY-----\n"
1153 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1154 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1155 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1156 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1157 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1158 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1159 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1160 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1161 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1162 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1163 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1164 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1165 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1166 "-----END RSA PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001167 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1168 return bssl::UniquePtr<EVP_PKEY>(
David Benjaminde942382016-02-11 12:02:01 -05001169 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1170}
1171
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001172static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001173 static const char kCertPEM[] =
1174 "-----BEGIN CERTIFICATE-----\n"
1175 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1176 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1177 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1178 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1179 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1180 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1181 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1182 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1183 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1184 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1185 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001186 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1187 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjamin0fc37ef2016-08-17 15:29:46 -04001188}
1189
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001190static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001191 static const char kKeyPEM[] =
1192 "-----BEGIN PRIVATE KEY-----\n"
1193 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1194 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1195 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1196 "-----END PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001197 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1198 return bssl::UniquePtr<EVP_PKEY>(
David Benjamin0fc37ef2016-08-17 15:29:46 -04001199 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1200}
1201
Adam Langleyd04ca952017-02-28 11:26:51 -08001202static bssl::UniquePtr<CRYPTO_BUFFER> BufferFromPEM(const char *pem) {
1203 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1204 char *name, *header;
1205 uint8_t *data;
1206 long data_len;
1207 if (!PEM_read_bio(bio.get(), &name, &header, &data,
1208 &data_len)) {
1209 return nullptr;
1210 }
1211 OPENSSL_free(name);
1212 OPENSSL_free(header);
1213
1214 auto ret = bssl::UniquePtr<CRYPTO_BUFFER>(
1215 CRYPTO_BUFFER_new(data, data_len, nullptr));
1216 OPENSSL_free(data);
1217 return ret;
1218}
1219
1220static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestCertificateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001221 static const char kCertPEM[] =
1222 "-----BEGIN CERTIFICATE-----\n"
1223 "MIIC0jCCAbqgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQiBD\n"
1224 "QTAeFw0xNjAyMjgyMDI3MDNaFw0yNjAyMjUyMDI3MDNaMBgxFjAUBgNVBAMMDUNs\n"
1225 "aWVudCBDZXJ0IEEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRvaz8\n"
1226 "CC/cshpCafJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/\n"
1227 "kLRcH89M/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3\n"
1228 "tHb+xs2PSs8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+c\n"
1229 "IDs2rQ+lP7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1\n"
1230 "z7C8jU50Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9V\n"
1231 "iLeXANgZi+Xx9KgfAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI\n"
1232 "KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBFEVbmYl+2RtNw\n"
1233 "rDftRDF1v2QUbcN2ouSnQDHxeDQdSgasLzT3ui8iYu0Rw2WWcZ0DV5e0ztGPhWq7\n"
1234 "AO0B120aFRMOY+4+bzu9Q2FFkQqc7/fKTvTDzIJI5wrMnFvUfzzvxh3OHWMYSs/w\n"
1235 "giq33hTKeHEq6Jyk3btCny0Ycecyc3yGXH10sizUfiHlhviCkDuESk8mFDwDDzqW\n"
1236 "ZF0IipzFbEDHoIxLlm3GQxpiLoEV4k8KYJp3R5KBLFyxM6UGPz8h72mIPCJp2RuK\n"
1237 "MYgF91UDvVzvnYm6TfseM2+ewKirC00GOrZ7rEcFvtxnKSqYf4ckqfNdSU1Y+RRC\n"
1238 "1ngWZ7Ih\n"
1239 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001240 return BufferFromPEM(kCertPEM);
David Benjamin1444c3a2016-12-20 17:23:11 -05001241}
1242
Adam Langleyd04ca952017-02-28 11:26:51 -08001243static bssl::UniquePtr<X509> X509FromBuffer(
1244 bssl::UniquePtr<CRYPTO_BUFFER> buffer) {
1245 if (!buffer) {
1246 return nullptr;
1247 }
1248 const uint8_t *derp = CRYPTO_BUFFER_data(buffer.get());
1249 return bssl::UniquePtr<X509>(
1250 d2i_X509(NULL, &derp, CRYPTO_BUFFER_len(buffer.get())));
1251}
1252
1253static bssl::UniquePtr<X509> GetChainTestCertificate() {
1254 return X509FromBuffer(GetChainTestCertificateBuffer());
1255}
1256
1257static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestIntermediateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001258 static const char kCertPEM[] =
1259 "-----BEGIN CERTIFICATE-----\n"
1260 "MIICwjCCAaqgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS\n"
1261 "b290IENBMB4XDTE2MDIyODIwMjcwM1oXDTI2MDIyNTIwMjcwM1owDzENMAsGA1UE\n"
1262 "AwwEQiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALsSCYmDip2D\n"
1263 "GkjFxw7ykz26JSjELkl6ArlYjFJ3aT/SCh8qbS4gln7RH8CPBd78oFdfhIKQrwtZ\n"
1264 "3/q21ykD9BAS3qHe2YdcJfm8/kWAy5DvXk6NXU4qX334KofBAEpgdA/igEFq1P1l\n"
1265 "HAuIfZCpMRfT+i5WohVsGi8f/NgpRvVaMONLNfgw57mz1lbtFeBEISmX0kbsuJxF\n"
1266 "Qj/Bwhi5/0HAEXG8e7zN4cEx0yPRvmOATRdVb/8dW2pwOHRJq9R5M0NUkIsTSnL7\n"
1267 "6N/z8hRAHMsV3IudC5Yd7GXW1AGu9a+iKU+Q4xcZCoj0DC99tL4VKujrV1kAeqsM\n"
1268 "cz5/dKzi6+cCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
1269 "AQYwDQYJKoZIhvcNAQELBQADggEBAIIeZiEeNhWWQ8Y4D+AGDwqUUeG8NjCbKrXQ\n"
1270 "BlHg5wZ8xftFaiP1Dp/UAezmx2LNazdmuwrYB8lm3FVTyaPDTKEGIPS4wJKHgqH1\n"
1271 "QPDhqNm85ey7TEtI9oYjsNim/Rb+iGkIAMXaxt58SzxbjvP0kMr1JfJIZbic9vye\n"
1272 "NwIspMFIpP3FB8ywyu0T0hWtCQgL4J47nigCHpOu58deP88fS/Nyz/fyGVWOZ76b\n"
1273 "WhWwgM3P3X95fQ3d7oFPR/bVh0YV+Cf861INwplokXgXQ3/TCQ+HNXeAMWn3JLWv\n"
1274 "XFwk8owk9dq/kQGdndGgy3KTEW4ctPX5GNhf3LJ9Q7dLji4ReQ4=\n"
1275 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001276 return BufferFromPEM(kCertPEM);
1277}
1278
1279static bssl::UniquePtr<X509> GetChainTestIntermediate() {
1280 return X509FromBuffer(GetChainTestIntermediateBuffer());
David Benjamin1444c3a2016-12-20 17:23:11 -05001281}
1282
1283static bssl::UniquePtr<EVP_PKEY> GetChainTestKey() {
1284 static const char kKeyPEM[] =
1285 "-----BEGIN PRIVATE KEY-----\n"
1286 "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRvaz8CC/cshpC\n"
1287 "afJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/kLRcH89M\n"
1288 "/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3tHb+xs2P\n"
1289 "Ss8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+cIDs2rQ+l\n"
1290 "P7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1z7C8jU50\n"
1291 "Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9ViLeXANgZ\n"
1292 "i+Xx9KgfAgMBAAECggEBAK0VjSJzkyPaamcyTVSWjo7GdaBGcK60lk657RjR+lK0\n"
1293 "YJ7pkej4oM2hdsVZFsP8Cs4E33nXLa/0pDsRov/qrp0WQm2skwqGMC1I/bZ0WRPk\n"
1294 "wHaDrBBfESWnJDX/AGpVtlyOjPmgmK6J2usMPihQUDkKdAYrVWJePrMIxt1q6BMe\n"
1295 "iczs3qriMmtY3bUc4UyUwJ5fhDLjshHvfuIpYQyI6EXZM6dZksn9LylXJnigY6QJ\n"
1296 "HxOYO0BDwOsZ8yQ8J8afLk88i0GizEkgE1z3REtQUwgWfxr1WV/ud+T6/ZhSAgH9\n"
1297 "042mQvSFZnIUSEsmCvjhWuAunfxHKCTcAoYISWfzWpkCgYEA7gpf3HHU5Tn+CgUn\n"
1298 "1X5uGpG3DmcMgfeGgs2r2f/IIg/5Ac1dfYILiybL1tN9zbyLCJfcbFpWBc9hJL6f\n"
1299 "CPc5hUiwWFJqBJewxQkC1Ae/HakHbip+IZ+Jr0842O4BAArvixk4Lb7/N2Ct9sTE\n"
1300 "NJO6RtK9lbEZ5uK61DglHy8CS2UCgYEA4ZC1o36kPAMQBggajgnucb2yuUEelk0f\n"
1301 "AEr+GI32MGE+93xMr7rAhBoqLg4AITyIfEnOSQ5HwagnIHonBbv1LV/Gf9ursx8Z\n"
1302 "YOGbvT8zzzC+SU1bkDzdjAYnFQVGIjMtKOBJ3K07++ypwX1fr4QsQ8uKL8WSOWwt\n"
1303 "Z3Bym6XiZzMCgYADnhy+2OwHX85AkLt+PyGlPbmuelpyTzS4IDAQbBa6jcuW/2wA\n"
1304 "UE2km75VUXmD+u2R/9zVuLm99NzhFhSMqlUxdV1YukfqMfP5yp1EY6m/5aW7QuIP\n"
1305 "2MDa7TVL9rIFMiVZ09RKvbBbQxjhuzPQKL6X/PPspnhiTefQ+dl2k9xREQKBgHDS\n"
1306 "fMfGNEeAEKezrfSVqxphE9/tXms3L+ZpnCaT+yu/uEr5dTIAawKoQ6i9f/sf1/Sy\n"
1307 "xedsqR+IB+oKrzIDDWMgoJybN4pkZ8E5lzhVQIjFjKgFdWLzzqyW9z1gYfABQPlN\n"
1308 "FiS20WX0vgP1vcKAjdNrHzc9zyHBpgQzDmAj3NZZAoGBAI8vKCKdH7w3aL5CNkZQ\n"
1309 "2buIeWNA2HZazVwAGG5F2TU/LmXfRKnG6dX5bkU+AkBZh56jNZy//hfFSewJB4Kk\n"
1310 "buB7ERSdaNbO21zXt9FEA3+z0RfMd/Zv2vlIWOSB5nzl/7UKti3sribK6s9ZVLfi\n"
1311 "SxpiPQ8d/hmSGwn4ksrWUsJD\n"
1312 "-----END PRIVATE KEY-----\n";
1313 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1314 return bssl::UniquePtr<EVP_PKEY>(
1315 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1316}
1317
David Benjaminc79ae7a2017-08-29 16:09:44 -04001318// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
1319// before configuring as a server.
1320TEST(SSLTest, ClientCAList) {
1321 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1322 ASSERT_TRUE(ctx);
1323 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1324 ASSERT_TRUE(ssl);
1325
1326 bssl::UniquePtr<X509_NAME> name(X509_NAME_new());
1327 ASSERT_TRUE(name);
1328
1329 bssl::UniquePtr<X509_NAME> name_dup(X509_NAME_dup(name.get()));
1330 ASSERT_TRUE(name_dup);
1331
1332 bssl::UniquePtr<STACK_OF(X509_NAME)> stack(sk_X509_NAME_new_null());
1333 ASSERT_TRUE(stack);
1334
1335 ASSERT_TRUE(sk_X509_NAME_push(stack.get(), name_dup.get()));
1336 name_dup.release();
1337
1338 // |SSL_set_client_CA_list| takes ownership.
1339 SSL_set_client_CA_list(ssl.get(), stack.release());
1340
1341 STACK_OF(X509_NAME) *result = SSL_get_client_CA_list(ssl.get());
1342 ASSERT_TRUE(result);
1343 ASSERT_EQ(1u, sk_X509_NAME_num(result));
1344 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(result, 0), name.get()));
1345}
1346
1347TEST(SSLTest, AddClientCA) {
1348 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1349 ASSERT_TRUE(ctx);
1350 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1351 ASSERT_TRUE(ssl);
1352
1353 bssl::UniquePtr<X509> cert1 = GetTestCertificate();
1354 bssl::UniquePtr<X509> cert2 = GetChainTestCertificate();
1355 ASSERT_TRUE(cert1 && cert2);
1356 X509_NAME *name1 = X509_get_subject_name(cert1.get());
1357 X509_NAME *name2 = X509_get_subject_name(cert2.get());
1358
1359 EXPECT_EQ(0u, sk_X509_NAME_num(SSL_get_client_CA_list(ssl.get())));
1360
1361 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1362 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert2.get()));
1363
1364 STACK_OF(X509_NAME) *list = SSL_get_client_CA_list(ssl.get());
1365 ASSERT_EQ(2u, sk_X509_NAME_num(list));
1366 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1367 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1368
1369 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1370
1371 list = SSL_get_client_CA_list(ssl.get());
1372 ASSERT_EQ(3u, sk_X509_NAME_num(list));
1373 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1374 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1375 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 2), name1));
1376}
1377
1378static void AppendSession(SSL_SESSION *session, void *arg) {
1379 std::vector<SSL_SESSION*> *out =
1380 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
1381 out->push_back(session);
1382}
1383
1384// CacheEquals returns true if |ctx|'s session cache consists of |expected|, in
1385// order.
1386static bool CacheEquals(SSL_CTX *ctx,
1387 const std::vector<SSL_SESSION*> &expected) {
1388 // Check the linked list.
1389 SSL_SESSION *ptr = ctx->session_cache_head;
1390 for (SSL_SESSION *session : expected) {
1391 if (ptr != session) {
1392 return false;
1393 }
1394 // TODO(davidben): This is an absurd way to denote the end of the list.
1395 if (ptr->next ==
1396 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
1397 ptr = nullptr;
1398 } else {
1399 ptr = ptr->next;
1400 }
1401 }
1402 if (ptr != nullptr) {
1403 return false;
1404 }
1405
1406 // Check the hash table.
1407 std::vector<SSL_SESSION*> actual, expected_copy;
David Benjamin9eaa3bd2017-09-27 17:03:54 -04001408 lh_SSL_SESSION_doall_arg(ctx->sessions, AppendSession, &actual);
David Benjaminc79ae7a2017-08-29 16:09:44 -04001409 expected_copy = expected;
1410
1411 std::sort(actual.begin(), actual.end());
1412 std::sort(expected_copy.begin(), expected_copy.end());
1413
1414 return actual == expected_copy;
1415}
1416
1417static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
1418 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
1419 if (!ssl_ctx) {
1420 return nullptr;
1421 }
1422 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new(ssl_ctx.get()));
1423 if (!ret) {
1424 return nullptr;
1425 }
1426
1427 ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
1428 OPENSSL_memset(ret->session_id, 0, ret->session_id_length);
1429 OPENSSL_memcpy(ret->session_id, &number, sizeof(number));
1430 return ret;
1431}
1432
1433// Test that the internal session cache behaves as expected.
1434TEST(SSLTest, InternalSessionCache) {
1435 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1436 ASSERT_TRUE(ctx);
1437
1438 // Prepare 10 test sessions.
1439 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
1440 for (int i = 0; i < 10; i++) {
1441 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
1442 ASSERT_TRUE(session);
1443 sessions.push_back(std::move(session));
1444 }
1445
1446 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1447
1448 // Insert all the test sessions.
1449 for (const auto &session : sessions) {
1450 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), session.get()));
1451 }
1452
1453 // Only the last five should be in the list.
1454 ASSERT_TRUE(CacheEquals(
1455 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
1456 sessions[6].get(), sessions[5].get()}));
1457
1458 // Inserting an element already in the cache should fail and leave the cache
1459 // unchanged.
1460 ASSERT_FALSE(SSL_CTX_add_session(ctx.get(), sessions[7].get()));
1461 ASSERT_TRUE(CacheEquals(
1462 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
1463 sessions[6].get(), sessions[5].get()}));
1464
1465 // Although collisions should be impossible (256-bit session IDs), the cache
1466 // must handle them gracefully.
1467 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
1468 ASSERT_TRUE(collision);
1469 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), collision.get()));
1470 ASSERT_TRUE(CacheEquals(
1471 ctx.get(), {collision.get(), sessions[9].get(), sessions[8].get(),
1472 sessions[6].get(), sessions[5].get()}));
1473
1474 // Removing sessions behaves correctly.
1475 ASSERT_TRUE(SSL_CTX_remove_session(ctx.get(), sessions[6].get()));
1476 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
1477 sessions[8].get(), sessions[5].get()}));
1478
1479 // Removing sessions requires an exact match.
1480 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[0].get()));
1481 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[7].get()));
1482
1483 // The cache remains unchanged.
1484 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
1485 sessions[8].get(), sessions[5].get()}));
1486}
1487
1488static uint16_t EpochFromSequence(uint64_t seq) {
1489 return static_cast<uint16_t>(seq >> 48);
1490}
1491
David Benjamin71dfad42017-07-16 17:27:39 -04001492static const uint8_t kTestName[] = {
1493 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
1494 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
1495 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
1496 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
1497 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
1498 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64,
1499};
1500
David Benjaminb79cc842016-12-07 15:57:14 -05001501static bool CompleteHandshakes(SSL *client, SSL *server) {
1502 // Drive both their handshakes to completion.
1503 for (;;) {
1504 int client_ret = SSL_do_handshake(client);
1505 int client_err = SSL_get_error(client, client_ret);
1506 if (client_err != SSL_ERROR_NONE &&
1507 client_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001508 client_err != SSL_ERROR_WANT_WRITE &&
1509 client_err != SSL_ERROR_PENDING_TICKET) {
David Benjaminb79cc842016-12-07 15:57:14 -05001510 fprintf(stderr, "Client error: %d\n", client_err);
1511 return false;
1512 }
1513
1514 int server_ret = SSL_do_handshake(server);
1515 int server_err = SSL_get_error(server, server_ret);
1516 if (server_err != SSL_ERROR_NONE &&
1517 server_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001518 server_err != SSL_ERROR_WANT_WRITE &&
1519 server_err != SSL_ERROR_PENDING_TICKET) {
David Benjaminb79cc842016-12-07 15:57:14 -05001520 fprintf(stderr, "Server error: %d\n", server_err);
1521 return false;
1522 }
1523
1524 if (client_ret == 1 && server_ret == 1) {
1525 break;
1526 }
1527 }
1528
1529 return true;
1530}
1531
David Benjamina8614602017-09-06 15:40:19 -04001532struct ClientConfig {
1533 SSL_SESSION *session = nullptr;
1534 std::string servername;
1535};
1536
David Benjaminb79cc842016-12-07 15:57:14 -05001537static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client,
1538 bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001539 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
David Benjamina8614602017-09-06 15:40:19 -04001540 const ClientConfig &config = ClientConfig()) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001541 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001542 if (!client || !server) {
1543 return false;
1544 }
1545 SSL_set_connect_state(client.get());
1546 SSL_set_accept_state(server.get());
1547
David Benjamina8614602017-09-06 15:40:19 -04001548 if (config.session) {
1549 SSL_set_session(client.get(), config.session);
1550 }
1551 if (!config.servername.empty() &&
1552 !SSL_set_tlsext_host_name(client.get(), config.servername.c_str())) {
1553 return false;
1554 }
David Benjamina20e5352016-08-02 19:09:41 -04001555
David Benjaminde942382016-02-11 12:02:01 -05001556 BIO *bio1, *bio2;
1557 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1558 return false;
1559 }
1560 // SSL_set_bio takes ownership.
1561 SSL_set_bio(client.get(), bio1, bio1);
1562 SSL_set_bio(server.get(), bio2, bio2);
1563
David Benjaminb79cc842016-12-07 15:57:14 -05001564 if (!CompleteHandshakes(client.get(), server.get())) {
1565 return false;
David Benjaminde942382016-02-11 12:02:01 -05001566 }
1567
David Benjamin686bb192016-05-10 15:15:41 -04001568 *out_client = std::move(client);
1569 *out_server = std::move(server);
1570 return true;
1571}
1572
David Benjaminc11ea9422017-08-29 16:33:21 -04001573// SSLVersionTest executes its test cases under all available protocol versions.
1574// Test cases call |Connect| to create a connection using context objects with
1575// the protocol version fixed to the current version under test.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001576class SSLVersionTest : public ::testing::TestWithParam<VersionParam> {
1577 protected:
1578 SSLVersionTest() : cert_(GetTestCertificate()), key_(GetTestKey()) {}
1579
1580 void SetUp() { ResetContexts(); }
1581
1582 bssl::UniquePtr<SSL_CTX> CreateContext() const {
1583 const SSL_METHOD *method = is_dtls() ? DTLS_method() : TLS_method();
1584 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
1585 if (!ctx || !SSL_CTX_set_min_proto_version(ctx.get(), version()) ||
1586 !SSL_CTX_set_max_proto_version(ctx.get(), version())) {
1587 return nullptr;
1588 }
1589 return ctx;
David Benjamin0fef3052016-11-18 15:11:10 +09001590 }
David Benjamin686bb192016-05-10 15:15:41 -04001591
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001592 void ResetContexts() {
1593 ASSERT_TRUE(cert_);
1594 ASSERT_TRUE(key_);
1595 client_ctx_ = CreateContext();
1596 ASSERT_TRUE(client_ctx_);
1597 server_ctx_ = CreateContext();
1598 ASSERT_TRUE(server_ctx_);
1599 // Set up a server cert. Client certs can be set up explicitly.
1600 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09001601 }
David Benjamin686bb192016-05-10 15:15:41 -04001602
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001603 bool UseCertAndKey(SSL_CTX *ctx) const {
1604 return SSL_CTX_use_certificate(ctx, cert_.get()) &&
1605 SSL_CTX_use_PrivateKey(ctx, key_.get());
David Benjamin0fef3052016-11-18 15:11:10 +09001606 }
David Benjamin686bb192016-05-10 15:15:41 -04001607
David Benjamina8614602017-09-06 15:40:19 -04001608 bool Connect(const ClientConfig &config = ClientConfig()) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001609 return ConnectClientAndServer(&client_, &server_, client_ctx_.get(),
David Benjamina8614602017-09-06 15:40:19 -04001610 server_ctx_.get(), config);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001611 }
1612
1613 uint16_t version() const { return GetParam().version; }
1614
1615 bool is_dtls() const {
1616 return GetParam().ssl_method == VersionParam::is_dtls;
1617 }
1618
1619 bssl::UniquePtr<SSL> client_, server_;
1620 bssl::UniquePtr<SSL_CTX> server_ctx_, client_ctx_;
1621 bssl::UniquePtr<X509> cert_;
1622 bssl::UniquePtr<EVP_PKEY> key_;
1623};
1624
1625INSTANTIATE_TEST_CASE_P(WithVersion, SSLVersionTest,
1626 testing::ValuesIn(kAllVersions),
1627 [](const testing::TestParamInfo<VersionParam> &i) {
1628 return i.param.name;
1629 });
1630
1631TEST_P(SSLVersionTest, SequenceNumber) {
1632 ASSERT_TRUE(Connect());
1633
David Benjamin0fef3052016-11-18 15:11:10 +09001634 // Drain any post-handshake messages to ensure there are no unread records
1635 // on either end.
1636 uint8_t byte = 0;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001637 ASSERT_LE(SSL_read(client_.get(), &byte, 1), 0);
1638 ASSERT_LE(SSL_read(server_.get(), &byte, 1), 0);
David Benjaminde942382016-02-11 12:02:01 -05001639
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001640 uint64_t client_read_seq = SSL_get_read_sequence(client_.get());
1641 uint64_t client_write_seq = SSL_get_write_sequence(client_.get());
1642 uint64_t server_read_seq = SSL_get_read_sequence(server_.get());
1643 uint64_t server_write_seq = SSL_get_write_sequence(server_.get());
Steven Valdez2c62fe92016-10-14 12:08:12 -04001644
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001645 if (is_dtls()) {
David Benjamin0fef3052016-11-18 15:11:10 +09001646 // Both client and server must be at epoch 1.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001647 EXPECT_EQ(EpochFromSequence(client_read_seq), 1);
1648 EXPECT_EQ(EpochFromSequence(client_write_seq), 1);
1649 EXPECT_EQ(EpochFromSequence(server_read_seq), 1);
1650 EXPECT_EQ(EpochFromSequence(server_write_seq), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09001651
1652 // The next record to be written should exceed the largest received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001653 EXPECT_GT(client_write_seq, server_read_seq);
1654 EXPECT_GT(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09001655 } else {
1656 // The next record to be written should equal the next to be received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001657 EXPECT_EQ(client_write_seq, server_read_seq);
1658 EXPECT_EQ(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09001659 }
1660
1661 // Send a record from client to server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001662 EXPECT_EQ(SSL_write(client_.get(), &byte, 1), 1);
1663 EXPECT_EQ(SSL_read(server_.get(), &byte, 1), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09001664
1665 // The client write and server read sequence numbers should have
1666 // incremented.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001667 EXPECT_EQ(client_write_seq + 1, SSL_get_write_sequence(client_.get()));
1668 EXPECT_EQ(server_read_seq + 1, SSL_get_read_sequence(server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05001669}
1670
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001671TEST_P(SSLVersionTest, OneSidedShutdown) {
David Benjamin68f37b72016-11-18 15:14:42 +09001672 // SSL_shutdown is a no-op in DTLS.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001673 if (is_dtls()) {
1674 return;
David Benjamin686bb192016-05-10 15:15:41 -04001675 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001676 ASSERT_TRUE(Connect());
David Benjamin686bb192016-05-10 15:15:41 -04001677
1678 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1679 // one side has shut down.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001680 ASSERT_EQ(SSL_shutdown(client_.get()), 0);
David Benjamin686bb192016-05-10 15:15:41 -04001681
1682 // Reading from the server should consume the EOF.
1683 uint8_t byte;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001684 ASSERT_EQ(SSL_read(server_.get(), &byte, 1), 0);
1685 ASSERT_EQ(SSL_get_error(server_.get(), 0), SSL_ERROR_ZERO_RETURN);
David Benjamin686bb192016-05-10 15:15:41 -04001686
1687 // However, the server may continue to write data and then shut down the
1688 // connection.
1689 byte = 42;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001690 ASSERT_EQ(SSL_write(server_.get(), &byte, 1), 1);
1691 ASSERT_EQ(SSL_read(client_.get(), &byte, 1), 1);
1692 ASSERT_EQ(byte, 42);
David Benjamin686bb192016-05-10 15:15:41 -04001693
1694 // The server may then shutdown the connection.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001695 EXPECT_EQ(SSL_shutdown(server_.get()), 1);
1696 EXPECT_EQ(SSL_shutdown(client_.get()), 1);
David Benjamin686bb192016-05-10 15:15:41 -04001697}
David Benjamin68f37b72016-11-18 15:14:42 +09001698
David Benjaminf0d8e222017-02-04 10:58:26 -05001699TEST(SSLTest, SessionDuplication) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001700 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1701 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001702 ASSERT_TRUE(client_ctx);
1703 ASSERT_TRUE(server_ctx);
Steven Valdez87eab492016-06-27 16:34:59 -04001704
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001705 bssl::UniquePtr<X509> cert = GetTestCertificate();
1706 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminf0d8e222017-02-04 10:58:26 -05001707 ASSERT_TRUE(cert);
1708 ASSERT_TRUE(key);
1709 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
1710 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04001711
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001712 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05001713 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04001714 server_ctx.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04001715
1716 SSL_SESSION *session0 = SSL_get_session(client.get());
David Benjamin31b0c9b2017-07-20 14:49:15 -04001717 bssl::UniquePtr<SSL_SESSION> session1 =
1718 bssl::SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL);
David Benjaminf0d8e222017-02-04 10:58:26 -05001719 ASSERT_TRUE(session1);
David Benjamin4501bd52016-08-01 13:39:41 -04001720
Steven Valdez84b5c002016-08-25 16:30:58 -04001721 session1->not_resumable = 0;
1722
Steven Valdez87eab492016-06-27 16:34:59 -04001723 uint8_t *s0_bytes, *s1_bytes;
1724 size_t s0_len, s1_len;
1725
David Benjaminf0d8e222017-02-04 10:58:26 -05001726 ASSERT_TRUE(SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001727 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001728
David Benjaminf0d8e222017-02-04 10:58:26 -05001729 ASSERT_TRUE(SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001730 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001731
David Benjamin7d7554b2017-02-04 11:48:59 -05001732 EXPECT_EQ(Bytes(s0_bytes, s0_len), Bytes(s1_bytes, s1_len));
Steven Valdez87eab492016-06-27 16:34:59 -04001733}
David Benjamin686bb192016-05-10 15:15:41 -04001734
David Benjaminf0d8e222017-02-04 10:58:26 -05001735static void ExpectFDs(const SSL *ssl, int rfd, int wfd) {
David Benjaminca743582017-06-15 17:51:35 -04001736 EXPECT_EQ(rfd, SSL_get_fd(ssl));
David Benjaminf0d8e222017-02-04 10:58:26 -05001737 EXPECT_EQ(rfd, SSL_get_rfd(ssl));
1738 EXPECT_EQ(wfd, SSL_get_wfd(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04001739
1740 // The wrapper BIOs are always equal when fds are equal, even if set
1741 // individually.
David Benjaminf0d8e222017-02-04 10:58:26 -05001742 if (rfd == wfd) {
1743 EXPECT_EQ(SSL_get_rbio(ssl), SSL_get_wbio(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04001744 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001745}
1746
David Benjaminf0d8e222017-02-04 10:58:26 -05001747TEST(SSLTest, SetFD) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001748 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001749 ASSERT_TRUE(ctx);
David Benjamin5c0fb882016-06-14 14:03:51 -04001750
1751 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001752 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001753 ASSERT_TRUE(ssl);
1754 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1755 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
1756 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04001757
1758 // Test setting the same FD.
1759 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001760 ASSERT_TRUE(ssl);
1761 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1762 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001763
1764 // Test setting the same FD one side at a time.
1765 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001766 ASSERT_TRUE(ssl);
1767 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1768 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1769 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001770
1771 // Test setting the same FD in the other order.
1772 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001773 ASSERT_TRUE(ssl);
1774 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1775 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1776 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001777
David Benjamin5c0fb882016-06-14 14:03:51 -04001778 // Test changing the read FD partway through.
1779 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001780 ASSERT_TRUE(ssl);
1781 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1782 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 2));
1783 ExpectFDs(ssl.get(), 2, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001784
1785 // Test changing the write FD partway through.
1786 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001787 ASSERT_TRUE(ssl);
1788 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1789 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
1790 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04001791
1792 // Test a no-op change to the read FD partway through.
1793 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001794 ASSERT_TRUE(ssl);
1795 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1796 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1797 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001798
1799 // Test a no-op change to the write FD partway through.
1800 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001801 ASSERT_TRUE(ssl);
1802 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1803 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1804 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001805
1806 // ASan builds will implicitly test that the internal |BIO| reference-counting
1807 // is correct.
David Benjamin5c0fb882016-06-14 14:03:51 -04001808}
1809
David Benjaminf0d8e222017-02-04 10:58:26 -05001810TEST(SSLTest, SetBIO) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001811 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001812 ASSERT_TRUE(ctx);
David Benjamin4501bd52016-08-01 13:39:41 -04001813
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001814 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1815 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04001816 bio3(BIO_new(BIO_s_mem()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001817 ASSERT_TRUE(ssl);
1818 ASSERT_TRUE(bio1);
1819 ASSERT_TRUE(bio2);
1820 ASSERT_TRUE(bio3);
David Benjamin4501bd52016-08-01 13:39:41 -04001821
1822 // SSL_set_bio takes one reference when the parameters are the same.
1823 BIO_up_ref(bio1.get());
1824 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1825
1826 // Repeating the call does nothing.
1827 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1828
1829 // It takes one reference each when the parameters are different.
1830 BIO_up_ref(bio2.get());
1831 BIO_up_ref(bio3.get());
1832 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1833
1834 // Repeating the call does nothing.
1835 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1836
1837 // It takes one reference when changing only wbio.
1838 BIO_up_ref(bio1.get());
1839 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1840
1841 // It takes one reference when changing only rbio and the two are different.
1842 BIO_up_ref(bio3.get());
1843 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1844
1845 // If setting wbio to rbio, it takes no additional references.
1846 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1847
1848 // From there, wbio may be switched to something else.
1849 BIO_up_ref(bio1.get());
1850 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1851
1852 // If setting rbio to wbio, it takes no additional references.
1853 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1854
1855 // From there, rbio may be switched to something else, but, for historical
1856 // reasons, it takes a reference to both parameters.
1857 BIO_up_ref(bio1.get());
1858 BIO_up_ref(bio2.get());
1859 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1860
1861 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1862 // is correct.
David Benjamin4501bd52016-08-01 13:39:41 -04001863}
1864
David Benjamin25490f22016-07-14 00:22:54 -04001865static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1866
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001867TEST_P(SSLVersionTest, GetPeerCertificate) {
1868 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04001869
David Benjamin0fef3052016-11-18 15:11:10 +09001870 // Configure both client and server to accept any certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001871 SSL_CTX_set_verify(client_ctx_.get(),
1872 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1873 nullptr);
1874 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
1875 SSL_CTX_set_verify(server_ctx_.get(),
1876 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1877 nullptr);
1878 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjaminadd5e522016-07-14 00:33:24 -04001879
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001880 ASSERT_TRUE(Connect());
David Benjaminadd5e522016-07-14 00:33:24 -04001881
David Benjamin0fef3052016-11-18 15:11:10 +09001882 // Client and server should both see the leaf certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001883 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1884 ASSERT_TRUE(peer);
1885 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04001886
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001887 peer.reset(SSL_get_peer_certificate(client_.get()));
1888 ASSERT_TRUE(peer);
1889 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04001890
David Benjamine664a532017-07-20 20:19:36 -04001891 // However, for historical reasons, the X509 chain includes the leaf on the
David Benjamin0fef3052016-11-18 15:11:10 +09001892 // client, but does not on the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001893 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(client_.get())), 1u);
1894 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(client_.get())),
1895 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04001896
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001897 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(server_.get())), 0u);
1898 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(server_.get())),
1899 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04001900}
1901
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001902TEST_P(SSLVersionTest, NoPeerCertificate) {
1903 SSL_CTX_set_verify(server_ctx_.get(), SSL_VERIFY_PEER, nullptr);
1904 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
1905 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
David Benjamine664a532017-07-20 20:19:36 -04001906
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001907 ASSERT_TRUE(Connect());
David Benjamine664a532017-07-20 20:19:36 -04001908
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001909 // Server should not see a peer certificate.
1910 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1911 ASSERT_FALSE(peer);
1912 ASSERT_FALSE(SSL_get0_peer_certificates(server_.get()));
David Benjamine664a532017-07-20 20:19:36 -04001913}
1914
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001915TEST_P(SSLVersionTest, RetainOnlySHA256OfCerts) {
David Benjamin25490f22016-07-14 00:22:54 -04001916 uint8_t *cert_der = NULL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001917 int cert_der_len = i2d_X509(cert_.get(), &cert_der);
1918 ASSERT_GE(cert_der_len, 0);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001919 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04001920
1921 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1922 SHA256(cert_der, cert_der_len, cert_sha256);
1923
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001924 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
1925
David Benjamin0fef3052016-11-18 15:11:10 +09001926 // Configure both client and server to accept any certificate, but the
1927 // server must retain only the SHA-256 of the peer.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001928 SSL_CTX_set_verify(client_ctx_.get(),
1929 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1930 nullptr);
1931 SSL_CTX_set_verify(server_ctx_.get(),
1932 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1933 nullptr);
1934 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
1935 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
1936 SSL_CTX_set_retain_only_sha256_of_client_certs(server_ctx_.get(), 1);
David Benjamin25490f22016-07-14 00:22:54 -04001937
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001938 ASSERT_TRUE(Connect());
David Benjamin25490f22016-07-14 00:22:54 -04001939
David Benjamin0fef3052016-11-18 15:11:10 +09001940 // The peer certificate has been dropped.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001941 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1942 EXPECT_FALSE(peer);
David Benjamin25490f22016-07-14 00:22:54 -04001943
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001944 SSL_SESSION *session = SSL_get_session(server_.get());
1945 EXPECT_TRUE(session->peer_sha256_valid);
David Benjamin25490f22016-07-14 00:22:54 -04001946
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001947 EXPECT_EQ(Bytes(cert_sha256), Bytes(session->peer_sha256));
David Benjamin25490f22016-07-14 00:22:54 -04001948}
1949
David Benjamin737d2df2017-09-25 15:05:19 -04001950// Tests that our ClientHellos do not change unexpectedly. These are purely
1951// change detection tests. If they fail as part of an intentional ClientHello
1952// change, update the test vector.
1953TEST(SSLTest, ClientHello) {
1954 struct {
1955 uint16_t max_version;
1956 std::vector<uint8_t> expected;
1957 } kTests[] = {
1958 {SSL3_VERSION,
1959 {0x16, 0x03, 0x00, 0x00, 0x3b, 0x01, 0x00, 0x00, 0x37, 0x03, 0x00,
1960 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1961 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1962 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1963 0x00, 0x10, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00,
1964 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x00, 0xff, 0x01, 0x00}},
1965 {TLS1_VERSION,
1966 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x01, 0x00,
1967 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1968 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1969 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
1970 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001971 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1972 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
David Benjamin737d2df2017-09-25 15:05:19 -04001973 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18}},
1974 {TLS1_1_VERSION,
1975 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x02, 0x00,
1976 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1977 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1978 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
1979 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001980 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1981 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
David Benjamin737d2df2017-09-25 15:05:19 -04001982 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18}},
David Benjamin737d2df2017-09-25 15:05:19 -04001983 {TLS1_2_VERSION,
1984 {0x16, 0x03, 0x01, 0x00, 0x8e, 0x01, 0x00, 0x00, 0x8a, 0x03, 0x03, 0x00,
1985 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1986 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1987 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0xcc, 0xa9,
1988 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xc0, 0x09,
1989 0xc0, 0x23, 0xc0, 0x13, 0xc0, 0x27, 0xc0, 0x0a, 0xc0, 0x24, 0xc0, 0x14,
1990 0xc0, 0x28, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x3c, 0x00, 0x35,
1991 0x00, 0x3d, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37, 0xff, 0x01, 0x00, 0x01,
1992 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
1993 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
1994 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x00, 0x0b, 0x00,
1995 0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00,
1996 0x17, 0x00, 0x18}},
David Benjamin737d2df2017-09-25 15:05:19 -04001997 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
1998 // implementation has settled enough that it won't change.
David Benjaminafc64de2016-07-19 17:12:41 +02001999 };
David Benjamin737d2df2017-09-25 15:05:19 -04002000
2001 for (const auto &t : kTests) {
2002 SCOPED_TRACE(t.max_version);
2003
2004 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2005 ASSERT_TRUE(ctx);
2006 // Our default cipher list varies by CPU capabilities, so manually place the
2007 // ChaCha20 ciphers in front.
2008 const char *cipher_list = "CHACHA20:ALL";
2009 // SSLv3 is off by default.
2010 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION));
2011 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), t.max_version));
2012 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list));
2013
2014 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
2015 ASSERT_TRUE(ssl);
2016 std::vector<uint8_t> client_hello;
2017 ASSERT_TRUE(GetClientHello(ssl.get(), &client_hello));
2018
2019 // Zero the client_random.
2020 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
2021 1 + 3 + // handshake message header
2022 2; // client_version
2023 ASSERT_GE(client_hello.size(), kRandomOffset + SSL3_RANDOM_SIZE);
2024 OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
2025
2026 if (client_hello != t.expected) {
2027 ADD_FAILURE() << "ClientHellos did not match.";
2028 // Print the value manually so it is easier to update the test vector.
2029 for (size_t i = 0; i < client_hello.size(); i += 12) {
2030 printf(" %c", i == 0 ? '{' : ' ');
2031 for (size_t j = i; j < client_hello.size() && j < i + 12; j++) {
2032 if (j > i) {
2033 printf(" ");
2034 }
2035 printf("0x%02x", client_hello[j]);
2036 if (j < client_hello.size() - 1) {
2037 printf(",");
2038 }
2039 }
2040 if (i + 12 >= client_hello.size()) {
2041 printf("}}");
2042 }
2043 printf("\n");
2044 }
2045 }
David Benjaminafc64de2016-07-19 17:12:41 +02002046 }
David Benjaminafc64de2016-07-19 17:12:41 +02002047}
2048
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002049static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04002050
2051static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
2052 // Save the most recent session.
2053 g_last_session.reset(session);
2054 return 1;
2055}
2056
David Benjamina8614602017-09-06 15:40:19 -04002057static bssl::UniquePtr<SSL_SESSION> CreateClientSession(
2058 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2059 const ClientConfig &config = ClientConfig()) {
David Benjamina20e5352016-08-02 19:09:41 -04002060 g_last_session = nullptr;
2061 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2062
2063 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002064 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04002065 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
David Benjamina8614602017-09-06 15:40:19 -04002066 config)) {
David Benjamina20e5352016-08-02 19:09:41 -04002067 fprintf(stderr, "Failed to connect client and server.\n");
2068 return nullptr;
2069 }
2070
2071 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2072 SSL_read(client.get(), nullptr, 0);
2073
2074 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2075
2076 if (!g_last_session) {
2077 fprintf(stderr, "Client did not receive a session.\n");
2078 return nullptr;
2079 }
2080 return std::move(g_last_session);
2081}
2082
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002083static void ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2084 SSL_SESSION *session, bool want_reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002085 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002086 ClientConfig config;
2087 config.session = session;
2088 EXPECT_TRUE(
2089 ConnectClientAndServer(&client, &server, client_ctx, server_ctx, config));
David Benjamina20e5352016-08-02 19:09:41 -04002090
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002091 EXPECT_EQ(SSL_session_reused(client.get()), SSL_session_reused(server.get()));
David Benjamina20e5352016-08-02 19:09:41 -04002092
2093 bool was_reused = !!SSL_session_reused(client.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002094 EXPECT_EQ(was_reused, want_reused);
David Benjamina20e5352016-08-02 19:09:41 -04002095}
2096
David Benjamin3c51d9b2016-11-01 17:50:42 -04002097static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
2098 SSL_CTX *server_ctx,
2099 SSL_SESSION *session) {
2100 g_last_session = nullptr;
2101 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2102
2103 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002104 ClientConfig config;
2105 config.session = session;
2106 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
2107 config)) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002108 fprintf(stderr, "Failed to connect client and server.\n");
2109 return nullptr;
2110 }
2111
2112 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2113 fprintf(stderr, "Client and server were inconsistent.\n");
2114 return nullptr;
2115 }
2116
2117 if (!SSL_session_reused(client.get())) {
2118 fprintf(stderr, "Session was not reused.\n");
2119 return nullptr;
2120 }
2121
2122 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2123 SSL_read(client.get(), nullptr, 0);
2124
2125 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2126
2127 if (!g_last_session) {
2128 fprintf(stderr, "Client did not receive a renewed session.\n");
2129 return nullptr;
2130 }
2131 return std::move(g_last_session);
2132}
2133
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002134static void ExpectTicketKeyChanged(SSL_CTX *ctx, uint8_t *inout_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002135 bool changed) {
2136 uint8_t new_key[kTicketKeyLen];
David Benjaminc11ea9422017-08-29 16:33:21 -04002137 // May return 0, 1 or 48.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002138 ASSERT_EQ(SSL_CTX_get_tlsext_ticket_keys(ctx, new_key, kTicketKeyLen), 1);
2139 if (changed) {
2140 ASSERT_NE(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
2141 } else {
2142 ASSERT_EQ(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002143 }
2144 OPENSSL_memcpy(inout_key, new_key, kTicketKeyLen);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002145}
2146
David Benjamina933c382016-10-28 00:10:03 -04002147static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
2148 static const uint8_t kContext[] = {3};
2149
2150 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
2151 return SSL_TLSEXT_ERR_ALERT_FATAL;
2152 }
2153
2154 return SSL_TLSEXT_ERR_OK;
2155}
2156
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002157TEST_P(SSLVersionTest, SessionIDContext) {
David Benjamina20e5352016-08-02 19:09:41 -04002158 static const uint8_t kContext1[] = {1};
2159 static const uint8_t kContext2[] = {2};
2160
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002161 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2162 sizeof(kContext1)));
David Benjamina20e5352016-08-02 19:09:41 -04002163
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002164 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2165 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002166
David Benjamin0fef3052016-11-18 15:11:10 +09002167 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002168 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2169 ASSERT_TRUE(session);
David Benjamina20e5352016-08-02 19:09:41 -04002170
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002171 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2172 session.get(),
2173 true /* expect session reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002174
David Benjamin0fef3052016-11-18 15:11:10 +09002175 // Change the session ID context.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002176 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext2,
2177 sizeof(kContext2)));
David Benjamina20e5352016-08-02 19:09:41 -04002178
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002179 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2180 session.get(),
2181 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002182
David Benjamin0fef3052016-11-18 15:11:10 +09002183 // Change the session ID context back and install an SNI callback to switch
2184 // it.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002185 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2186 sizeof(kContext1)));
David Benjamina933c382016-10-28 00:10:03 -04002187
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002188 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09002189 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04002190
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002191 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2192 session.get(),
2193 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002194
David Benjamin0fef3052016-11-18 15:11:10 +09002195 // Switch the session ID context with the early callback instead.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002196 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), nullptr);
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002197 SSL_CTX_set_select_certificate_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002198 server_ctx_.get(),
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002199 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
2200 static const uint8_t kContext[] = {3};
2201
2202 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
2203 sizeof(kContext))) {
2204 return ssl_select_cert_error;
2205 }
2206
2207 return ssl_select_cert_success;
2208 });
David Benjamina933c382016-10-28 00:10:03 -04002209
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002210 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2211 session.get(),
2212 false /* expect session not reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002213}
2214
David Benjamin721e8b72016-08-03 13:13:17 -04002215static timeval g_current_time;
2216
2217static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2218 *out_clock = g_current_time;
2219}
2220
David Benjamin17b30832017-01-28 14:00:32 -05002221static void FrozenTimeCallback(const SSL *ssl, timeval *out_clock) {
2222 out_clock->tv_sec = 1000;
2223 out_clock->tv_usec = 0;
2224}
2225
David Benjamin3c51d9b2016-11-01 17:50:42 -04002226static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
2227 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
2228 int encrypt) {
2229 static const uint8_t kZeros[16] = {0};
2230
2231 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -05002232 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamin3c51d9b2016-11-01 17:50:42 -04002233 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -05002234 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002235 return 0;
2236 }
2237
2238 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
2239 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
2240 return -1;
2241 }
2242
2243 // Returning two from the callback in decrypt mode renews the
2244 // session in TLS 1.2 and below.
2245 return encrypt ? 1 : 2;
2246}
2247
David Benjamin123db572016-11-03 16:59:25 -04002248static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjamin123db572016-11-03 16:59:25 -04002249 if (session->tlsext_ticklen < 16 + 16 + SHA256_DIGEST_LENGTH) {
2250 return false;
2251 }
2252
David Benjamin123db572016-11-03 16:59:25 -04002253 const uint8_t *ciphertext = session->tlsext_tick + 16 + 16;
2254 size_t len = session->tlsext_ticklen - 16 - 16 - SHA256_DIGEST_LENGTH;
2255 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
2256
David Benjamin9b63f292016-11-15 00:44:05 -05002257#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
2258 // Fuzzer-mode tickets are unencrypted.
David Benjamin17cf2cb2016-12-13 01:07:13 -05002259 OPENSSL_memcpy(plaintext.get(), ciphertext, len);
David Benjamin9b63f292016-11-15 00:44:05 -05002260#else
2261 static const uint8_t kZeros[16] = {0};
2262 const uint8_t *iv = session->tlsext_tick + 16;
David Benjamin123db572016-11-03 16:59:25 -04002263 bssl::ScopedEVP_CIPHER_CTX ctx;
2264 int len1, len2;
2265 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
2266 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
2267 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
2268 return false;
2269 }
2270
2271 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05002272#endif
David Benjamin123db572016-11-03 16:59:25 -04002273
Adam Langley46db7af2017-02-01 15:49:37 -08002274 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
2275 if (!ssl_ctx) {
2276 return false;
2277 }
David Benjamin123db572016-11-03 16:59:25 -04002278 bssl::UniquePtr<SSL_SESSION> server_session(
Adam Langley46db7af2017-02-01 15:49:37 -08002279 SSL_SESSION_from_bytes(plaintext.get(), len, ssl_ctx.get()));
David Benjamin123db572016-11-03 16:59:25 -04002280 if (!server_session) {
2281 return false;
2282 }
2283
2284 *out = server_session->time;
2285 return true;
2286}
2287
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002288TEST_P(SSLVersionTest, SessionTimeout) {
2289 for (bool server_test : {false, true}) {
2290 SCOPED_TRACE(server_test);
David Benjamin721e8b72016-08-03 13:13:17 -04002291
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002292 ResetContexts();
2293 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2294 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
2295
David Benjamin17b30832017-01-28 14:00:32 -05002296 static const time_t kStartTime = 1000;
David Benjamin0fef3052016-11-18 15:11:10 +09002297 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002298
David Benjamin17b30832017-01-28 14:00:32 -05002299 // We are willing to use a longer lifetime for TLS 1.3 sessions as
2300 // resumptions still perform ECDHE.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002301 const time_t timeout = version() == TLS1_3_VERSION
David Benjamin17b30832017-01-28 14:00:32 -05002302 ? SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT
2303 : SSL_DEFAULT_SESSION_TIMEOUT;
2304
David Benjamin17b30832017-01-28 14:00:32 -05002305 // Both client and server must enforce session timeouts. We configure the
2306 // other side with a frozen clock so it never expires tickets.
David Benjamin0fef3052016-11-18 15:11:10 +09002307 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002308 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2309 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002310 } else {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002311 SSL_CTX_set_current_time_cb(client_ctx_.get(), CurrentTimeCallback);
2312 SSL_CTX_set_current_time_cb(server_ctx_.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002313 }
2314
2315 // Configure a ticket callback which renews tickets.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002316 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002317
2318 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002319 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2320 ASSERT_TRUE(session);
David Benjamin0fef3052016-11-18 15:11:10 +09002321
2322 // Advance the clock just behind the timeout.
David Benjamin17b30832017-01-28 14:00:32 -05002323 g_current_time.tv_sec += timeout - 1;
David Benjamin0fef3052016-11-18 15:11:10 +09002324
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002325 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2326 session.get(),
2327 true /* expect session reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002328
2329 // Advance the clock one more second.
2330 g_current_time.tv_sec++;
2331
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002332 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2333 session.get(),
2334 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002335
2336 // Rewind the clock to before the session was minted.
2337 g_current_time.tv_sec = kStartTime - 1;
2338
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002339 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2340 session.get(),
2341 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002342
2343 // SSL 3.0 cannot renew sessions.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002344 if (version() == SSL3_VERSION) {
David Benjamin0fef3052016-11-18 15:11:10 +09002345 continue;
2346 }
2347
2348 // Renew the session 10 seconds before expiration.
David Benjamin17b30832017-01-28 14:00:32 -05002349 time_t new_start_time = kStartTime + timeout - 10;
2350 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002351 bssl::UniquePtr<SSL_SESSION> new_session = ExpectSessionRenewed(
2352 client_ctx_.get(), server_ctx_.get(), session.get());
2353 ASSERT_TRUE(new_session);
David Benjamin0fef3052016-11-18 15:11:10 +09002354
2355 // This new session is not the same object as before.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002356 EXPECT_NE(session.get(), new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002357
2358 // Check the sessions have timestamps measured from issuance.
2359 long session_time = 0;
2360 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002361 ASSERT_TRUE(GetServerTicketTime(&session_time, new_session.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09002362 } else {
2363 session_time = new_session->time;
2364 }
David Benjamin721e8b72016-08-03 13:13:17 -04002365
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002366 ASSERT_EQ(session_time, g_current_time.tv_sec);
David Benjamin721e8b72016-08-03 13:13:17 -04002367
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002368 if (version() == TLS1_3_VERSION) {
David Benjamin17b30832017-01-28 14:00:32 -05002369 // Renewal incorporates fresh key material in TLS 1.3, so we extend the
2370 // lifetime TLS 1.3.
2371 g_current_time.tv_sec = new_start_time + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002372 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2373 new_session.get(),
2374 true /* expect session reused */));
David Benjamin721e8b72016-08-03 13:13:17 -04002375
David Benjamin17b30832017-01-28 14:00:32 -05002376 // The new session expires after the new timeout.
2377 g_current_time.tv_sec = new_start_time + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002378 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2379 new_session.get(),
2380 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002381
2382 // Renew the session until it begins just past the auth timeout.
2383 time_t auth_end_time = kStartTime + SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
2384 while (new_start_time < auth_end_time - 1000) {
2385 // Get as close as possible to target start time.
2386 new_start_time =
2387 std::min(auth_end_time - 1000, new_start_time + timeout - 1);
2388 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002389 new_session = ExpectSessionRenewed(client_ctx_.get(), server_ctx_.get(),
David Benjamin17b30832017-01-28 14:00:32 -05002390 new_session.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002391 ASSERT_TRUE(new_session);
David Benjamin17b30832017-01-28 14:00:32 -05002392 }
2393
2394 // Now the session's lifetime is bound by the auth timeout.
2395 g_current_time.tv_sec = auth_end_time - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002396 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2397 new_session.get(),
2398 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002399
2400 g_current_time.tv_sec = auth_end_time + 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 } else {
2405 // The new session is usable just before the old expiration.
2406 g_current_time.tv_sec = kStartTime + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002407 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2408 new_session.get(),
2409 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002410
2411 // Renewal does not extend the lifetime, so it is not usable beyond the
2412 // old expiration.
2413 g_current_time.tv_sec = kStartTime + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002414 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2415 new_session.get(),
2416 false /* expect session not reused */));
David Benjamin1b22f852016-10-27 16:36:32 -04002417 }
David Benjamin721e8b72016-08-03 13:13:17 -04002418 }
David Benjamin721e8b72016-08-03 13:13:17 -04002419}
2420
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002421TEST_P(SSLVersionTest, DefaultTicketKeyInitialization) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002422 static const uint8_t kZeroKey[kTicketKeyLen] = {};
2423 uint8_t ticket_key[kTicketKeyLen];
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002424 ASSERT_EQ(1, SSL_CTX_get_tlsext_ticket_keys(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002425 kTicketKeyLen));
2426 ASSERT_NE(0, OPENSSL_memcmp(ticket_key, kZeroKey, kTicketKeyLen));
2427}
2428
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002429TEST_P(SSLVersionTest, DefaultTicketKeyRotation) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002430 if (GetParam().version == SSL3_VERSION) {
2431 return;
2432 }
2433
2434 static const time_t kStartTime = 1001;
2435 g_current_time.tv_sec = kStartTime;
2436 uint8_t ticket_key[kTicketKeyLen];
2437
David Benjaminc11ea9422017-08-29 16:33:21 -04002438 // We use session reuse as a proxy for ticket decryption success, hence
2439 // disable session timeouts.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002440 SSL_CTX_set_timeout(server_ctx_.get(), std::numeric_limits<uint32_t>::max());
2441 SSL_CTX_set_session_psk_dhe_timeout(server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002442 std::numeric_limits<uint32_t>::max());
2443
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002444 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2445 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002446
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002447 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2448 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_OFF);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002449
David Benjaminc11ea9422017-08-29 16:33:21 -04002450 // Initialize ticket_key with the current key.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002451 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2452 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002453
David Benjaminc11ea9422017-08-29 16:33:21 -04002454 // Verify ticket resumption actually works.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002455 bssl::UniquePtr<SSL> client, server;
2456 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002457 CreateClientSession(client_ctx_.get(), server_ctx_.get());
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002458 ASSERT_TRUE(session);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002459 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002460 session.get(), true /* reused */));
2461
David Benjaminc11ea9422017-08-29 16:33:21 -04002462 // Advance time to just before key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002463 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002464 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002465 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002466 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002467 false /* NOT changed */));
2468
David Benjaminc11ea9422017-08-29 16:33:21 -04002469 // Force key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002470 g_current_time.tv_sec += 1;
2471 bssl::UniquePtr<SSL_SESSION> new_session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002472 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2473 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2474 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002475
David Benjaminc11ea9422017-08-29 16:33:21 -04002476 // Resumption with both old and new ticket should work.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002477 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002478 session.get(), true /* reused */));
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 new_session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002481 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002482 false /* NOT changed */));
2483
David Benjaminc11ea9422017-08-29 16:33:21 -04002484 // Force key rotation again. Resumption with the old ticket now fails.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002485 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002486 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002487 session.get(), false /* NOT reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002488 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2489 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002490
David Benjaminc11ea9422017-08-29 16:33:21 -04002491 // But resumption with the newer session still works.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002492 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002493 new_session.get(), true /* reused */));
2494}
2495
David Benjamin0fc37ef2016-08-17 15:29:46 -04002496static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002497 SSL_CTX *ctx = reinterpret_cast<SSL_CTX *>(arg);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002498 SSL_set_SSL_CTX(ssl, ctx);
2499 return SSL_TLSEXT_ERR_OK;
2500}
2501
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002502TEST_P(SSLVersionTest, SNICallback) {
David Benjamin0fef3052016-11-18 15:11:10 +09002503 // SSL 3.0 lacks extensions.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002504 if (version() == SSL3_VERSION) {
2505 return;
David Benjamin0fef3052016-11-18 15:11:10 +09002506 }
2507
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002508 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002509 ASSERT_TRUE(cert2);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002510 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002511 ASSERT_TRUE(key2);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002512
David Benjamin0fef3052016-11-18 15:11:10 +09002513 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
2514 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002515
David Benjamin83a32122017-02-14 18:34:54 -05002516 static const uint8_t kSCTList[] = {0, 6, 0, 4, 5, 6, 7, 8};
2517 static const uint8_t kOCSPResponse[] = {1, 2, 3, 4};
2518
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002519 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
2520 ASSERT_TRUE(server_ctx2);
2521 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()));
2522 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()));
2523 ASSERT_TRUE(SSL_CTX_set_signed_cert_timestamp_list(
2524 server_ctx2.get(), kSCTList, sizeof(kSCTList)));
2525 ASSERT_TRUE(SSL_CTX_set_ocsp_response(server_ctx2.get(), kOCSPResponse,
2526 sizeof(kOCSPResponse)));
2527 // Historically signing preferences would be lost in some cases with the
2528 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2529 // this doesn't happen when |version| is TLS 1.2, configure the private
2530 // key to only sign SHA-256.
2531 ASSERT_TRUE(SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
2532 &kECDSAWithSHA256, 1));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002533
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002534 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), SwitchContext);
2535 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002536
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002537 SSL_CTX_enable_signed_cert_timestamps(client_ctx_.get());
2538 SSL_CTX_enable_ocsp_stapling(client_ctx_.get());
David Benjamin83a32122017-02-14 18:34:54 -05002539
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002540 ASSERT_TRUE(Connect());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002541
David Benjamin0fef3052016-11-18 15:11:10 +09002542 // The client should have received |cert2|.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002543 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client_.get()));
2544 ASSERT_TRUE(peer);
2545 EXPECT_EQ(X509_cmp(peer.get(), cert2.get()), 0);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002546
David Benjamin83a32122017-02-14 18:34:54 -05002547 // The client should have received |server_ctx2|'s SCT list.
2548 const uint8_t *data;
2549 size_t len;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002550 SSL_get0_signed_cert_timestamp_list(client_.get(), &data, &len);
2551 EXPECT_EQ(Bytes(kSCTList), Bytes(data, len));
David Benjamin83a32122017-02-14 18:34:54 -05002552
2553 // The client should have received |server_ctx2|'s OCSP response.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002554 SSL_get0_ocsp_response(client_.get(), &data, &len);
2555 EXPECT_EQ(Bytes(kOCSPResponse), Bytes(data, len));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002556}
2557
David Benjaminf0d8e222017-02-04 10:58:26 -05002558// Test that the early callback can swap the maximum version.
2559TEST(SSLTest, EarlyCallbackVersionSwitch) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002560 bssl::UniquePtr<X509> cert = GetTestCertificate();
2561 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2562 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2563 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002564 ASSERT_TRUE(cert);
2565 ASSERT_TRUE(key);
2566 ASSERT_TRUE(server_ctx);
2567 ASSERT_TRUE(client_ctx);
2568 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
2569 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
2570 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
2571 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
David Benjamin99620572016-08-30 00:35:36 -04002572
David Benjaminf0d8e222017-02-04 10:58:26 -05002573 SSL_CTX_set_select_certificate_cb(
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002574 server_ctx.get(),
2575 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
David Benjaminf0d8e222017-02-04 10:58:26 -05002576 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002577 return ssl_select_cert_error;
David Benjaminf0d8e222017-02-04 10:58:26 -05002578 }
2579
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002580 return ssl_select_cert_success;
David Benjaminf0d8e222017-02-04 10:58:26 -05002581 });
David Benjamin99620572016-08-30 00:35:36 -04002582
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002583 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05002584 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04002585 server_ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002586 EXPECT_EQ(TLS1_2_VERSION, SSL_version(client.get()));
David Benjamin99620572016-08-30 00:35:36 -04002587}
2588
David Benjaminf0d8e222017-02-04 10:58:26 -05002589TEST(SSLTest, SetVersion) {
David Benjamin2dc02042016-09-19 19:57:37 -04002590 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002591 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002592
David Benjaminf0d8e222017-02-04 10:58:26 -05002593 // Set valid TLS versions.
2594 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2595 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
2596 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2597 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002598
David Benjaminf0d8e222017-02-04 10:58:26 -05002599 // Invalid TLS versions are rejected.
2600 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2601 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x0200));
2602 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2603 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2604 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x0200));
2605 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002606
David Benjaminf0d8e222017-02-04 10:58:26 -05002607 // Zero is the default version.
2608 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002609 EXPECT_EQ(TLS1_2_VERSION, ctx->conf_max_version);
David Benjaminf0d8e222017-02-04 10:58:26 -05002610 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002611 EXPECT_EQ(TLS1_VERSION, ctx->conf_min_version);
David Benjamin3cfeb952017-03-01 16:48:38 -05002612
2613 // SSL 3.0 and TLS 1.3 are available, but not by default.
2614 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002615 EXPECT_EQ(SSL3_VERSION, ctx->conf_min_version);
David Benjamin3cfeb952017-03-01 16:48:38 -05002616 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002617 EXPECT_EQ(TLS1_3_VERSION, ctx->conf_max_version);
David Benjamine34bcc92016-09-21 16:53:09 -04002618
David Benjamin353577c2017-06-29 15:54:58 -04002619 // TLS1_3_DRAFT_VERSION is not an API-level version.
Steven Valdez64cc1212017-12-04 11:15:37 -05002620 EXPECT_FALSE(
2621 SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_DRAFT22_VERSION));
David Benjamin353577c2017-06-29 15:54:58 -04002622 ERR_clear_error();
2623
David Benjamin2dc02042016-09-19 19:57:37 -04002624 ctx.reset(SSL_CTX_new(DTLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002625 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002626
David Benjaminf0d8e222017-02-04 10:58:26 -05002627 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2628 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION));
2629 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2630 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002631
David Benjaminf0d8e222017-02-04 10:58:26 -05002632 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2633 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2634 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2635 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2636 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2637 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2638 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2639 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002640
David Benjaminf0d8e222017-02-04 10:58:26 -05002641 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002642 EXPECT_EQ(TLS1_2_VERSION, ctx->conf_max_version);
David Benjaminf0d8e222017-02-04 10:58:26 -05002643 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002644 EXPECT_EQ(TLS1_1_VERSION, ctx->conf_min_version);
David Benjamin2dc02042016-09-19 19:57:37 -04002645}
2646
David Benjamin458334a2016-12-15 13:53:25 -05002647static const char *GetVersionName(uint16_t version) {
2648 switch (version) {
2649 case SSL3_VERSION:
2650 return "SSLv3";
2651 case TLS1_VERSION:
2652 return "TLSv1";
2653 case TLS1_1_VERSION:
2654 return "TLSv1.1";
2655 case TLS1_2_VERSION:
2656 return "TLSv1.2";
2657 case TLS1_3_VERSION:
2658 return "TLSv1.3";
2659 case DTLS1_VERSION:
2660 return "DTLSv1";
2661 case DTLS1_2_VERSION:
2662 return "DTLSv1.2";
2663 default:
2664 return "???";
2665 }
2666}
2667
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002668TEST_P(SSLVersionTest, Version) {
2669 ASSERT_TRUE(Connect());
David Benjamincb18ac22016-09-27 14:09:15 -04002670
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002671 EXPECT_EQ(SSL_version(client_.get()), version());
2672 EXPECT_EQ(SSL_version(server_.get()), version());
David Benjamincb18ac22016-09-27 14:09:15 -04002673
David Benjamin458334a2016-12-15 13:53:25 -05002674 // Test the version name is reported as expected.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002675 const char *version_name = GetVersionName(version());
2676 EXPECT_EQ(strcmp(version_name, SSL_get_version(client_.get())), 0);
2677 EXPECT_EQ(strcmp(version_name, SSL_get_version(server_.get())), 0);
David Benjamin458334a2016-12-15 13:53:25 -05002678
2679 // Test SSL_SESSION reports the same name.
2680 const char *client_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002681 SSL_SESSION_get_version(SSL_get_session(client_.get()));
David Benjamin458334a2016-12-15 13:53:25 -05002682 const char *server_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002683 SSL_SESSION_get_version(SSL_get_session(server_.get()));
2684 EXPECT_EQ(strcmp(version_name, client_name), 0);
2685 EXPECT_EQ(strcmp(version_name, server_name), 0);
David Benjamincb18ac22016-09-27 14:09:15 -04002686}
2687
David Benjamin9ef31f02016-10-31 18:01:13 -04002688// Tests that that |SSL_get_pending_cipher| is available during the ALPN
2689// selection callback.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002690TEST_P(SSLVersionTest, ALPNCipherAvailable) {
David Benjamin0fef3052016-11-18 15:11:10 +09002691 // SSL 3.0 lacks extensions.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002692 if (version() == SSL3_VERSION) {
2693 return;
David Benjamin0fef3052016-11-18 15:11:10 +09002694 }
2695
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002696 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2697
David Benjamin9ef31f02016-10-31 18:01:13 -04002698 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002699 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
2700 sizeof(kALPNProtos)),
2701 0);
David Benjamin0fef3052016-11-18 15:11:10 +09002702
2703 // The ALPN callback does not fail the handshake on error, so have the
2704 // callback write a boolean.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002705 std::pair<uint16_t, bool> callback_state(version(), false);
David Benjamin0fef3052016-11-18 15:11:10 +09002706 SSL_CTX_set_alpn_select_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002707 server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09002708 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
2709 unsigned in_len, void *arg) -> int {
2710 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
2711 if (SSL_get_pending_cipher(ssl) != nullptr &&
2712 SSL_version(ssl) == state->first) {
2713 state->second = true;
2714 }
2715 return SSL_TLSEXT_ERR_NOACK;
2716 },
2717 &callback_state);
2718
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002719 ASSERT_TRUE(Connect());
David Benjamin0fef3052016-11-18 15:11:10 +09002720
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002721 ASSERT_TRUE(callback_state.second);
David Benjamin0fef3052016-11-18 15:11:10 +09002722}
2723
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002724TEST_P(SSLVersionTest, SSLClearSessionResumption) {
David Benjaminb79cc842016-12-07 15:57:14 -05002725 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
2726 // API pattern.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002727 if (version() == TLS1_3_VERSION) {
2728 return;
David Benjaminb79cc842016-12-07 15:57:14 -05002729 }
2730
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002731 ASSERT_TRUE(Connect());
David Benjaminb79cc842016-12-07 15:57:14 -05002732
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002733 EXPECT_FALSE(SSL_session_reused(client_.get()));
2734 EXPECT_FALSE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002735
2736 // Reset everything.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002737 ASSERT_TRUE(SSL_clear(client_.get()));
2738 ASSERT_TRUE(SSL_clear(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002739
2740 // Attempt to connect a second time.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002741 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002742
2743 // |SSL_clear| should implicitly offer the previous session to the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002744 EXPECT_TRUE(SSL_session_reused(client_.get()));
2745 EXPECT_TRUE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002746}
2747
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002748static bool ChainsEqual(STACK_OF(X509) * chain,
2749 const std::vector<X509 *> &expected) {
David Benjamin1444c3a2016-12-20 17:23:11 -05002750 if (sk_X509_num(chain) != expected.size()) {
2751 return false;
2752 }
2753
2754 for (size_t i = 0; i < expected.size(); i++) {
2755 if (X509_cmp(sk_X509_value(chain, i), expected[i]) != 0) {
2756 return false;
2757 }
2758 }
2759
2760 return true;
2761}
2762
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002763TEST_P(SSLVersionTest, AutoChain) {
2764 cert_ = GetChainTestCertificate();
2765 ASSERT_TRUE(cert_);
2766 key_ = GetChainTestKey();
2767 ASSERT_TRUE(key_);
David Benjamin1444c3a2016-12-20 17:23:11 -05002768 bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002769 ASSERT_TRUE(intermediate);
2770
2771 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2772 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin1444c3a2016-12-20 17:23:11 -05002773
2774 // Configure both client and server to accept any certificate. Add
2775 // |intermediate| to the cert store.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002776 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx_.get()),
2777 intermediate.get()));
2778 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(server_ctx_.get()),
2779 intermediate.get()));
2780 SSL_CTX_set_verify(client_ctx_.get(),
2781 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2782 nullptr);
2783 SSL_CTX_set_verify(server_ctx_.get(),
2784 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2785 nullptr);
2786 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
2787 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjamin1444c3a2016-12-20 17:23:11 -05002788
2789 // By default, the client and server should each only send the leaf.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002790 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002791
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002792 EXPECT_TRUE(
2793 ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()), {cert_.get()}));
2794 EXPECT_TRUE(
2795 ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()), {cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002796
2797 // If auto-chaining is enabled, then the intermediate is sent.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002798 SSL_CTX_clear_mode(client_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
2799 SSL_CTX_clear_mode(server_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
2800 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002801
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002802 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
2803 {cert_.get(), intermediate.get()}));
2804 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
2805 {cert_.get(), intermediate.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002806
2807 // Auto-chaining does not override explicitly-configured intermediates.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002808 ASSERT_TRUE(SSL_CTX_add1_chain_cert(client_ctx_.get(), cert_.get()));
2809 ASSERT_TRUE(SSL_CTX_add1_chain_cert(server_ctx_.get(), cert_.get()));
2810 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002811
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002812 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
2813 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002814
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002815 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
2816 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002817}
2818
David Benjamin48063c22017-01-01 23:56:36 -05002819static bool ExpectBadWriteRetry() {
2820 int err = ERR_get_error();
2821 if (ERR_GET_LIB(err) != ERR_LIB_SSL ||
2822 ERR_GET_REASON(err) != SSL_R_BAD_WRITE_RETRY) {
2823 char buf[ERR_ERROR_STRING_BUF_LEN];
2824 ERR_error_string_n(err, buf, sizeof(buf));
2825 fprintf(stderr, "Wanted SSL_R_BAD_WRITE_RETRY, got: %s.\n", buf);
2826 return false;
2827 }
2828
2829 if (ERR_peek_error() != 0) {
2830 fprintf(stderr, "Unexpected error following SSL_R_BAD_WRITE_RETRY.\n");
2831 return false;
2832 }
2833
2834 return true;
2835}
2836
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002837TEST_P(SSLVersionTest, SSLWriteRetry) {
2838 if (is_dtls()) {
2839 return;
David Benjamin48063c22017-01-01 23:56:36 -05002840 }
2841
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002842 for (bool enable_partial_write : {false, true}) {
2843 SCOPED_TRACE(enable_partial_write);
2844
David Benjamin48063c22017-01-01 23:56:36 -05002845 // Connect a client and server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002846 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2847
2848 ASSERT_TRUE(Connect());
David Benjamin48063c22017-01-01 23:56:36 -05002849
2850 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002851 SSL_set_mode(client_.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002852 }
2853
2854 // Write without reading until the buffer is full and we have an unfinished
2855 // write. Keep a count so we may reread it again later. "hello!" will be
2856 // written in two chunks, "hello" and "!".
2857 char data[] = "hello!";
2858 static const int kChunkLen = 5; // The length of "hello".
2859 unsigned count = 0;
2860 for (;;) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002861 int ret = SSL_write(client_.get(), data, kChunkLen);
David Benjamin48063c22017-01-01 23:56:36 -05002862 if (ret <= 0) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002863 ASSERT_EQ(SSL_get_error(client_.get(), ret), SSL_ERROR_WANT_WRITE);
2864 break;
David Benjamin48063c22017-01-01 23:56:36 -05002865 }
2866
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002867 ASSERT_EQ(ret, 5);
David Benjamin48063c22017-01-01 23:56:36 -05002868
2869 count++;
2870 }
2871
2872 // Retrying with the same parameters is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002873 ASSERT_EQ(
2874 SSL_get_error(client_.get(), SSL_write(client_.get(), data, kChunkLen)),
2875 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002876
2877 // Retrying with the same buffer but shorter length is not legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002878 ASSERT_EQ(SSL_get_error(client_.get(),
2879 SSL_write(client_.get(), data, kChunkLen - 1)),
2880 SSL_ERROR_SSL);
2881 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002882
2883 // Retrying with a different buffer pointer is not legal.
2884 char data2[] = "hello";
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002885 ASSERT_EQ(SSL_get_error(client_.get(),
2886 SSL_write(client_.get(), data2, kChunkLen)),
2887 SSL_ERROR_SSL);
2888 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002889
2890 // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002891 SSL_set_mode(client_.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
2892 ASSERT_EQ(SSL_get_error(client_.get(),
2893 SSL_write(client_.get(), data2, kChunkLen)),
2894 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002895
2896 // |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| does not disable length checks.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002897 ASSERT_EQ(SSL_get_error(client_.get(),
2898 SSL_write(client_.get(), data2, kChunkLen - 1)),
2899 SSL_ERROR_SSL);
2900 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002901
2902 // Retrying with a larger buffer is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002903 ASSERT_EQ(SSL_get_error(client_.get(),
2904 SSL_write(client_.get(), data, kChunkLen + 1)),
2905 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002906
2907 // Drain the buffer.
2908 char buf[20];
2909 for (unsigned i = 0; i < count; i++) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002910 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
2911 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
David Benjamin48063c22017-01-01 23:56:36 -05002912 }
2913
2914 // Now that there is space, a retry with a larger buffer should flush the
2915 // pending record, skip over that many bytes of input (on assumption they
2916 // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE
2917 // is set, this will complete in two steps.
2918 char data3[] = "_____!";
2919 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002920 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen);
2921 ASSERT_EQ(SSL_write(client_.get(), data3 + kChunkLen, 1), 1);
2922 } else {
2923 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen + 1);
David Benjamin48063c22017-01-01 23:56:36 -05002924 }
2925
2926 // Check the last write was correct. The data will be spread over two
2927 // records, so SSL_read returns twice.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002928 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
2929 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
2930 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), 1);
2931 ASSERT_EQ(buf[0], '!');
David Benjamin48063c22017-01-01 23:56:36 -05002932 }
David Benjamin48063c22017-01-01 23:56:36 -05002933}
2934
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002935TEST_P(SSLVersionTest, RecordCallback) {
2936 for (bool test_server : {true, false}) {
2937 SCOPED_TRACE(test_server);
2938 ResetContexts();
David Benjamin5df5be12017-06-22 19:43:11 -04002939
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002940 bool read_seen = false;
2941 bool write_seen = false;
2942 auto cb = [&](int is_write, int cb_version, int cb_type, const void *buf,
2943 size_t len, SSL *ssl) {
2944 if (cb_type != SSL3_RT_HEADER) {
2945 return;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002946 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002947
2948 // The callback does not report a version for records.
2949 EXPECT_EQ(0, cb_version);
2950
2951 if (is_write) {
2952 write_seen = true;
2953 } else {
2954 read_seen = true;
2955 }
2956
2957 // Sanity-check that the record header is plausible.
2958 CBS cbs;
2959 CBS_init(&cbs, reinterpret_cast<const uint8_t *>(buf), len);
2960 uint8_t type;
2961 uint16_t record_version, length;
2962 ASSERT_TRUE(CBS_get_u8(&cbs, &type));
2963 ASSERT_TRUE(CBS_get_u16(&cbs, &record_version));
Steven Valdez64cc1212017-12-04 11:15:37 -05002964 EXPECT_EQ(record_version & 0xff00, version() & 0xff00);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002965 if (is_dtls()) {
2966 uint16_t epoch;
2967 ASSERT_TRUE(CBS_get_u16(&cbs, &epoch));
2968 EXPECT_TRUE(epoch == 0 || epoch == 1) << "Invalid epoch: " << epoch;
2969 ASSERT_TRUE(CBS_skip(&cbs, 6));
2970 }
2971 ASSERT_TRUE(CBS_get_u16(&cbs, &length));
2972 EXPECT_EQ(0u, CBS_len(&cbs));
2973 };
2974 using CallbackType = decltype(cb);
2975 SSL_CTX *ctx = test_server ? server_ctx_.get() : client_ctx_.get();
2976 SSL_CTX_set_msg_callback(
2977 ctx, [](int is_write, int cb_version, int cb_type, const void *buf,
2978 size_t len, SSL *ssl, void *arg) {
2979 CallbackType *cb_ptr = reinterpret_cast<CallbackType *>(arg);
2980 (*cb_ptr)(is_write, cb_version, cb_type, buf, len, ssl);
2981 });
2982 SSL_CTX_set_msg_callback_arg(ctx, &cb);
2983
2984 ASSERT_TRUE(Connect());
2985
2986 EXPECT_TRUE(read_seen);
2987 EXPECT_TRUE(write_seen);
David Benjamin0fef3052016-11-18 15:11:10 +09002988 }
David Benjamin9ef31f02016-10-31 18:01:13 -04002989}
2990
David Benjamina8614602017-09-06 15:40:19 -04002991TEST_P(SSLVersionTest, GetServerName) {
2992 // No extensions in SSL 3.0.
2993 if (version() == SSL3_VERSION) {
2994 return;
2995 }
2996
2997 ClientConfig config;
2998 config.servername = "host1";
2999
3000 SSL_CTX_set_tlsext_servername_callback(
3001 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
3002 // During the handshake, |SSL_get_servername| must match |config|.
3003 ClientConfig *config_p = reinterpret_cast<ClientConfig *>(arg);
3004 EXPECT_STREQ(config_p->servername.c_str(),
3005 SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name));
3006 return SSL_TLSEXT_ERR_OK;
3007 });
3008 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), &config);
3009
3010 ASSERT_TRUE(Connect(config));
3011 // After the handshake, it must also be available.
3012 EXPECT_STREQ(config.servername.c_str(),
3013 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3014
3015 // Establish a session under host1.
3016 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3017 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3018 bssl::UniquePtr<SSL_SESSION> session =
3019 CreateClientSession(client_ctx_.get(), server_ctx_.get(), config);
3020
3021 // If the client resumes a session with a different name, |SSL_get_servername|
3022 // must return the new name.
3023 ASSERT_TRUE(session);
3024 config.session = session.get();
3025 config.servername = "host2";
3026 ASSERT_TRUE(Connect(config));
3027 EXPECT_STREQ(config.servername.c_str(),
3028 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3029}
3030
David Benjamin3d8f0802017-09-06 16:12:52 -04003031// Test that session cache mode bits are honored in the client session callback.
3032TEST_P(SSLVersionTest, ClientSessionCacheMode) {
3033 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_OFF);
3034 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3035
3036 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_CLIENT);
3037 EXPECT_TRUE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3038
3039 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_SERVER);
3040 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3041}
3042
Adam Langleye1e78132017-01-31 15:24:31 -08003043TEST(SSLTest, AddChainCertHack) {
3044 // Ensure that we don't accidently break the hack that we have in place to
3045 // keep curl and serf happy when they use an |X509| even after transfering
3046 // ownership.
3047
3048 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3049 ASSERT_TRUE(ctx);
3050 X509 *cert = GetTestCertificate().release();
3051 ASSERT_TRUE(cert);
3052 SSL_CTX_add0_chain_cert(ctx.get(), cert);
3053
3054 // This should not trigger a use-after-free.
3055 X509_cmp(cert, cert);
3056}
3057
David Benjaminb2ff2622017-02-03 17:06:18 -05003058TEST(SSLTest, GetCertificate) {
3059 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3060 ASSERT_TRUE(ctx);
3061 bssl::UniquePtr<X509> cert = GetTestCertificate();
3062 ASSERT_TRUE(cert);
3063 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
3064 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3065 ASSERT_TRUE(ssl);
3066
3067 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
3068 ASSERT_TRUE(cert2);
3069 X509 *cert3 = SSL_get_certificate(ssl.get());
3070 ASSERT_TRUE(cert3);
3071
3072 // The old and new certificates must be identical.
3073 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
3074 EXPECT_EQ(0, X509_cmp(cert.get(), cert3));
3075
3076 uint8_t *der = nullptr;
3077 long der_len = i2d_X509(cert.get(), &der);
3078 ASSERT_LT(0, der_len);
3079 bssl::UniquePtr<uint8_t> free_der(der);
3080
3081 uint8_t *der2 = nullptr;
3082 long der2_len = i2d_X509(cert2, &der2);
3083 ASSERT_LT(0, der2_len);
3084 bssl::UniquePtr<uint8_t> free_der2(der2);
3085
3086 uint8_t *der3 = nullptr;
3087 long der3_len = i2d_X509(cert3, &der3);
3088 ASSERT_LT(0, der3_len);
3089 bssl::UniquePtr<uint8_t> free_der3(der3);
3090
3091 // They must also encode identically.
David Benjamin7d7554b2017-02-04 11:48:59 -05003092 EXPECT_EQ(Bytes(der, der_len), Bytes(der2, der2_len));
3093 EXPECT_EQ(Bytes(der, der_len), Bytes(der3, der3_len));
David Benjaminb2ff2622017-02-03 17:06:18 -05003094}
3095
Adam Langleyd04ca952017-02-28 11:26:51 -08003096TEST(SSLTest, SetChainAndKeyMismatch) {
3097 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_with_buffers_method()));
3098 ASSERT_TRUE(ctx);
3099
3100 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3101 ASSERT_TRUE(key);
3102 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3103 ASSERT_TRUE(leaf);
3104 std::vector<CRYPTO_BUFFER*> chain = {
3105 leaf.get(),
3106 };
3107
3108 // Should fail because |GetTestKey| doesn't match the chain-test certificate.
3109 ASSERT_FALSE(SSL_CTX_set_chain_and_key(ctx.get(), &chain[0], chain.size(),
3110 key.get(), nullptr));
3111 ERR_clear_error();
3112}
3113
3114TEST(SSLTest, SetChainAndKey) {
3115 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3116 ASSERT_TRUE(client_ctx);
3117 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3118 ASSERT_TRUE(server_ctx);
3119
3120 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3121 ASSERT_TRUE(key);
3122 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3123 ASSERT_TRUE(leaf);
3124 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3125 GetChainTestIntermediateBuffer();
3126 ASSERT_TRUE(intermediate);
3127 std::vector<CRYPTO_BUFFER*> chain = {
3128 leaf.get(), intermediate.get(),
3129 };
3130 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3131 chain.size(), key.get(), nullptr));
3132
David Benjamin3a1dd462017-07-11 16:13:10 -04003133 SSL_CTX_set_custom_verify(
3134 client_ctx.get(), SSL_VERIFY_PEER,
3135 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3136 return ssl_verify_ok;
3137 });
Adam Langleyd04ca952017-02-28 11:26:51 -08003138
3139 bssl::UniquePtr<SSL> client, server;
3140 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003141 server_ctx.get()));
Adam Langleyd04ca952017-02-28 11:26:51 -08003142}
3143
David Benjamin71dfad42017-07-16 17:27:39 -04003144TEST(SSLTest, ClientCABuffers) {
3145 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3146 ASSERT_TRUE(client_ctx);
3147 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3148 ASSERT_TRUE(server_ctx);
3149
3150 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3151 ASSERT_TRUE(key);
3152 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3153 ASSERT_TRUE(leaf);
3154 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3155 GetChainTestIntermediateBuffer();
3156 ASSERT_TRUE(intermediate);
3157 std::vector<CRYPTO_BUFFER *> chain = {
3158 leaf.get(),
3159 intermediate.get(),
3160 };
3161 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3162 chain.size(), key.get(), nullptr));
3163
3164 bssl::UniquePtr<CRYPTO_BUFFER> ca_name(
3165 CRYPTO_BUFFER_new(kTestName, sizeof(kTestName), nullptr));
3166 ASSERT_TRUE(ca_name);
3167 bssl::UniquePtr<STACK_OF(CRYPTO_BUFFER)> ca_names(
3168 sk_CRYPTO_BUFFER_new_null());
3169 ASSERT_TRUE(ca_names);
3170 ASSERT_TRUE(sk_CRYPTO_BUFFER_push(ca_names.get(), ca_name.get()));
3171 ca_name.release();
3172 SSL_CTX_set0_client_CAs(server_ctx.get(), ca_names.release());
3173
3174 // Configure client and server to accept all certificates.
3175 SSL_CTX_set_custom_verify(
3176 client_ctx.get(), SSL_VERIFY_PEER,
3177 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3178 return ssl_verify_ok;
3179 });
3180 SSL_CTX_set_custom_verify(
3181 server_ctx.get(), SSL_VERIFY_PEER,
3182 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3183 return ssl_verify_ok;
3184 });
3185
3186 bool cert_cb_called = false;
3187 SSL_CTX_set_cert_cb(
3188 client_ctx.get(),
3189 [](SSL *ssl, void *arg) -> int {
3190 STACK_OF(CRYPTO_BUFFER) *peer_names =
3191 SSL_get0_server_requested_CAs(ssl);
3192 EXPECT_EQ(1u, sk_CRYPTO_BUFFER_num(peer_names));
3193 CRYPTO_BUFFER *peer_name = sk_CRYPTO_BUFFER_value(peer_names, 0);
3194 EXPECT_EQ(Bytes(kTestName), Bytes(CRYPTO_BUFFER_data(peer_name),
3195 CRYPTO_BUFFER_len(peer_name)));
3196 *reinterpret_cast<bool *>(arg) = true;
3197 return 1;
3198 },
3199 &cert_cb_called);
3200
3201 bssl::UniquePtr<SSL> client, server;
3202 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003203 server_ctx.get()));
David Benjamin71dfad42017-07-16 17:27:39 -04003204 EXPECT_TRUE(cert_cb_called);
3205}
3206
David Benjamin91222b82017-03-09 20:10:56 -05003207// Configuring the empty cipher list, though an error, should still modify the
3208// configuration.
3209TEST(SSLTest, EmptyCipherList) {
3210 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3211 ASSERT_TRUE(ctx);
3212
3213 // Initially, the cipher list is not empty.
3214 EXPECT_NE(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3215
3216 // Configuring the empty cipher list fails.
3217 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), ""));
3218 ERR_clear_error();
3219
3220 // But the cipher list is still updated to empty.
3221 EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3222}
3223
Adam Langley4c341d02017-03-08 19:33:21 -08003224// ssl_test_ticket_aead_failure_mode enumerates the possible ways in which the
3225// test |SSL_TICKET_AEAD_METHOD| can fail.
3226enum ssl_test_ticket_aead_failure_mode {
3227 ssl_test_ticket_aead_ok = 0,
3228 ssl_test_ticket_aead_seal_fail,
3229 ssl_test_ticket_aead_open_soft_fail,
3230 ssl_test_ticket_aead_open_hard_fail,
3231};
3232
3233struct ssl_test_ticket_aead_state {
3234 unsigned retry_count;
3235 ssl_test_ticket_aead_failure_mode failure_mode;
3236};
3237
3238static int ssl_test_ticket_aead_ex_index_dup(CRYPTO_EX_DATA *to,
3239 const CRYPTO_EX_DATA *from,
3240 void **from_d, int index,
3241 long argl, void *argp) {
3242 abort();
3243}
3244
3245static void ssl_test_ticket_aead_ex_index_free(void *parent, void *ptr,
3246 CRYPTO_EX_DATA *ad, int index,
3247 long argl, void *argp) {
3248 auto state = reinterpret_cast<ssl_test_ticket_aead_state*>(ptr);
3249 if (state == nullptr) {
3250 return;
3251 }
3252
3253 OPENSSL_free(state);
3254}
3255
3256static CRYPTO_once_t g_ssl_test_ticket_aead_ex_index_once = CRYPTO_ONCE_INIT;
3257static int g_ssl_test_ticket_aead_ex_index;
3258
3259static int ssl_test_ticket_aead_get_ex_index() {
3260 CRYPTO_once(&g_ssl_test_ticket_aead_ex_index_once, [] {
3261 g_ssl_test_ticket_aead_ex_index = SSL_get_ex_new_index(
3262 0, nullptr, nullptr, ssl_test_ticket_aead_ex_index_dup,
3263 ssl_test_ticket_aead_ex_index_free);
3264 });
3265 return g_ssl_test_ticket_aead_ex_index;
3266}
3267
3268static size_t ssl_test_ticket_aead_max_overhead(SSL *ssl) {
3269 return 1;
3270}
3271
3272static int ssl_test_ticket_aead_seal(SSL *ssl, uint8_t *out, size_t *out_len,
3273 size_t max_out_len, const uint8_t *in,
3274 size_t in_len) {
3275 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3276 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3277
3278 if (state->failure_mode == ssl_test_ticket_aead_seal_fail ||
3279 max_out_len < in_len + 1) {
3280 return 0;
3281 }
3282
3283 OPENSSL_memmove(out, in, in_len);
3284 out[in_len] = 0xff;
3285 *out_len = in_len + 1;
3286
3287 return 1;
3288}
3289
3290static ssl_ticket_aead_result_t ssl_test_ticket_aead_open(
3291 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len,
3292 const uint8_t *in, size_t in_len) {
3293 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3294 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3295
3296 if (state->retry_count > 0) {
3297 state->retry_count--;
3298 return ssl_ticket_aead_retry;
3299 }
3300
3301 switch (state->failure_mode) {
3302 case ssl_test_ticket_aead_ok:
3303 break;
3304 case ssl_test_ticket_aead_seal_fail:
3305 // If |seal| failed then there shouldn't be any ticket to try and
3306 // decrypt.
3307 abort();
3308 break;
3309 case ssl_test_ticket_aead_open_soft_fail:
3310 return ssl_ticket_aead_ignore_ticket;
3311 case ssl_test_ticket_aead_open_hard_fail:
3312 return ssl_ticket_aead_error;
3313 }
3314
3315 if (in_len == 0 || in[in_len - 1] != 0xff) {
3316 return ssl_ticket_aead_ignore_ticket;
3317 }
3318
3319 if (max_out_len < in_len - 1) {
3320 return ssl_ticket_aead_error;
3321 }
3322
3323 OPENSSL_memmove(out, in, in_len - 1);
3324 *out_len = in_len - 1;
3325 return ssl_ticket_aead_success;
3326}
3327
3328static const SSL_TICKET_AEAD_METHOD kSSLTestTicketMethod = {
3329 ssl_test_ticket_aead_max_overhead,
3330 ssl_test_ticket_aead_seal,
3331 ssl_test_ticket_aead_open,
3332};
3333
3334static void ConnectClientAndServerWithTicketMethod(
3335 bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
3336 SSL_CTX *client_ctx, SSL_CTX *server_ctx, unsigned retry_count,
3337 ssl_test_ticket_aead_failure_mode failure_mode, SSL_SESSION *session) {
3338 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
3339 ASSERT_TRUE(client);
3340 ASSERT_TRUE(server);
3341 SSL_set_connect_state(client.get());
3342 SSL_set_accept_state(server.get());
3343
3344 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3345 OPENSSL_malloc(sizeof(ssl_test_ticket_aead_state)));
3346 ASSERT_TRUE(state);
3347 OPENSSL_memset(state, 0, sizeof(ssl_test_ticket_aead_state));
3348 state->retry_count = retry_count;
3349 state->failure_mode = failure_mode;
3350
3351 ASSERT_TRUE(SSL_set_ex_data(server.get(), ssl_test_ticket_aead_get_ex_index(),
3352 state));
3353
3354 SSL_set_session(client.get(), session);
3355
3356 BIO *bio1, *bio2;
3357 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
3358
3359 // SSL_set_bio takes ownership.
3360 SSL_set_bio(client.get(), bio1, bio1);
3361 SSL_set_bio(server.get(), bio2, bio2);
3362
3363 if (CompleteHandshakes(client.get(), server.get())) {
3364 *out_client = std::move(client);
3365 *out_server = std::move(server);
3366 } else {
3367 out_client->reset();
3368 out_server->reset();
3369 }
3370}
3371
3372class TicketAEADMethodTest
3373 : public ::testing::TestWithParam<testing::tuple<
3374 uint16_t, unsigned, ssl_test_ticket_aead_failure_mode>> {};
3375
3376TEST_P(TicketAEADMethodTest, Resume) {
3377 bssl::UniquePtr<X509> cert = GetTestCertificate();
3378 ASSERT_TRUE(cert);
3379 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3380 ASSERT_TRUE(key);
3381
3382 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
3383 ASSERT_TRUE(server_ctx);
3384 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
3385 ASSERT_TRUE(client_ctx);
3386
3387 const uint16_t version = testing::get<0>(GetParam());
3388 const unsigned retry_count = testing::get<1>(GetParam());
3389 const ssl_test_ticket_aead_failure_mode failure_mode =
3390 testing::get<2>(GetParam());
3391
3392 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3393 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3394 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), version));
3395 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), version));
3396 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), version));
3397 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), version));
3398
3399 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
3400 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
3401 SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
3402 SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
David Benjamin707af292017-03-10 17:47:18 -05003403 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langley4c341d02017-03-08 19:33:21 -08003404
3405 SSL_CTX_set_ticket_aead_method(server_ctx.get(), &kSSLTestTicketMethod);
3406
3407 bssl::UniquePtr<SSL> client, server;
3408 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3409 server_ctx.get(), retry_count,
3410 failure_mode, nullptr);
3411 switch (failure_mode) {
3412 case ssl_test_ticket_aead_ok:
3413 case ssl_test_ticket_aead_open_hard_fail:
3414 case ssl_test_ticket_aead_open_soft_fail:
3415 ASSERT_TRUE(client);
3416 break;
3417 case ssl_test_ticket_aead_seal_fail:
3418 EXPECT_FALSE(client);
3419 return;
3420 }
3421 EXPECT_FALSE(SSL_session_reused(client.get()));
3422 EXPECT_FALSE(SSL_session_reused(server.get()));
3423
David Benjamin707af292017-03-10 17:47:18 -05003424 // Run the read loop to account for post-handshake tickets in TLS 1.3.
3425 SSL_read(client.get(), nullptr, 0);
3426
3427 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
Adam Langley4c341d02017-03-08 19:33:21 -08003428 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3429 server_ctx.get(), retry_count,
David Benjamin707af292017-03-10 17:47:18 -05003430 failure_mode, session.get());
Adam Langley4c341d02017-03-08 19:33:21 -08003431 switch (failure_mode) {
3432 case ssl_test_ticket_aead_ok:
3433 ASSERT_TRUE(client);
3434 EXPECT_TRUE(SSL_session_reused(client.get()));
3435 EXPECT_TRUE(SSL_session_reused(server.get()));
3436 break;
3437 case ssl_test_ticket_aead_seal_fail:
3438 abort();
3439 break;
3440 case ssl_test_ticket_aead_open_hard_fail:
3441 EXPECT_FALSE(client);
3442 break;
3443 case ssl_test_ticket_aead_open_soft_fail:
3444 ASSERT_TRUE(client);
3445 EXPECT_FALSE(SSL_session_reused(client.get()));
3446 EXPECT_FALSE(SSL_session_reused(server.get()));
3447 }
3448}
3449
3450INSTANTIATE_TEST_CASE_P(
3451 TicketAEADMethodTests, TicketAEADMethodTest,
3452 testing::Combine(
David Benjamin707af292017-03-10 17:47:18 -05003453 testing::Values(TLS1_2_VERSION, TLS1_3_VERSION),
Adam Langley4c341d02017-03-08 19:33:21 -08003454 testing::Values(0, 1, 2),
3455 testing::Values(ssl_test_ticket_aead_ok,
3456 ssl_test_ticket_aead_seal_fail,
3457 ssl_test_ticket_aead_open_soft_fail,
3458 ssl_test_ticket_aead_open_hard_fail)));
3459
David Benjamin3cfeb952017-03-01 16:48:38 -05003460TEST(SSLTest, SSL3Method) {
3461 bssl::UniquePtr<X509> cert = GetTestCertificate();
3462 ASSERT_TRUE(cert);
3463
3464 // For compatibility, SSLv3_method should work up to SSL_CTX_new and SSL_new.
3465 bssl::UniquePtr<SSL_CTX> ssl3_ctx(SSL_CTX_new(SSLv3_method()));
3466 ASSERT_TRUE(ssl3_ctx);
3467 ASSERT_TRUE(SSL_CTX_use_certificate(ssl3_ctx.get(), cert.get()));
3468 bssl::UniquePtr<SSL> ssl(SSL_new(ssl3_ctx.get()));
3469 EXPECT_TRUE(ssl);
3470
3471 // Create a normal TLS context to test against.
3472 bssl::UniquePtr<SSL_CTX> tls_ctx(SSL_CTX_new(TLS_method()));
3473 ASSERT_TRUE(tls_ctx);
3474 ASSERT_TRUE(SSL_CTX_use_certificate(tls_ctx.get(), cert.get()));
3475
3476 // However, handshaking an SSLv3_method server should fail to resolve the
3477 // version range. Explicit calls to SSL_CTX_set_min_proto_version are the only
3478 // way to enable SSL 3.0.
3479 bssl::UniquePtr<SSL> client, server;
3480 EXPECT_FALSE(ConnectClientAndServer(&client, &server, tls_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003481 ssl3_ctx.get()));
David Benjamin3cfeb952017-03-01 16:48:38 -05003482 uint32_t err = ERR_get_error();
3483 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
3484 EXPECT_EQ(SSL_R_NO_SUPPORTED_VERSIONS_ENABLED, ERR_GET_REASON(err));
3485
3486 // Likewise for SSLv3_method clients.
3487 EXPECT_FALSE(ConnectClientAndServer(&client, &server, ssl3_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003488 tls_ctx.get()));
David Benjamin3cfeb952017-03-01 16:48:38 -05003489 err = ERR_get_error();
3490 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
3491 EXPECT_EQ(SSL_R_NO_SUPPORTED_VERSIONS_ENABLED, ERR_GET_REASON(err));
3492}
3493
David Benjaminca743582017-06-15 17:51:35 -04003494TEST(SSLTest, SelectNextProto) {
3495 uint8_t *result;
3496 uint8_t result_len;
3497
3498 // If there is an overlap, it should be returned.
3499 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3500 SSL_select_next_proto(&result, &result_len,
3501 (const uint8_t *)"\1a\2bb\3ccc", 9,
3502 (const uint8_t *)"\1x\1y\1a\1z", 8));
3503 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
3504
3505 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3506 SSL_select_next_proto(&result, &result_len,
3507 (const uint8_t *)"\1a\2bb\3ccc", 9,
3508 (const uint8_t *)"\1x\1y\2bb\1z", 9));
3509 EXPECT_EQ(Bytes("bb"), Bytes(result, result_len));
3510
3511 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3512 SSL_select_next_proto(&result, &result_len,
3513 (const uint8_t *)"\1a\2bb\3ccc", 9,
3514 (const uint8_t *)"\1x\1y\3ccc\1z", 10));
3515 EXPECT_EQ(Bytes("ccc"), Bytes(result, result_len));
3516
3517 // Peer preference order takes precedence over local.
3518 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3519 SSL_select_next_proto(&result, &result_len,
3520 (const uint8_t *)"\1a\2bb\3ccc", 9,
3521 (const uint8_t *)"\3ccc\2bb\1a", 9));
3522 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
3523
3524 // If there is no overlap, return the first local protocol.
3525 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
3526 SSL_select_next_proto(&result, &result_len,
3527 (const uint8_t *)"\1a\2bb\3ccc", 9,
3528 (const uint8_t *)"\1x\2yy\3zzz", 9));
3529 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
3530
3531 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
3532 SSL_select_next_proto(&result, &result_len, nullptr, 0,
3533 (const uint8_t *)"\1x\2yy\3zzz", 9));
3534 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
3535}
3536
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003537TEST(SSLTest, SealRecord) {
3538 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3539 server_ctx(SSL_CTX_new(TLS_method()));
3540 ASSERT_TRUE(client_ctx);
3541 ASSERT_TRUE(server_ctx);
3542
3543 bssl::UniquePtr<X509> cert = GetTestCertificate();
3544 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3545 ASSERT_TRUE(cert);
3546 ASSERT_TRUE(key);
3547 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3548 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3549
3550 bssl::UniquePtr<SSL> client, server;
3551 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003552 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003553
3554 const std::vector<uint8_t> record = {1, 2, 3, 4, 5};
3555 std::vector<uint8_t> prefix(
3556 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003557 body(record.size()),
3558 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003559 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3560 bssl::MakeSpan(body), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003561 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003562
3563 std::vector<uint8_t> sealed;
3564 sealed.insert(sealed.end(), prefix.begin(), prefix.end());
3565 sealed.insert(sealed.end(), body.begin(), body.end());
3566 sealed.insert(sealed.end(), suffix.begin(), suffix.end());
3567 std::vector<uint8_t> sealed_copy = sealed;
3568
3569 bssl::Span<uint8_t> plaintext;
3570 size_t record_len;
3571 uint8_t alert = 255;
3572 EXPECT_EQ(bssl::OpenRecord(server.get(), &plaintext, &record_len, &alert,
3573 bssl::MakeSpan(sealed)),
3574 bssl::OpenRecordResult::kOK);
3575 EXPECT_EQ(record_len, sealed.size());
3576 EXPECT_EQ(plaintext, record);
3577 EXPECT_EQ(255, alert);
3578}
3579
3580TEST(SSLTest, SealRecordInPlace) {
3581 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3582 server_ctx(SSL_CTX_new(TLS_method()));
3583 ASSERT_TRUE(client_ctx);
3584 ASSERT_TRUE(server_ctx);
3585
3586 bssl::UniquePtr<X509> cert = GetTestCertificate();
3587 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3588 ASSERT_TRUE(cert);
3589 ASSERT_TRUE(key);
3590 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3591 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3592
3593 bssl::UniquePtr<SSL> client, server;
3594 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003595 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003596
3597 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
3598 std::vector<uint8_t> record = plaintext;
3599 std::vector<uint8_t> prefix(
3600 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003601 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003602 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3603 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003604 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003605 record.insert(record.begin(), prefix.begin(), prefix.end());
3606 record.insert(record.end(), suffix.begin(), suffix.end());
3607
3608 bssl::Span<uint8_t> result;
3609 size_t record_len;
3610 uint8_t alert;
3611 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
3612 bssl::MakeSpan(record)),
3613 bssl::OpenRecordResult::kOK);
3614 EXPECT_EQ(record_len, record.size());
3615 EXPECT_EQ(plaintext, result);
3616}
3617
3618TEST(SSLTest, SealRecordTrailingData) {
3619 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3620 server_ctx(SSL_CTX_new(TLS_method()));
3621 ASSERT_TRUE(client_ctx);
3622 ASSERT_TRUE(server_ctx);
3623
3624 bssl::UniquePtr<X509> cert = GetTestCertificate();
3625 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3626 ASSERT_TRUE(cert);
3627 ASSERT_TRUE(key);
3628 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3629 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3630
3631 bssl::UniquePtr<SSL> client, server;
3632 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003633 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003634
3635 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
3636 std::vector<uint8_t> record = plaintext;
3637 std::vector<uint8_t> prefix(
3638 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003639 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003640 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3641 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003642 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003643 record.insert(record.begin(), prefix.begin(), prefix.end());
3644 record.insert(record.end(), suffix.begin(), suffix.end());
3645 record.insert(record.end(), {5, 4, 3, 2, 1});
3646
3647 bssl::Span<uint8_t> result;
3648 size_t record_len;
3649 uint8_t alert;
3650 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
3651 bssl::MakeSpan(record)),
3652 bssl::OpenRecordResult::kOK);
3653 EXPECT_EQ(record_len, record.size() - 5);
3654 EXPECT_EQ(plaintext, result);
3655}
3656
3657TEST(SSLTest, SealRecordInvalidSpanSize) {
3658 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3659 server_ctx(SSL_CTX_new(TLS_method()));
3660 ASSERT_TRUE(client_ctx);
3661 ASSERT_TRUE(server_ctx);
3662
3663 bssl::UniquePtr<X509> cert = GetTestCertificate();
3664 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3665 ASSERT_TRUE(cert);
3666 ASSERT_TRUE(key);
3667 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3668 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3669
3670 bssl::UniquePtr<SSL> client, server;
3671 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003672 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003673
3674 std::vector<uint8_t> record = {1, 2, 3, 4, 5};
3675 std::vector<uint8_t> prefix(
3676 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003677 body(record.size()),
3678 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003679
3680 auto expect_err = []() {
3681 int err = ERR_get_error();
3682 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
3683 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_BUFFER_TOO_SMALL);
3684 ERR_clear_error();
3685 };
3686 EXPECT_FALSE(bssl::SealRecord(
3687 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003688 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003689 expect_err();
3690 EXPECT_FALSE(bssl::SealRecord(
3691 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003692 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003693 expect_err();
3694
3695 EXPECT_FALSE(
3696 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3697 bssl::MakeSpan(record.data(), record.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003698 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003699 expect_err();
3700 EXPECT_FALSE(
3701 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3702 bssl::MakeSpan(record.data(), record.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003703 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003704 expect_err();
3705
3706 EXPECT_FALSE(bssl::SealRecord(
3707 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003708 bssl::MakeSpan(suffix.data(), suffix.size() - 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003709 expect_err();
3710 EXPECT_FALSE(bssl::SealRecord(
3711 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003712 bssl::MakeSpan(suffix.data(), suffix.size() + 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003713 expect_err();
3714}
3715
David Benjamin617b8182017-08-29 15:33:10 -04003716// The client should gracefully handle no suitable ciphers being enabled.
3717TEST(SSLTest, NoCiphersAvailable) {
3718 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3719 ASSERT_TRUE(ctx);
3720
3721 // Configure |client_ctx| with a cipher list that does not intersect with its
3722 // version configuration.
3723 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
3724 ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
3725 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
3726
3727 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3728 ASSERT_TRUE(ssl);
3729 SSL_set_connect_state(ssl.get());
3730
3731 UniquePtr<BIO> rbio(BIO_new(BIO_s_mem())), wbio(BIO_new(BIO_s_mem()));
3732 ASSERT_TRUE(rbio);
3733 ASSERT_TRUE(wbio);
3734 SSL_set0_rbio(ssl.get(), rbio.release());
3735 SSL_set0_wbio(ssl.get(), wbio.release());
3736
3737 int ret = SSL_do_handshake(ssl.get());
3738 EXPECT_EQ(-1, ret);
3739 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), ret));
3740 uint32_t err = ERR_get_error();
3741 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
3742 EXPECT_EQ(SSL_R_NO_CIPHERS_AVAILABLE, ERR_GET_REASON(err));
3743}
3744
David Benjamina4bafd32017-10-03 15:06:29 -04003745TEST_P(SSLVersionTest, SessionVersion) {
3746 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3747 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3748
3749 bssl::UniquePtr<SSL_SESSION> session =
3750 CreateClientSession(client_ctx_.get(), server_ctx_.get());
3751 ASSERT_TRUE(session);
3752 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
3753
3754 // Sessions in TLS 1.3 and later should be single-use.
3755 EXPECT_EQ(version() == TLS1_3_VERSION,
3756 !!SSL_SESSION_should_be_single_use(session.get()));
3757
3758 // Making fake sessions for testing works.
3759 session.reset(SSL_SESSION_new(client_ctx_.get()));
3760 ASSERT_TRUE(session);
3761 ASSERT_TRUE(SSL_SESSION_set_protocol_version(session.get(), version()));
3762 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
3763}
3764
David Benjaminfdb7a352017-10-12 17:34:18 -04003765TEST_P(SSLVersionTest, SSLPending) {
3766 UniquePtr<SSL> ssl(SSL_new(client_ctx_.get()));
3767 ASSERT_TRUE(ssl);
3768 EXPECT_EQ(0, SSL_pending(ssl.get()));
3769
3770 ASSERT_TRUE(Connect());
3771 EXPECT_EQ(0, SSL_pending(client_.get()));
3772
3773 ASSERT_EQ(5, SSL_write(server_.get(), "hello", 5));
3774 ASSERT_EQ(5, SSL_write(server_.get(), "world", 5));
3775 EXPECT_EQ(0, SSL_pending(client_.get()));
3776
3777 char buf[10];
3778 ASSERT_EQ(1, SSL_peek(client_.get(), buf, 1));
3779 EXPECT_EQ(5, SSL_pending(client_.get()));
3780
3781 ASSERT_EQ(1, SSL_read(client_.get(), buf, 1));
3782 EXPECT_EQ(4, SSL_pending(client_.get()));
3783
3784 ASSERT_EQ(4, SSL_read(client_.get(), buf, 10));
3785 EXPECT_EQ(0, SSL_pending(client_.get()));
3786
3787 ASSERT_EQ(2, SSL_read(client_.get(), buf, 2));
3788 EXPECT_EQ(3, SSL_pending(client_.get()));
3789}
3790
David Benjamina031b612017-10-11 20:48:25 -04003791// Test that post-handshake tickets consumed by |SSL_shutdown| are ignored.
3792TEST(SSLTest, ShutdownIgnoresTickets) {
3793 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3794 ASSERT_TRUE(ctx);
3795 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_3_VERSION));
3796 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
3797
3798 bssl::UniquePtr<X509> cert = GetTestCertificate();
3799 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3800 ASSERT_TRUE(cert);
3801 ASSERT_TRUE(key);
3802 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
3803 ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
3804
3805 SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_BOTH);
3806
3807 bssl::UniquePtr<SSL> client, server;
3808 ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
3809
3810 SSL_CTX_sess_set_new_cb(ctx.get(), [](SSL *ssl, SSL_SESSION *session) -> int {
3811 ADD_FAILURE() << "New session callback called during SSL_shutdown";
3812 return 0;
3813 });
3814
3815 // Send close_notify.
3816 EXPECT_EQ(0, SSL_shutdown(server.get()));
3817 EXPECT_EQ(0, SSL_shutdown(client.get()));
3818
3819 // Receive close_notify.
3820 EXPECT_EQ(1, SSL_shutdown(server.get()));
3821 EXPECT_EQ(1, SSL_shutdown(client.get()));
3822}
3823
David Benjamin6cc352e2017-11-02 17:21:39 -04003824TEST(SSLTest, SignatureAlgorithmProperties) {
3825 EXPECT_EQ(EVP_PKEY_NONE, SSL_get_signature_algorithm_key_type(0x1234));
3826 EXPECT_EQ(nullptr, SSL_get_signature_algorithm_digest(0x1234));
3827 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(0x1234));
3828
3829 EXPECT_EQ(EVP_PKEY_RSA,
3830 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
3831 EXPECT_EQ(EVP_md5_sha1(),
3832 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
3833 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
3834
3835 EXPECT_EQ(EVP_PKEY_EC, SSL_get_signature_algorithm_key_type(
3836 SSL_SIGN_ECDSA_SECP256R1_SHA256));
3837 EXPECT_EQ(EVP_sha256(), SSL_get_signature_algorithm_digest(
3838 SSL_SIGN_ECDSA_SECP256R1_SHA256));
3839 EXPECT_FALSE(
3840 SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_ECDSA_SECP256R1_SHA256));
3841
3842 EXPECT_EQ(EVP_PKEY_RSA,
3843 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PSS_SHA384));
3844 EXPECT_EQ(EVP_sha384(),
3845 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PSS_SHA384));
3846 EXPECT_TRUE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PSS_SHA384));
3847}
3848
David Benjamin96628432017-01-19 19:05:47 -05003849// TODO(davidben): Convert this file to GTest properly.
3850TEST(SSLTest, AllTests) {
David Benjamine11726a2017-04-23 12:14:28 -04003851 if (!TestSSL_SESSIONEncoding(kOpenSSLSession) ||
Adam Langley10f97f32016-07-12 08:09:33 -07003852 !TestSSL_SESSIONEncoding(kCustomSession) ||
3853 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
3854 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
3855 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
3856 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
Steven Valdeza833c352016-11-01 13:39:36 -04003857 // Test the padding extension at TLS 1.2.
3858 !TestPaddingExtension(TLS1_2_VERSION, TLS1_2_VERSION) ||
3859 // Test the padding extension at TLS 1.3 with a TLS 1.2 session, so there
3860 // will be no PSK binder after the padding extension.
3861 !TestPaddingExtension(TLS1_3_VERSION, TLS1_2_VERSION) ||
3862 // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
3863 // will be a PSK binder after the padding extension.
Steven Valdez74666da2018-01-09 06:18:36 -05003864 !TestPaddingExtension(TLS1_3_VERSION, TLS1_3_DRAFT23_VERSION)) {
David Benjamin96628432017-01-19 19:05:47 -05003865 ADD_FAILURE() << "Tests failed";
David Benjaminbb0a17c2014-09-20 15:35:39 -04003866 }
David Benjamin2e521212014-07-16 14:37:51 -04003867}
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003868
3869} // namespace
3870} // namespace bssl