blob: 66f03047132fe20a94b4beb133288aaac4b6f6a8 [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"},
78// TLS 1.3 requires RSA-PSS, which is disabled for Android system builds.
79#if !defined(BORINGSSL_ANDROID_SYSTEM)
80 {TLS1_3_VERSION, VersionParam::is_tls, "TLS1_3"},
81#endif
82 {DTLS1_VERSION, VersionParam::is_dtls, "DTLS1"},
83 {DTLS1_2_VERSION, VersionParam::is_dtls, "DTLS1_2"},
84};
85
David Benjamin1d77e562015-03-22 17:22:08 -040086struct ExpectedCipher {
87 unsigned long id;
David Benjaminbb0a17c2014-09-20 15:35:39 -040088 int in_group_flag;
David Benjamin1d77e562015-03-22 17:22:08 -040089};
David Benjaminbb0a17c2014-09-20 15:35:39 -040090
David Benjamin1d77e562015-03-22 17:22:08 -040091struct CipherTest {
92 // The rule string to apply.
David Benjaminbb0a17c2014-09-20 15:35:39 -040093 const char *rule;
David Benjaminfb974e62015-12-16 19:34:22 -050094 // The list of expected ciphers, in order.
95 std::vector<ExpectedCipher> expected;
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -080096 // True if this cipher list should fail in strict mode.
97 bool strict_fail;
David Benjamin1d77e562015-03-22 17:22:08 -040098};
David Benjaminbb0a17c2014-09-20 15:35:39 -040099
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100100struct CurveTest {
101 // The rule string to apply.
102 const char *rule;
103 // The list of expected curves, in order.
104 std::vector<uint16_t> expected;
105};
106
David Benjaminfb974e62015-12-16 19:34:22 -0500107static const CipherTest kCipherTests[] = {
108 // Selecting individual ciphers should work.
109 {
110 "ECDHE-ECDSA-CHACHA20-POLY1305:"
111 "ECDHE-RSA-CHACHA20-POLY1305:"
112 "ECDHE-ECDSA-AES128-GCM-SHA256:"
113 "ECDHE-RSA-AES128-GCM-SHA256",
114 {
115 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500116 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500117 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
118 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
119 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800120 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500121 },
122 // + reorders selected ciphers to the end, keeping their relative order.
123 {
124 "ECDHE-ECDSA-CHACHA20-POLY1305:"
125 "ECDHE-RSA-CHACHA20-POLY1305:"
126 "ECDHE-ECDSA-AES128-GCM-SHA256:"
127 "ECDHE-RSA-AES128-GCM-SHA256:"
128 "+aRSA",
129 {
130 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500131 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
132 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500133 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
134 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800135 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500136 },
137 // ! banishes ciphers from future selections.
138 {
139 "!aRSA:"
140 "ECDHE-ECDSA-CHACHA20-POLY1305:"
141 "ECDHE-RSA-CHACHA20-POLY1305:"
142 "ECDHE-ECDSA-AES128-GCM-SHA256:"
143 "ECDHE-RSA-AES128-GCM-SHA256",
144 {
145 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500146 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
147 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800148 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500149 },
150 // Multiple masks can be ANDed in a single rule.
151 {
152 "kRSA+AESGCM+AES128",
153 {
154 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
155 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800156 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500157 },
158 // - removes selected ciphers, but preserves their order for future
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700159 // selections. Select AES_128_GCM, but order the key exchanges RSA,
David Benjaminfb974e62015-12-16 19:34:22 -0500160 // ECDHE_RSA.
161 {
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700162 "ALL:-kECDHE:"
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700163 "-kRSA:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500164 "AESGCM+AES128+aRSA",
165 {
166 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500167 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
168 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800169 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500170 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800171 // Unknown selectors are no-ops, except in strict mode.
David Benjaminfb974e62015-12-16 19:34:22 -0500172 {
173 "ECDHE-ECDSA-CHACHA20-POLY1305:"
174 "ECDHE-RSA-CHACHA20-POLY1305:"
175 "ECDHE-ECDSA-AES128-GCM-SHA256:"
176 "ECDHE-RSA-AES128-GCM-SHA256:"
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800177 "BOGUS1",
David Benjaminfb974e62015-12-16 19:34:22 -0500178 {
179 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500180 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500181 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
182 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
183 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800184 true,
185 },
186 // Unknown selectors are no-ops, except in strict mode.
187 {
188 "ECDHE-ECDSA-CHACHA20-POLY1305:"
189 "ECDHE-RSA-CHACHA20-POLY1305:"
190 "ECDHE-ECDSA-AES128-GCM-SHA256:"
191 "ECDHE-RSA-AES128-GCM-SHA256:"
192 "-BOGUS2:+BOGUS3:!BOGUS4",
193 {
194 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
195 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
196 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
197 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
198 },
199 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500200 },
201 // Square brackets specify equi-preference groups.
202 {
203 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
204 "[ECDHE-RSA-CHACHA20-POLY1305]:"
205 "ECDHE-RSA-AES128-GCM-SHA256",
206 {
207 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
David Benjaminfb974e62015-12-16 19:34:22 -0500208 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley2e839242017-01-19 15:12:44 -0800209 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500210 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
211 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800212 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500213 },
David Benjamin6fff3862017-06-21 21:07:04 -0400214 // Standard names may be used instead of OpenSSL names.
215 {
216 "[TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256|"
David Benjaminbf5f1922017-07-01 11:13:53 -0400217 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256]:"
David Benjamin6fff3862017-06-21 21:07:04 -0400218 "[TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256]:"
219 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
220 {
221 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
222 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
223 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
224 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
225 },
226 false,
227 },
David Benjaminfb974e62015-12-16 19:34:22 -0500228 // @STRENGTH performs a stable strength-sort of the selected ciphers and
229 // only the selected ciphers.
230 {
231 // To simplify things, banish all but {ECDHE_RSA,RSA} x
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700232 // {CHACHA20,AES_256_CBC,AES_128_CBC} x SHA1.
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700233 "!AESGCM:!3DES:!SHA256:!SHA384:"
David Benjaminfb974e62015-12-16 19:34:22 -0500234 // Order some ciphers backwards by strength.
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700235 "ALL:-CHACHA20:-AES256:-AES128:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500236 // Select ECDHE ones and sort them by strength. Ties should resolve
237 // based on the order above.
238 "kECDHE:@STRENGTH:-ALL:"
239 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
240 // by strength. Then RSA, backwards by strength.
241 "aRSA",
242 {
243 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
244 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500245 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500246 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
247 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
248 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800249 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500250 },
David Benjaminbf5f1922017-07-01 11:13:53 -0400251 // Additional masks after @STRENGTH get silently discarded.
252 //
253 // TODO(davidben): Make this an error. If not silently discarded, they get
254 // interpreted as + opcodes which are very different.
255 {
256 "ECDHE-RSA-AES128-GCM-SHA256:"
257 "ECDHE-RSA-AES256-GCM-SHA384:"
258 "@STRENGTH+AES256",
259 {
260 {TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
261 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
262 },
263 false,
264 },
265 {
266 "ECDHE-RSA-AES128-GCM-SHA256:"
267 "ECDHE-RSA-AES256-GCM-SHA384:"
268 "@STRENGTH+AES256:"
269 "ECDHE-RSA-CHACHA20-POLY1305",
270 {
271 {TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
272 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
273 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
274 },
275 false,
276 },
David Benjaminfb974e62015-12-16 19:34:22 -0500277 // Exact ciphers may not be used in multi-part rules; they are treated
278 // as unknown aliases.
279 {
280 "ECDHE-ECDSA-AES128-GCM-SHA256:"
281 "ECDHE-RSA-AES128-GCM-SHA256:"
282 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
283 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
284 {
285 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
286 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
287 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800288 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500289 },
290 // SSLv3 matches everything that existed before TLS 1.2.
291 {
292 "AES128-SHA:AES128-SHA256:!SSLv3",
293 {
294 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
295 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800296 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500297 },
298 // TLSv1.2 matches everything added in TLS 1.2.
299 {
300 "AES128-SHA:AES128-SHA256:!TLSv1.2",
301 {
302 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
303 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800304 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500305 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800306 // The two directives have no intersection. But each component is valid, so
307 // even in strict mode it is accepted.
David Benjaminfb974e62015-12-16 19:34:22 -0500308 {
309 "AES128-SHA:AES128-SHA256:!TLSv1.2+SSLv3",
310 {
311 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
312 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
313 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800314 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500315 },
Adam Langley22df6912017-07-25 12:27:37 -0700316 // Spaces, semi-colons and commas are separators.
317 {
318 "AES128-SHA: AES128-SHA256 AES256-SHA ,AES256-SHA256 ; AES128-GCM-SHA256",
319 {
320 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
321 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
322 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
323 {TLS1_CK_RSA_WITH_AES_256_SHA256, 0},
324 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
325 },
326 // …but not in strict mode.
327 true,
328 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400329};
330
331static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400332 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400333 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
334 "RSA]",
335 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400336 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400337 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400338 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400339 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400340 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400341 "",
342 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400343 // COMPLEMENTOFDEFAULT is empty.
344 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400345 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400346 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400347 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400348 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
349 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
350 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
351 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
Adam Langleyf99f2442016-10-02 09:53:38 -0700352 // Opcode supplied, but missing selector.
353 "+",
Adam Langley22df6912017-07-25 12:27:37 -0700354 // Spaces are forbidden in equal-preference groups.
355 "[AES128-SHA | AES128-SHA256]",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400356};
357
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700358static const char *kMustNotIncludeNull[] = {
359 "ALL",
360 "DEFAULT",
David Benjamind6e9eec2015-11-18 09:48:55 -0500361 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700362 "FIPS",
363 "SHA",
364 "SHA1",
365 "RSA",
366 "SSLv3",
367 "TLSv1",
368 "TLSv1.2",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700369};
370
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100371static const CurveTest kCurveTests[] = {
372 {
373 "P-256",
374 { SSL_CURVE_SECP256R1 },
375 },
376 {
377 "P-256:P-384:P-521:X25519",
378 {
379 SSL_CURVE_SECP256R1,
380 SSL_CURVE_SECP384R1,
381 SSL_CURVE_SECP521R1,
382 SSL_CURVE_X25519,
383 },
384 },
385};
386
387static const char *kBadCurvesLists[] = {
388 "",
389 ":",
390 "::",
391 "P-256::X25519",
392 "RSA:P-256",
393 "P-256:RSA",
394 "X25519:P-256:",
395 ":X25519:P-256",
396};
397
David Benjamin70dbf042017-08-08 18:51:37 -0400398static std::string CipherListToString(SSL_CTX *ctx) {
David Benjamin1d77e562015-03-22 17:22:08 -0400399 bool in_group = false;
David Benjamine11726a2017-04-23 12:14:28 -0400400 std::string ret;
David Benjamin70dbf042017-08-08 18:51:37 -0400401 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
402 for (size_t i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
403 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
404 if (!in_group && SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400405 ret += "\t[\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400406 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400407 }
David Benjamine11726a2017-04-23 12:14:28 -0400408 ret += "\t";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400409 if (in_group) {
David Benjamine11726a2017-04-23 12:14:28 -0400410 ret += " ";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400411 }
David Benjamine11726a2017-04-23 12:14:28 -0400412 ret += SSL_CIPHER_get_name(cipher);
413 ret += "\n";
David Benjamin70dbf042017-08-08 18:51:37 -0400414 if (in_group && !SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400415 ret += "\t]\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400416 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400417 }
418 }
David Benjamine11726a2017-04-23 12:14:28 -0400419 return ret;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400420}
421
David Benjamin70dbf042017-08-08 18:51:37 -0400422static bool CipherListsEqual(SSL_CTX *ctx,
David Benjamine11726a2017-04-23 12:14:28 -0400423 const std::vector<ExpectedCipher> &expected) {
David Benjamin70dbf042017-08-08 18:51:37 -0400424 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
425 if (sk_SSL_CIPHER_num(ciphers) != expected.size()) {
David Benjamin1d77e562015-03-22 17:22:08 -0400426 return false;
David Benjamin65226252015-02-05 16:49:47 -0500427 }
428
David Benjamine11726a2017-04-23 12:14:28 -0400429 for (size_t i = 0; i < expected.size(); i++) {
David Benjamin70dbf042017-08-08 18:51:37 -0400430 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
David Benjamine11726a2017-04-23 12:14:28 -0400431 if (expected[i].id != SSL_CIPHER_get_id(cipher) ||
David Benjamin70dbf042017-08-08 18:51:37 -0400432 expected[i].in_group_flag != !!SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400433 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400434 }
435 }
436
David Benjamin1d77e562015-03-22 17:22:08 -0400437 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400438}
439
David Benjamine11726a2017-04-23 12:14:28 -0400440TEST(SSLTest, CipherRules) {
441 for (const CipherTest &t : kCipherTests) {
442 SCOPED_TRACE(t.rule);
443 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
444 ASSERT_TRUE(ctx);
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700445
David Benjamine11726a2017-04-23 12:14:28 -0400446 // Test lax mode.
447 ASSERT_TRUE(SSL_CTX_set_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400448 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400449 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400450 << CipherListToString(ctx.get());
David Benjamine11726a2017-04-23 12:14:28 -0400451
452 // Test strict mode.
453 if (t.strict_fail) {
454 EXPECT_FALSE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
455 } else {
456 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400457 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400458 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400459 << CipherListToString(ctx.get());
David Benjaminbb0a17c2014-09-20 15:35:39 -0400460 }
461 }
462
David Benjaminfb974e62015-12-16 19:34:22 -0500463 for (const char *rule : kBadRules) {
David Benjamine11726a2017-04-23 12:14:28 -0400464 SCOPED_TRACE(rule);
465 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
466 ASSERT_TRUE(ctx);
467
468 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), rule));
David Benjaminbb0a17c2014-09-20 15:35:39 -0400469 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400470 }
471
David Benjaminfb974e62015-12-16 19:34:22 -0500472 for (const char *rule : kMustNotIncludeNull) {
David Benjamine11726a2017-04-23 12:14:28 -0400473 SCOPED_TRACE(rule);
474 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
475 ASSERT_TRUE(ctx);
476
477 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400478 for (const SSL_CIPHER *cipher : SSL_CTX_get_ciphers(ctx.get())) {
David Benjamine3bb51c2017-08-22 23:16:02 -0700479 EXPECT_NE(NID_undef, SSL_CIPHER_get_cipher_nid(cipher));
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700480 }
481 }
David Benjaminbb0a17c2014-09-20 15:35:39 -0400482}
David Benjamin2e521212014-07-16 14:37:51 -0400483
David Benjamine11726a2017-04-23 12:14:28 -0400484TEST(SSLTest, CurveRules) {
485 for (const CurveTest &t : kCurveTests) {
486 SCOPED_TRACE(t.rule);
487 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
488 ASSERT_TRUE(ctx);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100489
David Benjamine11726a2017-04-23 12:14:28 -0400490 ASSERT_TRUE(SSL_CTX_set1_curves_list(ctx.get(), t.rule));
491 ASSERT_EQ(t.expected.size(), ctx->supported_group_list_len);
492 for (size_t i = 0; i < t.expected.size(); i++) {
493 EXPECT_EQ(t.expected[i], ctx->supported_group_list[i]);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100494 }
495 }
496
497 for (const char *rule : kBadCurvesLists) {
David Benjamine11726a2017-04-23 12:14:28 -0400498 SCOPED_TRACE(rule);
499 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
500 ASSERT_TRUE(ctx);
501
502 EXPECT_FALSE(SSL_CTX_set1_curves_list(ctx.get(), rule));
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100503 ERR_clear_error();
504 }
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100505}
506
Adam Langley364f7a62016-12-12 10:51:00 -0800507// kOpenSSLSession is a serialized SSL_SESSION.
Adam Langley10f97f32016-07-12 08:09:33 -0700508static const char kOpenSSLSession[] =
Adam Langley364f7a62016-12-12 10:51:00 -0800509 "MIIFqgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700510 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
511 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
512 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
513 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
514 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
515 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
516 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
517 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
518 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
519 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
520 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
521 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
522 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
523 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
524 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
525 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
526 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
527 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
528 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
529 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
530 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
531 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
532 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
533 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
534 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
535 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
536 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
537 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
538 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
Adam Langley364f7a62016-12-12 10:51:00 -0800539 "i4gv7Y5oliyntgMBAQA=";
Adam Langley10f97f32016-07-12 08:09:33 -0700540
541// kCustomSession is a custom serialized SSL_SESSION generated by
542// filling in missing fields from |kOpenSSLSession|. This includes
543// providing |peer_sha256|, so |peer| is not serialized.
544static const char kCustomSession[] =
David Benjamina8614602017-09-06 15:40:19 -0400545 "MIIBZAIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700546 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
David Benjamina8614602017-09-06 15:40:19 -0400547 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUqAcEBXdvcmxkqQUCAwGJwKqBpwSB"
548 "pBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38"
549 "VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd"
550 "3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hg"
551 "b+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYGBgYGBgYGBgYGBgYGBgYGBgYG"
552 "BgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
Adam Langley10f97f32016-07-12 08:09:33 -0700553
554// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
555static const char kBoringSSLSession[] =
556 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
557 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
558 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
559 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
560 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
561 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
562 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
563 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
564 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
565 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
566 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
567 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
568 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
569 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
570 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
571 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
572 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
573 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
574 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
575 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
576 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
577 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
578 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
579 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
580 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
581 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
582 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
583 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
584 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
585 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
586 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
587 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
588 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
589 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
590 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
591 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
592 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
593 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
594 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
595 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
596 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
597 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
598 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
599 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
600 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
601 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
602 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
603 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
604 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
605 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
606 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
607 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
608 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
609 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
610 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
611 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
612 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
613 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
614 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
615 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
616 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
617 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
618 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
619 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
620 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
621 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
622 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
623 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
624 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
625 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
626 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
627 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
628 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
629 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
630 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
631 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
632 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
633 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
634 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
635 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
636 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
637 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
638 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
639 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
640 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
641 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
642 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
643 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
644 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
645 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
646 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
647 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
648 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
649 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
650 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
651
652// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
653// the final (optional) element of |kCustomSession| with tag number 30.
654static const char kBadSessionExtraField[] =
655 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
656 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
657 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
658 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
659 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
660 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
661 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
662 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
663
664// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
665// the version of |kCustomSession| with 2.
666static const char kBadSessionVersion[] =
667 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
668 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
669 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
670 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
671 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
672 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
673 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
674 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
675
676// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
677// appended.
678static const char kBadSessionTrailingData[] =
679 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
680 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
681 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
682 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
683 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
684 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
685 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
686 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
687
David Benjamin1d77e562015-03-22 17:22:08 -0400688static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400689 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400690 if (!EVP_DecodedLength(&len, strlen(in))) {
691 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400692 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400693 }
694
David Benjamin1d77e562015-03-22 17:22:08 -0400695 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800696 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400697 strlen(in))) {
698 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400699 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400700 }
David Benjamin1d77e562015-03-22 17:22:08 -0400701 out->resize(len);
702 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400703}
704
David Benjamin1d77e562015-03-22 17:22:08 -0400705static bool TestSSL_SESSIONEncoding(const char *input_b64) {
David Benjamin751e8892014-10-19 00:59:36 -0400706 const uint8_t *cptr;
707 uint8_t *ptr;
David Benjamin751e8892014-10-19 00:59:36 -0400708
David Benjamin1d77e562015-03-22 17:22:08 -0400709 // Decode the input.
710 std::vector<uint8_t> input;
711 if (!DecodeBase64(&input, input_b64)) {
712 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400713 }
714
David Benjamin1d77e562015-03-22 17:22:08 -0400715 // Verify the SSL_SESSION decodes.
Adam Langley46db7af2017-02-01 15:49:37 -0800716 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
717 if (!ssl_ctx) {
718 return false;
719 }
720 bssl::UniquePtr<SSL_SESSION> session(
721 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
David Benjaminfd67aa82015-06-15 19:41:48 -0400722 if (!session) {
723 fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400724 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400725 }
726
David Benjamin1d77e562015-03-22 17:22:08 -0400727 // Verify the SSL_SESSION encoding round-trips.
728 size_t encoded_len;
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700729 bssl::UniquePtr<uint8_t> encoded;
David Benjamin1d77e562015-03-22 17:22:08 -0400730 uint8_t *encoded_raw;
731 if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
David Benjamin3cac4502014-10-21 01:46:30 -0400732 fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400733 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400734 }
David Benjamin1d77e562015-03-22 17:22:08 -0400735 encoded.reset(encoded_raw);
736 if (encoded_len != input.size() ||
David Benjamin17cf2cb2016-12-13 01:07:13 -0500737 OPENSSL_memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin3cac4502014-10-21 01:46:30 -0400738 fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
Sigbjorn Vik2b23d242015-06-29 15:07:26 +0200739 hexdump(stderr, "Before: ", input.data(), input.size());
740 hexdump(stderr, "After: ", encoded_raw, encoded_len);
David Benjamin1d77e562015-03-22 17:22:08 -0400741 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400742 }
David Benjamin3cac4502014-10-21 01:46:30 -0400743
David Benjaminfd67aa82015-06-15 19:41:48 -0400744 // Verify the SSL_SESSION also decodes with the legacy API.
David Benjaminef14b2d2015-11-11 14:01:27 -0800745 cptr = input.data();
David Benjaminfd67aa82015-06-15 19:41:48 -0400746 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
David Benjaminef14b2d2015-11-11 14:01:27 -0800747 if (!session || cptr != input.data() + input.size()) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400748 fprintf(stderr, "d2i_SSL_SESSION failed\n");
749 return false;
750 }
751
David Benjamin1d77e562015-03-22 17:22:08 -0400752 // Verify the SSL_SESSION encoding round-trips via the legacy API.
753 int len = i2d_SSL_SESSION(session.get(), NULL);
754 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400755 fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400756 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400757 }
758
David Benjamin1d77e562015-03-22 17:22:08 -0400759 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
760 if (!encoded) {
David Benjamin751e8892014-10-19 00:59:36 -0400761 fprintf(stderr, "malloc failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400762 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400763 }
David Benjamin1d77e562015-03-22 17:22:08 -0400764
765 ptr = encoded.get();
766 len = i2d_SSL_SESSION(session.get(), &ptr);
767 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400768 fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400769 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400770 }
David Benjamin1d77e562015-03-22 17:22:08 -0400771 if (ptr != encoded.get() + input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400772 fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400773 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400774 }
David Benjamin17cf2cb2016-12-13 01:07:13 -0500775 if (OPENSSL_memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin751e8892014-10-19 00:59:36 -0400776 fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400777 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400778 }
779
David Benjamin1d77e562015-03-22 17:22:08 -0400780 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400781}
782
David Benjaminf297e022015-05-28 19:55:29 -0400783static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
784 std::vector<uint8_t> input;
785 if (!DecodeBase64(&input, input_b64)) {
786 return false;
787 }
788
789 // Verify that the SSL_SESSION fails to decode.
Adam Langley46db7af2017-02-01 15:49:37 -0800790 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
791 if (!ssl_ctx) {
792 return false;
793 }
794 bssl::UniquePtr<SSL_SESSION> session(
795 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
David Benjaminf297e022015-05-28 19:55:29 -0400796 if (session) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400797 fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
David Benjaminf297e022015-05-28 19:55:29 -0400798 return false;
799 }
800 ERR_clear_error();
801 return true;
802}
803
David Benjamin321fcdc2017-04-24 11:42:42 -0400804static void ExpectDefaultVersion(uint16_t min_version, uint16_t max_version,
805 const SSL_METHOD *(*method)(void)) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700806 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
David Benjamin321fcdc2017-04-24 11:42:42 -0400807 ASSERT_TRUE(ctx);
David Benjaminfc08dfc2017-06-20 14:39:32 -0400808 EXPECT_EQ(min_version, ctx->conf_min_version);
809 EXPECT_EQ(max_version, ctx->conf_max_version);
David Benjamin321fcdc2017-04-24 11:42:42 -0400810}
811
812TEST(SSLTest, DefaultVersion) {
813 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
814 ExpectDefaultVersion(TLS1_VERSION, TLS1_2_VERSION, &TLS_method);
815 ExpectDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method);
816 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method);
817 ExpectDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method);
818 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method);
819 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method);
820 ExpectDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method);
David Benjamin82c9e902014-12-12 15:55:27 -0500821}
822
David Benjamin348f0d82017-08-10 16:06:27 -0400823TEST(SSLTest, CipherProperties) {
David Benjamin6fff3862017-06-21 21:07:04 -0400824 static const struct {
825 int id;
826 const char *standard_name;
David Benjamin348f0d82017-08-10 16:06:27 -0400827 int cipher_nid;
828 int digest_nid;
829 int kx_nid;
830 int auth_nid;
David Benjamin6fff3862017-06-21 21:07:04 -0400831 } kTests[] = {
David Benjamin348f0d82017-08-10 16:06:27 -0400832 {
833 SSL3_CK_RSA_DES_192_CBC3_SHA,
834 "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
835 NID_des_ede3_cbc,
836 NID_sha1,
837 NID_kx_rsa,
838 NID_auth_rsa,
839 },
840 {
841 TLS1_CK_RSA_WITH_AES_128_SHA,
842 "TLS_RSA_WITH_AES_128_CBC_SHA",
843 NID_aes_128_cbc,
844 NID_sha1,
845 NID_kx_rsa,
846 NID_auth_rsa,
847 },
848 {
849 TLS1_CK_PSK_WITH_AES_256_CBC_SHA,
850 "TLS_PSK_WITH_AES_256_CBC_SHA",
851 NID_aes_256_cbc,
852 NID_sha1,
853 NID_kx_psk,
854 NID_auth_psk,
855 },
856 {
857 TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
858 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
859 NID_aes_128_cbc,
860 NID_sha256,
861 NID_kx_ecdhe,
862 NID_auth_rsa,
863 },
864 {
865 TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
866 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
867 NID_aes_256_cbc,
868 NID_sha384,
869 NID_kx_ecdhe,
870 NID_auth_rsa,
871 },
872 {
873 TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
874 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
875 NID_aes_128_gcm,
876 NID_undef,
877 NID_kx_ecdhe,
878 NID_auth_rsa,
879 },
880 {
881 TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
882 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
883 NID_aes_128_gcm,
884 NID_undef,
885 NID_kx_ecdhe,
886 NID_auth_ecdsa,
887 },
888 {
889 TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
890 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
891 NID_aes_256_gcm,
892 NID_undef,
893 NID_kx_ecdhe,
894 NID_auth_ecdsa,
895 },
896 {
897 TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
898 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
899 NID_aes_128_cbc,
900 NID_sha1,
901 NID_kx_ecdhe,
902 NID_auth_psk,
903 },
904 {
905 TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
906 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
907 NID_chacha20_poly1305,
908 NID_undef,
909 NID_kx_ecdhe,
910 NID_auth_rsa,
911 },
912 {
913 TLS1_CK_AES_256_GCM_SHA384,
914 "TLS_AES_256_GCM_SHA384",
915 NID_aes_256_gcm,
916 NID_undef,
917 NID_kx_any,
918 NID_auth_any,
919 },
920 {
921 TLS1_CK_AES_128_GCM_SHA256,
922 "TLS_AES_128_GCM_SHA256",
923 NID_aes_128_gcm,
924 NID_undef,
925 NID_kx_any,
926 NID_auth_any,
927 },
928 {
929 TLS1_CK_CHACHA20_POLY1305_SHA256,
930 "TLS_CHACHA20_POLY1305_SHA256",
931 NID_chacha20_poly1305,
932 NID_undef,
933 NID_kx_any,
934 NID_auth_any,
935 },
David Benjamin6fff3862017-06-21 21:07:04 -0400936 };
David Benjamin65226252015-02-05 16:49:47 -0500937
David Benjamin6fff3862017-06-21 21:07:04 -0400938 for (const auto &t : kTests) {
939 SCOPED_TRACE(t.standard_name);
David Benjamine11726a2017-04-23 12:14:28 -0400940
941 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(t.id & 0xffff);
942 ASSERT_TRUE(cipher);
David Benjamin6fff3862017-06-21 21:07:04 -0400943 EXPECT_STREQ(t.standard_name, SSL_CIPHER_standard_name(cipher));
944
David Benjamine11726a2017-04-23 12:14:28 -0400945 bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
946 ASSERT_TRUE(rfc_name);
David Benjamin6fff3862017-06-21 21:07:04 -0400947 EXPECT_STREQ(t.standard_name, rfc_name.get());
David Benjamin348f0d82017-08-10 16:06:27 -0400948
949 EXPECT_EQ(t.cipher_nid, SSL_CIPHER_get_cipher_nid(cipher));
950 EXPECT_EQ(t.digest_nid, SSL_CIPHER_get_digest_nid(cipher));
951 EXPECT_EQ(t.kx_nid, SSL_CIPHER_get_kx_nid(cipher));
952 EXPECT_EQ(t.auth_nid, SSL_CIPHER_get_auth_nid(cipher));
David Benjamin65226252015-02-05 16:49:47 -0500953 }
David Benjamin65226252015-02-05 16:49:47 -0500954}
955
Steven Valdeza833c352016-11-01 13:39:36 -0400956// CreateSessionWithTicket returns a sample |SSL_SESSION| with the specified
957// version and ticket length or nullptr on failure.
958static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(uint16_t version,
959 size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -0400960 std::vector<uint8_t> der;
961 if (!DecodeBase64(&der, kOpenSSLSession)) {
962 return nullptr;
963 }
Adam Langley46db7af2017-02-01 15:49:37 -0800964
965 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
966 if (!ssl_ctx) {
967 return nullptr;
968 }
Steven Valdeza833c352016-11-01 13:39:36 -0400969 bssl::UniquePtr<SSL_SESSION> session(
Adam Langley46db7af2017-02-01 15:49:37 -0800970 SSL_SESSION_from_bytes(der.data(), der.size(), ssl_ctx.get()));
David Benjamin422fe082015-07-21 22:03:43 -0400971 if (!session) {
972 return nullptr;
973 }
974
Steven Valdeza833c352016-11-01 13:39:36 -0400975 session->ssl_version = version;
976
David Benjamin422fe082015-07-21 22:03:43 -0400977 // Swap out the ticket for a garbage one.
978 OPENSSL_free(session->tlsext_tick);
979 session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len));
980 if (session->tlsext_tick == nullptr) {
981 return nullptr;
982 }
David Benjamin17cf2cb2016-12-13 01:07:13 -0500983 OPENSSL_memset(session->tlsext_tick, 'a', ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -0400984 session->tlsext_ticklen = ticket_len;
David Benjamin1269ddd2015-10-18 15:18:55 -0400985
986 // Fix up the timeout.
David Benjamin9b63f292016-11-15 00:44:05 -0500987#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
988 session->time = 1234;
989#else
David Benjamin1269ddd2015-10-18 15:18:55 -0400990 session->time = time(NULL);
David Benjamin9b63f292016-11-15 00:44:05 -0500991#endif
David Benjamin422fe082015-07-21 22:03:43 -0400992 return session;
993}
994
David Benjaminafc64de2016-07-19 17:12:41 +0200995static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700996 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +0200997 if (!bio) {
998 return false;
999 }
1000 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -04001001 BIO_up_ref(bio.get());
1002 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +02001003 int ret = SSL_connect(ssl);
1004 if (ret > 0) {
1005 // SSL_connect should fail without a BIO to write to.
1006 return false;
1007 }
1008 ERR_clear_error();
1009
1010 const uint8_t *client_hello;
1011 size_t client_hello_len;
1012 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
1013 return false;
1014 }
1015 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
1016 return true;
1017}
1018
Steven Valdeza833c352016-11-01 13:39:36 -04001019// GetClientHelloLen creates a client SSL connection with the specified version
1020// and ticket length. It returns the length of the ClientHello, not including
1021// the record header, on success and zero on error.
1022static size_t GetClientHelloLen(uint16_t max_version, uint16_t session_version,
1023 size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001024 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Steven Valdeza833c352016-11-01 13:39:36 -04001025 bssl::UniquePtr<SSL_SESSION> session =
1026 CreateSessionWithTicket(session_version, ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -04001027 if (!ctx || !session) {
1028 return 0;
1029 }
Steven Valdeza833c352016-11-01 13:39:36 -04001030
1031 // Set a one-element cipher list so the baseline ClientHello is unpadded.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001032 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
Steven Valdez2c62fe92016-10-14 12:08:12 -04001033 if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -08001034 !SSL_set_strict_cipher_list(ssl.get(), "ECDHE-RSA-AES128-GCM-SHA256") ||
Steven Valdeza833c352016-11-01 13:39:36 -04001035 !SSL_set_max_proto_version(ssl.get(), max_version)) {
David Benjamin422fe082015-07-21 22:03:43 -04001036 return 0;
1037 }
Steven Valdeza833c352016-11-01 13:39:36 -04001038
David Benjaminafc64de2016-07-19 17:12:41 +02001039 std::vector<uint8_t> client_hello;
1040 if (!GetClientHello(ssl.get(), &client_hello) ||
1041 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -04001042 return 0;
1043 }
Steven Valdeza833c352016-11-01 13:39:36 -04001044
David Benjaminafc64de2016-07-19 17:12:41 +02001045 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -04001046}
1047
1048struct PaddingTest {
1049 size_t input_len, padded_len;
1050};
1051
1052static const PaddingTest kPaddingTests[] = {
1053 // ClientHellos of length below 0x100 do not require padding.
1054 {0xfe, 0xfe},
1055 {0xff, 0xff},
1056 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
1057 {0x100, 0x200},
1058 {0x123, 0x200},
1059 {0x1fb, 0x200},
1060 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
1061 // padding extension takes a minimum of four bytes plus one required content
1062 // byte. (To work around yet more server bugs, we avoid empty final
1063 // extensions.)
1064 {0x1fc, 0x201},
1065 {0x1fd, 0x202},
1066 {0x1fe, 0x203},
1067 {0x1ff, 0x204},
1068 // Finally, larger ClientHellos need no padding.
1069 {0x200, 0x200},
1070 {0x201, 0x201},
1071};
1072
Steven Valdeza833c352016-11-01 13:39:36 -04001073static bool TestPaddingExtension(uint16_t max_version,
1074 uint16_t session_version) {
David Benjamin422fe082015-07-21 22:03:43 -04001075 // Sample a baseline length.
Steven Valdeza833c352016-11-01 13:39:36 -04001076 size_t base_len = GetClientHelloLen(max_version, session_version, 1);
David Benjamin422fe082015-07-21 22:03:43 -04001077 if (base_len == 0) {
1078 return false;
1079 }
1080
1081 for (const PaddingTest &test : kPaddingTests) {
1082 if (base_len > test.input_len) {
Steven Valdeza833c352016-11-01 13:39:36 -04001083 fprintf(stderr,
1084 "Baseline ClientHello too long (max_version = %04x, "
1085 "session_version = %04x).\n",
1086 max_version, session_version);
David Benjamin422fe082015-07-21 22:03:43 -04001087 return false;
1088 }
1089
Steven Valdeza833c352016-11-01 13:39:36 -04001090 size_t padded_len = GetClientHelloLen(max_version, session_version,
1091 1 + test.input_len - base_len);
David Benjamin422fe082015-07-21 22:03:43 -04001092 if (padded_len != test.padded_len) {
Steven Valdeza833c352016-11-01 13:39:36 -04001093 fprintf(stderr,
1094 "%u-byte ClientHello padded to %u bytes, not %u (max_version = "
1095 "%04x, session_version = %04x).\n",
David Benjamin422fe082015-07-21 22:03:43 -04001096 static_cast<unsigned>(test.input_len),
1097 static_cast<unsigned>(padded_len),
Steven Valdeza833c352016-11-01 13:39:36 -04001098 static_cast<unsigned>(test.padded_len), max_version,
1099 session_version);
David Benjamin422fe082015-07-21 22:03:43 -04001100 return false;
1101 }
1102 }
Steven Valdeza833c352016-11-01 13:39:36 -04001103
David Benjamin422fe082015-07-21 22:03:43 -04001104 return true;
1105}
1106
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001107static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001108 static const char kCertPEM[] =
1109 "-----BEGIN CERTIFICATE-----\n"
1110 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1111 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1112 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1113 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1114 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1115 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1116 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1117 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1118 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1119 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1120 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1121 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1122 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1123 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001124 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
David Benjamin1444c3a2016-12-20 17:23:11 -05001125 return bssl::UniquePtr<X509>(
1126 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjaminde942382016-02-11 12:02:01 -05001127}
1128
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001129static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001130 static const char kKeyPEM[] =
1131 "-----BEGIN RSA PRIVATE KEY-----\n"
1132 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1133 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1134 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1135 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1136 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1137 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1138 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1139 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1140 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1141 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1142 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1143 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1144 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1145 "-----END RSA PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001146 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1147 return bssl::UniquePtr<EVP_PKEY>(
David Benjaminde942382016-02-11 12:02:01 -05001148 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1149}
1150
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001151static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001152 static const char kCertPEM[] =
1153 "-----BEGIN CERTIFICATE-----\n"
1154 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1155 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1156 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1157 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1158 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1159 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1160 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1161 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1162 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1163 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1164 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001165 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1166 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjamin0fc37ef2016-08-17 15:29:46 -04001167}
1168
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001169static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001170 static const char kKeyPEM[] =
1171 "-----BEGIN PRIVATE KEY-----\n"
1172 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1173 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1174 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1175 "-----END PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001176 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1177 return bssl::UniquePtr<EVP_PKEY>(
David Benjamin0fc37ef2016-08-17 15:29:46 -04001178 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1179}
1180
Adam Langleyd04ca952017-02-28 11:26:51 -08001181static bssl::UniquePtr<CRYPTO_BUFFER> BufferFromPEM(const char *pem) {
1182 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1183 char *name, *header;
1184 uint8_t *data;
1185 long data_len;
1186 if (!PEM_read_bio(bio.get(), &name, &header, &data,
1187 &data_len)) {
1188 return nullptr;
1189 }
1190 OPENSSL_free(name);
1191 OPENSSL_free(header);
1192
1193 auto ret = bssl::UniquePtr<CRYPTO_BUFFER>(
1194 CRYPTO_BUFFER_new(data, data_len, nullptr));
1195 OPENSSL_free(data);
1196 return ret;
1197}
1198
1199static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestCertificateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001200 static const char kCertPEM[] =
1201 "-----BEGIN CERTIFICATE-----\n"
1202 "MIIC0jCCAbqgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQiBD\n"
1203 "QTAeFw0xNjAyMjgyMDI3MDNaFw0yNjAyMjUyMDI3MDNaMBgxFjAUBgNVBAMMDUNs\n"
1204 "aWVudCBDZXJ0IEEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRvaz8\n"
1205 "CC/cshpCafJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/\n"
1206 "kLRcH89M/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3\n"
1207 "tHb+xs2PSs8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+c\n"
1208 "IDs2rQ+lP7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1\n"
1209 "z7C8jU50Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9V\n"
1210 "iLeXANgZi+Xx9KgfAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI\n"
1211 "KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBFEVbmYl+2RtNw\n"
1212 "rDftRDF1v2QUbcN2ouSnQDHxeDQdSgasLzT3ui8iYu0Rw2WWcZ0DV5e0ztGPhWq7\n"
1213 "AO0B120aFRMOY+4+bzu9Q2FFkQqc7/fKTvTDzIJI5wrMnFvUfzzvxh3OHWMYSs/w\n"
1214 "giq33hTKeHEq6Jyk3btCny0Ycecyc3yGXH10sizUfiHlhviCkDuESk8mFDwDDzqW\n"
1215 "ZF0IipzFbEDHoIxLlm3GQxpiLoEV4k8KYJp3R5KBLFyxM6UGPz8h72mIPCJp2RuK\n"
1216 "MYgF91UDvVzvnYm6TfseM2+ewKirC00GOrZ7rEcFvtxnKSqYf4ckqfNdSU1Y+RRC\n"
1217 "1ngWZ7Ih\n"
1218 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001219 return BufferFromPEM(kCertPEM);
David Benjamin1444c3a2016-12-20 17:23:11 -05001220}
1221
Adam Langleyd04ca952017-02-28 11:26:51 -08001222static bssl::UniquePtr<X509> X509FromBuffer(
1223 bssl::UniquePtr<CRYPTO_BUFFER> buffer) {
1224 if (!buffer) {
1225 return nullptr;
1226 }
1227 const uint8_t *derp = CRYPTO_BUFFER_data(buffer.get());
1228 return bssl::UniquePtr<X509>(
1229 d2i_X509(NULL, &derp, CRYPTO_BUFFER_len(buffer.get())));
1230}
1231
1232static bssl::UniquePtr<X509> GetChainTestCertificate() {
1233 return X509FromBuffer(GetChainTestCertificateBuffer());
1234}
1235
1236static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestIntermediateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001237 static const char kCertPEM[] =
1238 "-----BEGIN CERTIFICATE-----\n"
1239 "MIICwjCCAaqgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS\n"
1240 "b290IENBMB4XDTE2MDIyODIwMjcwM1oXDTI2MDIyNTIwMjcwM1owDzENMAsGA1UE\n"
1241 "AwwEQiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALsSCYmDip2D\n"
1242 "GkjFxw7ykz26JSjELkl6ArlYjFJ3aT/SCh8qbS4gln7RH8CPBd78oFdfhIKQrwtZ\n"
1243 "3/q21ykD9BAS3qHe2YdcJfm8/kWAy5DvXk6NXU4qX334KofBAEpgdA/igEFq1P1l\n"
1244 "HAuIfZCpMRfT+i5WohVsGi8f/NgpRvVaMONLNfgw57mz1lbtFeBEISmX0kbsuJxF\n"
1245 "Qj/Bwhi5/0HAEXG8e7zN4cEx0yPRvmOATRdVb/8dW2pwOHRJq9R5M0NUkIsTSnL7\n"
1246 "6N/z8hRAHMsV3IudC5Yd7GXW1AGu9a+iKU+Q4xcZCoj0DC99tL4VKujrV1kAeqsM\n"
1247 "cz5/dKzi6+cCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
1248 "AQYwDQYJKoZIhvcNAQELBQADggEBAIIeZiEeNhWWQ8Y4D+AGDwqUUeG8NjCbKrXQ\n"
1249 "BlHg5wZ8xftFaiP1Dp/UAezmx2LNazdmuwrYB8lm3FVTyaPDTKEGIPS4wJKHgqH1\n"
1250 "QPDhqNm85ey7TEtI9oYjsNim/Rb+iGkIAMXaxt58SzxbjvP0kMr1JfJIZbic9vye\n"
1251 "NwIspMFIpP3FB8ywyu0T0hWtCQgL4J47nigCHpOu58deP88fS/Nyz/fyGVWOZ76b\n"
1252 "WhWwgM3P3X95fQ3d7oFPR/bVh0YV+Cf861INwplokXgXQ3/TCQ+HNXeAMWn3JLWv\n"
1253 "XFwk8owk9dq/kQGdndGgy3KTEW4ctPX5GNhf3LJ9Q7dLji4ReQ4=\n"
1254 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001255 return BufferFromPEM(kCertPEM);
1256}
1257
1258static bssl::UniquePtr<X509> GetChainTestIntermediate() {
1259 return X509FromBuffer(GetChainTestIntermediateBuffer());
David Benjamin1444c3a2016-12-20 17:23:11 -05001260}
1261
1262static bssl::UniquePtr<EVP_PKEY> GetChainTestKey() {
1263 static const char kKeyPEM[] =
1264 "-----BEGIN PRIVATE KEY-----\n"
1265 "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRvaz8CC/cshpC\n"
1266 "afJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/kLRcH89M\n"
1267 "/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3tHb+xs2P\n"
1268 "Ss8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+cIDs2rQ+l\n"
1269 "P7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1z7C8jU50\n"
1270 "Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9ViLeXANgZ\n"
1271 "i+Xx9KgfAgMBAAECggEBAK0VjSJzkyPaamcyTVSWjo7GdaBGcK60lk657RjR+lK0\n"
1272 "YJ7pkej4oM2hdsVZFsP8Cs4E33nXLa/0pDsRov/qrp0WQm2skwqGMC1I/bZ0WRPk\n"
1273 "wHaDrBBfESWnJDX/AGpVtlyOjPmgmK6J2usMPihQUDkKdAYrVWJePrMIxt1q6BMe\n"
1274 "iczs3qriMmtY3bUc4UyUwJ5fhDLjshHvfuIpYQyI6EXZM6dZksn9LylXJnigY6QJ\n"
1275 "HxOYO0BDwOsZ8yQ8J8afLk88i0GizEkgE1z3REtQUwgWfxr1WV/ud+T6/ZhSAgH9\n"
1276 "042mQvSFZnIUSEsmCvjhWuAunfxHKCTcAoYISWfzWpkCgYEA7gpf3HHU5Tn+CgUn\n"
1277 "1X5uGpG3DmcMgfeGgs2r2f/IIg/5Ac1dfYILiybL1tN9zbyLCJfcbFpWBc9hJL6f\n"
1278 "CPc5hUiwWFJqBJewxQkC1Ae/HakHbip+IZ+Jr0842O4BAArvixk4Lb7/N2Ct9sTE\n"
1279 "NJO6RtK9lbEZ5uK61DglHy8CS2UCgYEA4ZC1o36kPAMQBggajgnucb2yuUEelk0f\n"
1280 "AEr+GI32MGE+93xMr7rAhBoqLg4AITyIfEnOSQ5HwagnIHonBbv1LV/Gf9ursx8Z\n"
1281 "YOGbvT8zzzC+SU1bkDzdjAYnFQVGIjMtKOBJ3K07++ypwX1fr4QsQ8uKL8WSOWwt\n"
1282 "Z3Bym6XiZzMCgYADnhy+2OwHX85AkLt+PyGlPbmuelpyTzS4IDAQbBa6jcuW/2wA\n"
1283 "UE2km75VUXmD+u2R/9zVuLm99NzhFhSMqlUxdV1YukfqMfP5yp1EY6m/5aW7QuIP\n"
1284 "2MDa7TVL9rIFMiVZ09RKvbBbQxjhuzPQKL6X/PPspnhiTefQ+dl2k9xREQKBgHDS\n"
1285 "fMfGNEeAEKezrfSVqxphE9/tXms3L+ZpnCaT+yu/uEr5dTIAawKoQ6i9f/sf1/Sy\n"
1286 "xedsqR+IB+oKrzIDDWMgoJybN4pkZ8E5lzhVQIjFjKgFdWLzzqyW9z1gYfABQPlN\n"
1287 "FiS20WX0vgP1vcKAjdNrHzc9zyHBpgQzDmAj3NZZAoGBAI8vKCKdH7w3aL5CNkZQ\n"
1288 "2buIeWNA2HZazVwAGG5F2TU/LmXfRKnG6dX5bkU+AkBZh56jNZy//hfFSewJB4Kk\n"
1289 "buB7ERSdaNbO21zXt9FEA3+z0RfMd/Zv2vlIWOSB5nzl/7UKti3sribK6s9ZVLfi\n"
1290 "SxpiPQ8d/hmSGwn4ksrWUsJD\n"
1291 "-----END PRIVATE KEY-----\n";
1292 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1293 return bssl::UniquePtr<EVP_PKEY>(
1294 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1295}
1296
David Benjaminc79ae7a2017-08-29 16:09:44 -04001297// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
1298// before configuring as a server.
1299TEST(SSLTest, ClientCAList) {
1300 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1301 ASSERT_TRUE(ctx);
1302 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1303 ASSERT_TRUE(ssl);
1304
1305 bssl::UniquePtr<X509_NAME> name(X509_NAME_new());
1306 ASSERT_TRUE(name);
1307
1308 bssl::UniquePtr<X509_NAME> name_dup(X509_NAME_dup(name.get()));
1309 ASSERT_TRUE(name_dup);
1310
1311 bssl::UniquePtr<STACK_OF(X509_NAME)> stack(sk_X509_NAME_new_null());
1312 ASSERT_TRUE(stack);
1313
1314 ASSERT_TRUE(sk_X509_NAME_push(stack.get(), name_dup.get()));
1315 name_dup.release();
1316
1317 // |SSL_set_client_CA_list| takes ownership.
1318 SSL_set_client_CA_list(ssl.get(), stack.release());
1319
1320 STACK_OF(X509_NAME) *result = SSL_get_client_CA_list(ssl.get());
1321 ASSERT_TRUE(result);
1322 ASSERT_EQ(1u, sk_X509_NAME_num(result));
1323 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(result, 0), name.get()));
1324}
1325
1326TEST(SSLTest, AddClientCA) {
1327 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1328 ASSERT_TRUE(ctx);
1329 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1330 ASSERT_TRUE(ssl);
1331
1332 bssl::UniquePtr<X509> cert1 = GetTestCertificate();
1333 bssl::UniquePtr<X509> cert2 = GetChainTestCertificate();
1334 ASSERT_TRUE(cert1 && cert2);
1335 X509_NAME *name1 = X509_get_subject_name(cert1.get());
1336 X509_NAME *name2 = X509_get_subject_name(cert2.get());
1337
1338 EXPECT_EQ(0u, sk_X509_NAME_num(SSL_get_client_CA_list(ssl.get())));
1339
1340 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1341 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert2.get()));
1342
1343 STACK_OF(X509_NAME) *list = SSL_get_client_CA_list(ssl.get());
1344 ASSERT_EQ(2u, sk_X509_NAME_num(list));
1345 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1346 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1347
1348 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1349
1350 list = SSL_get_client_CA_list(ssl.get());
1351 ASSERT_EQ(3u, sk_X509_NAME_num(list));
1352 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1353 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1354 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 2), name1));
1355}
1356
1357static void AppendSession(SSL_SESSION *session, void *arg) {
1358 std::vector<SSL_SESSION*> *out =
1359 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
1360 out->push_back(session);
1361}
1362
1363// CacheEquals returns true if |ctx|'s session cache consists of |expected|, in
1364// order.
1365static bool CacheEquals(SSL_CTX *ctx,
1366 const std::vector<SSL_SESSION*> &expected) {
1367 // Check the linked list.
1368 SSL_SESSION *ptr = ctx->session_cache_head;
1369 for (SSL_SESSION *session : expected) {
1370 if (ptr != session) {
1371 return false;
1372 }
1373 // TODO(davidben): This is an absurd way to denote the end of the list.
1374 if (ptr->next ==
1375 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
1376 ptr = nullptr;
1377 } else {
1378 ptr = ptr->next;
1379 }
1380 }
1381 if (ptr != nullptr) {
1382 return false;
1383 }
1384
1385 // Check the hash table.
1386 std::vector<SSL_SESSION*> actual, expected_copy;
1387 lh_SSL_SESSION_doall_arg(SSL_CTX_sessions(ctx), AppendSession, &actual);
1388 expected_copy = expected;
1389
1390 std::sort(actual.begin(), actual.end());
1391 std::sort(expected_copy.begin(), expected_copy.end());
1392
1393 return actual == expected_copy;
1394}
1395
1396static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
1397 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
1398 if (!ssl_ctx) {
1399 return nullptr;
1400 }
1401 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new(ssl_ctx.get()));
1402 if (!ret) {
1403 return nullptr;
1404 }
1405
1406 ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
1407 OPENSSL_memset(ret->session_id, 0, ret->session_id_length);
1408 OPENSSL_memcpy(ret->session_id, &number, sizeof(number));
1409 return ret;
1410}
1411
1412// Test that the internal session cache behaves as expected.
1413TEST(SSLTest, InternalSessionCache) {
1414 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1415 ASSERT_TRUE(ctx);
1416
1417 // Prepare 10 test sessions.
1418 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
1419 for (int i = 0; i < 10; i++) {
1420 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
1421 ASSERT_TRUE(session);
1422 sessions.push_back(std::move(session));
1423 }
1424
1425 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1426
1427 // Insert all the test sessions.
1428 for (const auto &session : sessions) {
1429 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), session.get()));
1430 }
1431
1432 // Only the last five should be in the list.
1433 ASSERT_TRUE(CacheEquals(
1434 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
1435 sessions[6].get(), sessions[5].get()}));
1436
1437 // Inserting an element already in the cache should fail and leave the cache
1438 // unchanged.
1439 ASSERT_FALSE(SSL_CTX_add_session(ctx.get(), sessions[7].get()));
1440 ASSERT_TRUE(CacheEquals(
1441 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
1442 sessions[6].get(), sessions[5].get()}));
1443
1444 // Although collisions should be impossible (256-bit session IDs), the cache
1445 // must handle them gracefully.
1446 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
1447 ASSERT_TRUE(collision);
1448 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), collision.get()));
1449 ASSERT_TRUE(CacheEquals(
1450 ctx.get(), {collision.get(), sessions[9].get(), sessions[8].get(),
1451 sessions[6].get(), sessions[5].get()}));
1452
1453 // Removing sessions behaves correctly.
1454 ASSERT_TRUE(SSL_CTX_remove_session(ctx.get(), sessions[6].get()));
1455 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
1456 sessions[8].get(), sessions[5].get()}));
1457
1458 // Removing sessions requires an exact match.
1459 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[0].get()));
1460 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[7].get()));
1461
1462 // The cache remains unchanged.
1463 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
1464 sessions[8].get(), sessions[5].get()}));
1465}
1466
1467static uint16_t EpochFromSequence(uint64_t seq) {
1468 return static_cast<uint16_t>(seq >> 48);
1469}
1470
David Benjamin71dfad42017-07-16 17:27:39 -04001471static const uint8_t kTestName[] = {
1472 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
1473 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
1474 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
1475 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
1476 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
1477 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64,
1478};
1479
David Benjaminb79cc842016-12-07 15:57:14 -05001480static bool CompleteHandshakes(SSL *client, SSL *server) {
1481 // Drive both their handshakes to completion.
1482 for (;;) {
1483 int client_ret = SSL_do_handshake(client);
1484 int client_err = SSL_get_error(client, client_ret);
1485 if (client_err != SSL_ERROR_NONE &&
1486 client_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001487 client_err != SSL_ERROR_WANT_WRITE &&
1488 client_err != SSL_ERROR_PENDING_TICKET) {
David Benjaminb79cc842016-12-07 15:57:14 -05001489 fprintf(stderr, "Client error: %d\n", client_err);
1490 return false;
1491 }
1492
1493 int server_ret = SSL_do_handshake(server);
1494 int server_err = SSL_get_error(server, server_ret);
1495 if (server_err != SSL_ERROR_NONE &&
1496 server_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001497 server_err != SSL_ERROR_WANT_WRITE &&
1498 server_err != SSL_ERROR_PENDING_TICKET) {
David Benjaminb79cc842016-12-07 15:57:14 -05001499 fprintf(stderr, "Server error: %d\n", server_err);
1500 return false;
1501 }
1502
1503 if (client_ret == 1 && server_ret == 1) {
1504 break;
1505 }
1506 }
1507
1508 return true;
1509}
1510
David Benjamina8614602017-09-06 15:40:19 -04001511struct ClientConfig {
1512 SSL_SESSION *session = nullptr;
1513 std::string servername;
1514};
1515
David Benjaminb79cc842016-12-07 15:57:14 -05001516static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client,
1517 bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001518 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
David Benjamina8614602017-09-06 15:40:19 -04001519 const ClientConfig &config = ClientConfig()) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001520 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001521 if (!client || !server) {
1522 return false;
1523 }
1524 SSL_set_connect_state(client.get());
1525 SSL_set_accept_state(server.get());
1526
David Benjamina8614602017-09-06 15:40:19 -04001527 if (config.session) {
1528 SSL_set_session(client.get(), config.session);
1529 }
1530 if (!config.servername.empty() &&
1531 !SSL_set_tlsext_host_name(client.get(), config.servername.c_str())) {
1532 return false;
1533 }
David Benjamina20e5352016-08-02 19:09:41 -04001534
David Benjaminde942382016-02-11 12:02:01 -05001535 BIO *bio1, *bio2;
1536 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1537 return false;
1538 }
1539 // SSL_set_bio takes ownership.
1540 SSL_set_bio(client.get(), bio1, bio1);
1541 SSL_set_bio(server.get(), bio2, bio2);
1542
David Benjaminb79cc842016-12-07 15:57:14 -05001543 if (!CompleteHandshakes(client.get(), server.get())) {
1544 return false;
David Benjaminde942382016-02-11 12:02:01 -05001545 }
1546
David Benjamin686bb192016-05-10 15:15:41 -04001547 *out_client = std::move(client);
1548 *out_server = std::move(server);
1549 return true;
1550}
1551
David Benjaminc11ea9422017-08-29 16:33:21 -04001552// SSLVersionTest executes its test cases under all available protocol versions.
1553// Test cases call |Connect| to create a connection using context objects with
1554// the protocol version fixed to the current version under test.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001555class SSLVersionTest : public ::testing::TestWithParam<VersionParam> {
1556 protected:
1557 SSLVersionTest() : cert_(GetTestCertificate()), key_(GetTestKey()) {}
1558
1559 void SetUp() { ResetContexts(); }
1560
1561 bssl::UniquePtr<SSL_CTX> CreateContext() const {
1562 const SSL_METHOD *method = is_dtls() ? DTLS_method() : TLS_method();
1563 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
1564 if (!ctx || !SSL_CTX_set_min_proto_version(ctx.get(), version()) ||
1565 !SSL_CTX_set_max_proto_version(ctx.get(), version())) {
1566 return nullptr;
1567 }
1568 return ctx;
David Benjamin0fef3052016-11-18 15:11:10 +09001569 }
David Benjamin686bb192016-05-10 15:15:41 -04001570
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001571 void ResetContexts() {
1572 ASSERT_TRUE(cert_);
1573 ASSERT_TRUE(key_);
1574 client_ctx_ = CreateContext();
1575 ASSERT_TRUE(client_ctx_);
1576 server_ctx_ = CreateContext();
1577 ASSERT_TRUE(server_ctx_);
1578 // Set up a server cert. Client certs can be set up explicitly.
1579 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09001580 }
David Benjamin686bb192016-05-10 15:15:41 -04001581
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001582 bool UseCertAndKey(SSL_CTX *ctx) const {
1583 return SSL_CTX_use_certificate(ctx, cert_.get()) &&
1584 SSL_CTX_use_PrivateKey(ctx, key_.get());
David Benjamin0fef3052016-11-18 15:11:10 +09001585 }
David Benjamin686bb192016-05-10 15:15:41 -04001586
David Benjamina8614602017-09-06 15:40:19 -04001587 bool Connect(const ClientConfig &config = ClientConfig()) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001588 return ConnectClientAndServer(&client_, &server_, client_ctx_.get(),
David Benjamina8614602017-09-06 15:40:19 -04001589 server_ctx_.get(), config);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001590 }
1591
1592 uint16_t version() const { return GetParam().version; }
1593
1594 bool is_dtls() const {
1595 return GetParam().ssl_method == VersionParam::is_dtls;
1596 }
1597
1598 bssl::UniquePtr<SSL> client_, server_;
1599 bssl::UniquePtr<SSL_CTX> server_ctx_, client_ctx_;
1600 bssl::UniquePtr<X509> cert_;
1601 bssl::UniquePtr<EVP_PKEY> key_;
1602};
1603
1604INSTANTIATE_TEST_CASE_P(WithVersion, SSLVersionTest,
1605 testing::ValuesIn(kAllVersions),
1606 [](const testing::TestParamInfo<VersionParam> &i) {
1607 return i.param.name;
1608 });
1609
1610TEST_P(SSLVersionTest, SequenceNumber) {
1611 ASSERT_TRUE(Connect());
1612
David Benjamin0fef3052016-11-18 15:11:10 +09001613 // Drain any post-handshake messages to ensure there are no unread records
1614 // on either end.
1615 uint8_t byte = 0;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001616 ASSERT_LE(SSL_read(client_.get(), &byte, 1), 0);
1617 ASSERT_LE(SSL_read(server_.get(), &byte, 1), 0);
David Benjaminde942382016-02-11 12:02:01 -05001618
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001619 uint64_t client_read_seq = SSL_get_read_sequence(client_.get());
1620 uint64_t client_write_seq = SSL_get_write_sequence(client_.get());
1621 uint64_t server_read_seq = SSL_get_read_sequence(server_.get());
1622 uint64_t server_write_seq = SSL_get_write_sequence(server_.get());
Steven Valdez2c62fe92016-10-14 12:08:12 -04001623
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001624 if (is_dtls()) {
David Benjamin0fef3052016-11-18 15:11:10 +09001625 // Both client and server must be at epoch 1.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001626 EXPECT_EQ(EpochFromSequence(client_read_seq), 1);
1627 EXPECT_EQ(EpochFromSequence(client_write_seq), 1);
1628 EXPECT_EQ(EpochFromSequence(server_read_seq), 1);
1629 EXPECT_EQ(EpochFromSequence(server_write_seq), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09001630
1631 // The next record to be written should exceed the largest received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001632 EXPECT_GT(client_write_seq, server_read_seq);
1633 EXPECT_GT(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09001634 } else {
1635 // The next record to be written should equal the next to be received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001636 EXPECT_EQ(client_write_seq, server_read_seq);
1637 EXPECT_EQ(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09001638 }
1639
1640 // Send a record from client to server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001641 EXPECT_EQ(SSL_write(client_.get(), &byte, 1), 1);
1642 EXPECT_EQ(SSL_read(server_.get(), &byte, 1), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09001643
1644 // The client write and server read sequence numbers should have
1645 // incremented.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001646 EXPECT_EQ(client_write_seq + 1, SSL_get_write_sequence(client_.get()));
1647 EXPECT_EQ(server_read_seq + 1, SSL_get_read_sequence(server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05001648}
1649
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001650TEST_P(SSLVersionTest, OneSidedShutdown) {
David Benjamin68f37b72016-11-18 15:14:42 +09001651 // SSL_shutdown is a no-op in DTLS.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001652 if (is_dtls()) {
1653 return;
David Benjamin686bb192016-05-10 15:15:41 -04001654 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001655 ASSERT_TRUE(Connect());
David Benjamin686bb192016-05-10 15:15:41 -04001656
1657 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1658 // one side has shut down.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001659 ASSERT_EQ(SSL_shutdown(client_.get()), 0);
David Benjamin686bb192016-05-10 15:15:41 -04001660
1661 // Reading from the server should consume the EOF.
1662 uint8_t byte;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001663 ASSERT_EQ(SSL_read(server_.get(), &byte, 1), 0);
1664 ASSERT_EQ(SSL_get_error(server_.get(), 0), SSL_ERROR_ZERO_RETURN);
David Benjamin686bb192016-05-10 15:15:41 -04001665
1666 // However, the server may continue to write data and then shut down the
1667 // connection.
1668 byte = 42;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001669 ASSERT_EQ(SSL_write(server_.get(), &byte, 1), 1);
1670 ASSERT_EQ(SSL_read(client_.get(), &byte, 1), 1);
1671 ASSERT_EQ(byte, 42);
David Benjamin686bb192016-05-10 15:15:41 -04001672
1673 // The server may then shutdown the connection.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001674 EXPECT_EQ(SSL_shutdown(server_.get()), 1);
1675 EXPECT_EQ(SSL_shutdown(client_.get()), 1);
David Benjamin686bb192016-05-10 15:15:41 -04001676}
David Benjamin68f37b72016-11-18 15:14:42 +09001677
David Benjaminf0d8e222017-02-04 10:58:26 -05001678TEST(SSLTest, SessionDuplication) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001679 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1680 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001681 ASSERT_TRUE(client_ctx);
1682 ASSERT_TRUE(server_ctx);
Steven Valdez87eab492016-06-27 16:34:59 -04001683
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001684 bssl::UniquePtr<X509> cert = GetTestCertificate();
1685 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminf0d8e222017-02-04 10:58:26 -05001686 ASSERT_TRUE(cert);
1687 ASSERT_TRUE(key);
1688 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
1689 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04001690
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001691 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05001692 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04001693 server_ctx.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04001694
1695 SSL_SESSION *session0 = SSL_get_session(client.get());
David Benjamin31b0c9b2017-07-20 14:49:15 -04001696 bssl::UniquePtr<SSL_SESSION> session1 =
1697 bssl::SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL);
David Benjaminf0d8e222017-02-04 10:58:26 -05001698 ASSERT_TRUE(session1);
David Benjamin4501bd52016-08-01 13:39:41 -04001699
Steven Valdez84b5c002016-08-25 16:30:58 -04001700 session1->not_resumable = 0;
1701
Steven Valdez87eab492016-06-27 16:34:59 -04001702 uint8_t *s0_bytes, *s1_bytes;
1703 size_t s0_len, s1_len;
1704
David Benjaminf0d8e222017-02-04 10:58:26 -05001705 ASSERT_TRUE(SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001706 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001707
David Benjaminf0d8e222017-02-04 10:58:26 -05001708 ASSERT_TRUE(SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001709 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001710
David Benjamin7d7554b2017-02-04 11:48:59 -05001711 EXPECT_EQ(Bytes(s0_bytes, s0_len), Bytes(s1_bytes, s1_len));
Steven Valdez87eab492016-06-27 16:34:59 -04001712}
David Benjamin686bb192016-05-10 15:15:41 -04001713
David Benjaminf0d8e222017-02-04 10:58:26 -05001714static void ExpectFDs(const SSL *ssl, int rfd, int wfd) {
David Benjaminca743582017-06-15 17:51:35 -04001715 EXPECT_EQ(rfd, SSL_get_fd(ssl));
David Benjaminf0d8e222017-02-04 10:58:26 -05001716 EXPECT_EQ(rfd, SSL_get_rfd(ssl));
1717 EXPECT_EQ(wfd, SSL_get_wfd(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04001718
1719 // The wrapper BIOs are always equal when fds are equal, even if set
1720 // individually.
David Benjaminf0d8e222017-02-04 10:58:26 -05001721 if (rfd == wfd) {
1722 EXPECT_EQ(SSL_get_rbio(ssl), SSL_get_wbio(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04001723 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001724}
1725
David Benjaminf0d8e222017-02-04 10:58:26 -05001726TEST(SSLTest, SetFD) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001727 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001728 ASSERT_TRUE(ctx);
David Benjamin5c0fb882016-06-14 14:03:51 -04001729
1730 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001731 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001732 ASSERT_TRUE(ssl);
1733 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1734 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
1735 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04001736
1737 // Test setting the same FD.
1738 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001739 ASSERT_TRUE(ssl);
1740 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1741 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001742
1743 // Test setting the same FD one side at a time.
1744 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001745 ASSERT_TRUE(ssl);
1746 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1747 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1748 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001749
1750 // Test setting the same FD in the other order.
1751 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001752 ASSERT_TRUE(ssl);
1753 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1754 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1755 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001756
David Benjamin5c0fb882016-06-14 14:03:51 -04001757 // Test changing the read FD partway through.
1758 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001759 ASSERT_TRUE(ssl);
1760 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1761 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 2));
1762 ExpectFDs(ssl.get(), 2, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001763
1764 // Test changing the write FD partway through.
1765 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001766 ASSERT_TRUE(ssl);
1767 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1768 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
1769 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04001770
1771 // Test a no-op change to the read FD partway through.
1772 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001773 ASSERT_TRUE(ssl);
1774 EXPECT_TRUE(SSL_set_fd(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
1778 // Test a no-op change to the write 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_wfd(ssl.get(), 1));
1783 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001784
1785 // ASan builds will implicitly test that the internal |BIO| reference-counting
1786 // is correct.
David Benjamin5c0fb882016-06-14 14:03:51 -04001787}
1788
David Benjaminf0d8e222017-02-04 10:58:26 -05001789TEST(SSLTest, SetBIO) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001790 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001791 ASSERT_TRUE(ctx);
David Benjamin4501bd52016-08-01 13:39:41 -04001792
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001793 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1794 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04001795 bio3(BIO_new(BIO_s_mem()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001796 ASSERT_TRUE(ssl);
1797 ASSERT_TRUE(bio1);
1798 ASSERT_TRUE(bio2);
1799 ASSERT_TRUE(bio3);
David Benjamin4501bd52016-08-01 13:39:41 -04001800
1801 // SSL_set_bio takes one reference when the parameters are the same.
1802 BIO_up_ref(bio1.get());
1803 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1804
1805 // Repeating the call does nothing.
1806 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1807
1808 // It takes one reference each when the parameters are different.
1809 BIO_up_ref(bio2.get());
1810 BIO_up_ref(bio3.get());
1811 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1812
1813 // Repeating the call does nothing.
1814 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1815
1816 // It takes one reference when changing only wbio.
1817 BIO_up_ref(bio1.get());
1818 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1819
1820 // It takes one reference when changing only rbio and the two are different.
1821 BIO_up_ref(bio3.get());
1822 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1823
1824 // If setting wbio to rbio, it takes no additional references.
1825 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1826
1827 // From there, wbio may be switched to something else.
1828 BIO_up_ref(bio1.get());
1829 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1830
1831 // If setting rbio to wbio, it takes no additional references.
1832 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1833
1834 // From there, rbio may be switched to something else, but, for historical
1835 // reasons, it takes a reference to both parameters.
1836 BIO_up_ref(bio1.get());
1837 BIO_up_ref(bio2.get());
1838 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1839
1840 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1841 // is correct.
David Benjamin4501bd52016-08-01 13:39:41 -04001842}
1843
David Benjamin25490f22016-07-14 00:22:54 -04001844static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1845
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001846TEST_P(SSLVersionTest, GetPeerCertificate) {
1847 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04001848
David Benjamin0fef3052016-11-18 15:11:10 +09001849 // Configure both client and server to accept any certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001850 SSL_CTX_set_verify(client_ctx_.get(),
1851 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1852 nullptr);
1853 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
1854 SSL_CTX_set_verify(server_ctx_.get(),
1855 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1856 nullptr);
1857 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjaminadd5e522016-07-14 00:33:24 -04001858
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001859 ASSERT_TRUE(Connect());
David Benjaminadd5e522016-07-14 00:33:24 -04001860
David Benjamin0fef3052016-11-18 15:11:10 +09001861 // Client and server should both see the leaf certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001862 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1863 ASSERT_TRUE(peer);
1864 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04001865
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001866 peer.reset(SSL_get_peer_certificate(client_.get()));
1867 ASSERT_TRUE(peer);
1868 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04001869
David Benjamine664a532017-07-20 20:19:36 -04001870 // However, for historical reasons, the X509 chain includes the leaf on the
David Benjamin0fef3052016-11-18 15:11:10 +09001871 // client, but does not on the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001872 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(client_.get())), 1u);
1873 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(client_.get())),
1874 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04001875
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001876 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(server_.get())), 0u);
1877 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(server_.get())),
1878 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04001879}
1880
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001881TEST_P(SSLVersionTest, NoPeerCertificate) {
1882 SSL_CTX_set_verify(server_ctx_.get(), SSL_VERIFY_PEER, nullptr);
1883 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
1884 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
David Benjamine664a532017-07-20 20:19:36 -04001885
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001886 ASSERT_TRUE(Connect());
David Benjamine664a532017-07-20 20:19:36 -04001887
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001888 // Server should not see a peer certificate.
1889 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1890 ASSERT_FALSE(peer);
1891 ASSERT_FALSE(SSL_get0_peer_certificates(server_.get()));
David Benjamine664a532017-07-20 20:19:36 -04001892}
1893
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001894TEST_P(SSLVersionTest, RetainOnlySHA256OfCerts) {
David Benjamin25490f22016-07-14 00:22:54 -04001895 uint8_t *cert_der = NULL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001896 int cert_der_len = i2d_X509(cert_.get(), &cert_der);
1897 ASSERT_GE(cert_der_len, 0);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001898 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04001899
1900 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1901 SHA256(cert_der, cert_der_len, cert_sha256);
1902
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001903 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
1904
David Benjamin0fef3052016-11-18 15:11:10 +09001905 // Configure both client and server to accept any certificate, but the
1906 // server must retain only the SHA-256 of the peer.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001907 SSL_CTX_set_verify(client_ctx_.get(),
1908 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1909 nullptr);
1910 SSL_CTX_set_verify(server_ctx_.get(),
1911 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1912 nullptr);
1913 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
1914 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
1915 SSL_CTX_set_retain_only_sha256_of_client_certs(server_ctx_.get(), 1);
David Benjamin25490f22016-07-14 00:22:54 -04001916
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001917 ASSERT_TRUE(Connect());
David Benjamin25490f22016-07-14 00:22:54 -04001918
David Benjamin0fef3052016-11-18 15:11:10 +09001919 // The peer certificate has been dropped.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001920 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1921 EXPECT_FALSE(peer);
David Benjamin25490f22016-07-14 00:22:54 -04001922
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001923 SSL_SESSION *session = SSL_get_session(server_.get());
1924 EXPECT_TRUE(session->peer_sha256_valid);
David Benjamin25490f22016-07-14 00:22:54 -04001925
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001926 EXPECT_EQ(Bytes(cert_sha256), Bytes(session->peer_sha256));
David Benjamin25490f22016-07-14 00:22:54 -04001927}
1928
David Benjaminafc64de2016-07-19 17:12:41 +02001929static bool ClientHelloMatches(uint16_t version, const uint8_t *expected,
1930 size_t expected_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001931 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001932 // Our default cipher list varies by CPU capabilities, so manually place the
1933 // ChaCha20 ciphers in front.
Matthew Braithwaite7e06de52017-04-10 15:52:14 -07001934 const char* cipher_list = "CHACHA20:ALL";
David Benjamin2dc02042016-09-19 19:57:37 -04001935 if (!ctx ||
David Benjamin3cfeb952017-03-01 16:48:38 -05001936 // SSLv3 is off by default.
1937 !SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION) ||
David Benjamine4706902016-09-20 15:12:23 -04001938 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001939 !SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list)) {
David Benjaminafc64de2016-07-19 17:12:41 +02001940 return false;
1941 }
David Benjamin2dc02042016-09-19 19:57:37 -04001942
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001943 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +02001944 if (!ssl) {
1945 return false;
1946 }
1947 std::vector<uint8_t> client_hello;
1948 if (!GetClientHello(ssl.get(), &client_hello)) {
1949 return false;
1950 }
1951
1952 // Zero the client_random.
1953 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
1954 1 + 3 + // handshake message header
1955 2; // client_version
1956 if (client_hello.size() < kRandomOffset + SSL3_RANDOM_SIZE) {
1957 fprintf(stderr, "ClientHello for version %04x too short.\n", version);
1958 return false;
1959 }
David Benjamin17cf2cb2016-12-13 01:07:13 -05001960 OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
David Benjaminafc64de2016-07-19 17:12:41 +02001961
1962 if (client_hello.size() != expected_len ||
David Benjamin17cf2cb2016-12-13 01:07:13 -05001963 OPENSSL_memcmp(client_hello.data(), expected, expected_len) != 0) {
David Benjaminafc64de2016-07-19 17:12:41 +02001964 fprintf(stderr, "ClientHello for version %04x did not match:\n", version);
1965 fprintf(stderr, "Got:\n\t");
1966 for (size_t i = 0; i < client_hello.size(); i++) {
1967 fprintf(stderr, "0x%02x, ", client_hello[i]);
1968 }
1969 fprintf(stderr, "\nWanted:\n\t");
1970 for (size_t i = 0; i < expected_len; i++) {
1971 fprintf(stderr, "0x%02x, ", expected[i]);
1972 }
1973 fprintf(stderr, "\n");
1974 return false;
1975 }
1976
1977 return true;
1978}
1979
1980// Tests that our ClientHellos do not change unexpectedly.
1981static bool TestClientHello() {
1982 static const uint8_t kSSL3ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001983 0x16,
1984 0x03, 0x00,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001985 0x00, 0x3b,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001986 0x01,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001987 0x00, 0x00, 0x37,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001988 0x03, 0x00,
1989 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1990 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1991 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1992 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1993 0x00,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001994 0x00, 0x10,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001995 0xc0, 0x09,
1996 0xc0, 0x13,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001997 0xc0, 0x0a,
1998 0xc0, 0x14,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001999 0x00, 0x2f,
2000 0x00, 0x35,
2001 0x00, 0x0a,
2002 0x00, 0xff, 0x01, 0x00,
David Benjaminafc64de2016-07-19 17:12:41 +02002003 };
2004 if (!ClientHelloMatches(SSL3_VERSION, kSSL3ClientHello,
2005 sizeof(kSSL3ClientHello))) {
2006 return false;
2007 }
2008
2009 static const uint8_t kTLS1ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002010 0x16,
2011 0x03, 0x01,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07002012 0x00, 0x5a,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002013 0x01,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07002014 0x00, 0x00, 0x56,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002015 0x03, 0x01,
2016 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2017 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2018 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2019 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2020 0x00,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07002021 0x00, 0x0e,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002022 0xc0, 0x09,
2023 0xc0, 0x13,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002024 0xc0, 0x0a,
2025 0xc0, 0x14,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002026 0x00, 0x2f,
2027 0x00, 0x35,
2028 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02002029 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
2030 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
2031 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
2032 };
2033 if (!ClientHelloMatches(TLS1_VERSION, kTLS1ClientHello,
2034 sizeof(kTLS1ClientHello))) {
2035 return false;
2036 }
2037
2038 static const uint8_t kTLS11ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002039 0x16,
2040 0x03, 0x01,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07002041 0x00, 0x5a,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002042 0x01,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07002043 0x00, 0x00, 0x56,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002044 0x03, 0x02,
2045 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2046 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2047 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2048 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2049 0x00,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07002050 0x00, 0x0e,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002051 0xc0, 0x09,
2052 0xc0, 0x13,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002053 0xc0, 0x0a,
2054 0xc0, 0x14,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002055 0x00, 0x2f,
2056 0x00, 0x35,
2057 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02002058 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
2059 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
2060 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
2061 };
2062 if (!ClientHelloMatches(TLS1_1_VERSION, kTLS11ClientHello,
2063 sizeof(kTLS11ClientHello))) {
2064 return false;
2065 }
2066
David Benjamin3b584332017-01-24 22:47:18 -05002067 // kTLS12ClientHello assumes RSA-PSS, which is disabled for Android system
2068 // builds.
2069#if defined(BORINGSSL_ANDROID_SYSTEM)
2070 return true;
2071#endif
2072
David Benjaminafc64de2016-07-19 17:12:41 +02002073 static const uint8_t kTLS12ClientHello[] = {
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07002074 0x16,
2075 0x03, 0x01,
2076 0x00, 0x8e,
2077 0x01,
2078 0x00, 0x00, 0x8a,
2079 0x03, 0x03,
David Benjamin57e929f2016-08-30 00:30:38 -04002080 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2081 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07002082 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2083 0x00, 0x2a,
2084 0xcc, 0xa9,
2085 0xcc, 0xa8,
2086 0xc0, 0x2b,
2087 0xc0, 0x2f,
2088 0xc0, 0x2c,
2089 0xc0, 0x30,
2090 0xc0, 0x09,
2091 0xc0, 0x23,
2092 0xc0, 0x13,
2093 0xc0, 0x27,
2094 0xc0, 0x0a,
2095 0xc0, 0x24,
2096 0xc0, 0x14,
2097 0xc0, 0x28,
2098 0x00, 0x9c,
2099 0x00, 0x9d,
2100 0x00, 0x2f,
2101 0x00, 0x3c,
2102 0x00, 0x35,
2103 0x00, 0x3d,
2104 0x00, 0x0a,
2105 0x01, 0x00, 0x00, 0x37, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
2106 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04,
2107 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08,
2108 0x06, 0x06, 0x01, 0x02, 0x01, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
2109 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
David Benjaminafc64de2016-07-19 17:12:41 +02002110 };
2111 if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
2112 sizeof(kTLS12ClientHello))) {
2113 return false;
2114 }
2115
2116 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
2117 // implementation has settled enough that it won't change.
2118
2119 return true;
2120}
2121
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002122static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04002123
2124static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
2125 // Save the most recent session.
2126 g_last_session.reset(session);
2127 return 1;
2128}
2129
David Benjamina8614602017-09-06 15:40:19 -04002130static bssl::UniquePtr<SSL_SESSION> CreateClientSession(
2131 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2132 const ClientConfig &config = ClientConfig()) {
David Benjamina20e5352016-08-02 19:09:41 -04002133 g_last_session = nullptr;
2134 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2135
2136 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002137 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04002138 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
David Benjamina8614602017-09-06 15:40:19 -04002139 config)) {
David Benjamina20e5352016-08-02 19:09:41 -04002140 fprintf(stderr, "Failed to connect client and server.\n");
2141 return nullptr;
2142 }
2143
2144 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2145 SSL_read(client.get(), nullptr, 0);
2146
2147 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2148
2149 if (!g_last_session) {
2150 fprintf(stderr, "Client did not receive a session.\n");
2151 return nullptr;
2152 }
2153 return std::move(g_last_session);
2154}
2155
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002156static void ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2157 SSL_SESSION *session, bool want_reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002158 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002159 ClientConfig config;
2160 config.session = session;
2161 EXPECT_TRUE(
2162 ConnectClientAndServer(&client, &server, client_ctx, server_ctx, config));
David Benjamina20e5352016-08-02 19:09:41 -04002163
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002164 EXPECT_EQ(SSL_session_reused(client.get()), SSL_session_reused(server.get()));
David Benjamina20e5352016-08-02 19:09:41 -04002165
2166 bool was_reused = !!SSL_session_reused(client.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002167 EXPECT_EQ(was_reused, want_reused);
David Benjamina20e5352016-08-02 19:09:41 -04002168}
2169
David Benjamin3c51d9b2016-11-01 17:50:42 -04002170static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
2171 SSL_CTX *server_ctx,
2172 SSL_SESSION *session) {
2173 g_last_session = nullptr;
2174 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2175
2176 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002177 ClientConfig config;
2178 config.session = session;
2179 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
2180 config)) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002181 fprintf(stderr, "Failed to connect client and server.\n");
2182 return nullptr;
2183 }
2184
2185 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2186 fprintf(stderr, "Client and server were inconsistent.\n");
2187 return nullptr;
2188 }
2189
2190 if (!SSL_session_reused(client.get())) {
2191 fprintf(stderr, "Session was not reused.\n");
2192 return nullptr;
2193 }
2194
2195 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2196 SSL_read(client.get(), nullptr, 0);
2197
2198 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2199
2200 if (!g_last_session) {
2201 fprintf(stderr, "Client did not receive a renewed session.\n");
2202 return nullptr;
2203 }
2204 return std::move(g_last_session);
2205}
2206
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002207static void ExpectTicketKeyChanged(SSL_CTX *ctx, uint8_t *inout_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002208 bool changed) {
2209 uint8_t new_key[kTicketKeyLen];
David Benjaminc11ea9422017-08-29 16:33:21 -04002210 // May return 0, 1 or 48.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002211 ASSERT_EQ(SSL_CTX_get_tlsext_ticket_keys(ctx, new_key, kTicketKeyLen), 1);
2212 if (changed) {
2213 ASSERT_NE(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
2214 } else {
2215 ASSERT_EQ(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002216 }
2217 OPENSSL_memcpy(inout_key, new_key, kTicketKeyLen);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002218}
2219
David Benjamina933c382016-10-28 00:10:03 -04002220static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
2221 static const uint8_t kContext[] = {3};
2222
2223 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
2224 return SSL_TLSEXT_ERR_ALERT_FATAL;
2225 }
2226
2227 return SSL_TLSEXT_ERR_OK;
2228}
2229
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002230TEST_P(SSLVersionTest, SessionIDContext) {
David Benjamina20e5352016-08-02 19:09:41 -04002231 static const uint8_t kContext1[] = {1};
2232 static const uint8_t kContext2[] = {2};
2233
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002234 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2235 sizeof(kContext1)));
David Benjamina20e5352016-08-02 19:09:41 -04002236
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002237 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2238 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002239
David Benjamin0fef3052016-11-18 15:11:10 +09002240 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002241 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2242 ASSERT_TRUE(session);
David Benjamina20e5352016-08-02 19:09:41 -04002243
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002244 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2245 session.get(),
2246 true /* expect session reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002247
David Benjamin0fef3052016-11-18 15:11:10 +09002248 // Change the session ID context.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002249 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext2,
2250 sizeof(kContext2)));
David Benjamina20e5352016-08-02 19:09:41 -04002251
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002252 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2253 session.get(),
2254 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002255
David Benjamin0fef3052016-11-18 15:11:10 +09002256 // Change the session ID context back and install an SNI callback to switch
2257 // it.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002258 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2259 sizeof(kContext1)));
David Benjamina933c382016-10-28 00:10:03 -04002260
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002261 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09002262 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04002263
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002264 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2265 session.get(),
2266 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002267
David Benjamin0fef3052016-11-18 15:11:10 +09002268 // Switch the session ID context with the early callback instead.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002269 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), nullptr);
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002270 SSL_CTX_set_select_certificate_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002271 server_ctx_.get(),
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002272 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
2273 static const uint8_t kContext[] = {3};
2274
2275 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
2276 sizeof(kContext))) {
2277 return ssl_select_cert_error;
2278 }
2279
2280 return ssl_select_cert_success;
2281 });
David Benjamina933c382016-10-28 00:10:03 -04002282
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002283 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2284 session.get(),
2285 false /* expect session not reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002286}
2287
David Benjamin721e8b72016-08-03 13:13:17 -04002288static timeval g_current_time;
2289
2290static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2291 *out_clock = g_current_time;
2292}
2293
David Benjamin17b30832017-01-28 14:00:32 -05002294static void FrozenTimeCallback(const SSL *ssl, timeval *out_clock) {
2295 out_clock->tv_sec = 1000;
2296 out_clock->tv_usec = 0;
2297}
2298
David Benjamin3c51d9b2016-11-01 17:50:42 -04002299static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
2300 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
2301 int encrypt) {
2302 static const uint8_t kZeros[16] = {0};
2303
2304 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -05002305 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamin3c51d9b2016-11-01 17:50:42 -04002306 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -05002307 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002308 return 0;
2309 }
2310
2311 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
2312 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
2313 return -1;
2314 }
2315
2316 // Returning two from the callback in decrypt mode renews the
2317 // session in TLS 1.2 and below.
2318 return encrypt ? 1 : 2;
2319}
2320
David Benjamin123db572016-11-03 16:59:25 -04002321static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjamin123db572016-11-03 16:59:25 -04002322 if (session->tlsext_ticklen < 16 + 16 + SHA256_DIGEST_LENGTH) {
2323 return false;
2324 }
2325
David Benjamin123db572016-11-03 16:59:25 -04002326 const uint8_t *ciphertext = session->tlsext_tick + 16 + 16;
2327 size_t len = session->tlsext_ticklen - 16 - 16 - SHA256_DIGEST_LENGTH;
2328 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
2329
David Benjamin9b63f292016-11-15 00:44:05 -05002330#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
2331 // Fuzzer-mode tickets are unencrypted.
David Benjamin17cf2cb2016-12-13 01:07:13 -05002332 OPENSSL_memcpy(plaintext.get(), ciphertext, len);
David Benjamin9b63f292016-11-15 00:44:05 -05002333#else
2334 static const uint8_t kZeros[16] = {0};
2335 const uint8_t *iv = session->tlsext_tick + 16;
David Benjamin123db572016-11-03 16:59:25 -04002336 bssl::ScopedEVP_CIPHER_CTX ctx;
2337 int len1, len2;
2338 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
2339 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
2340 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
2341 return false;
2342 }
2343
2344 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05002345#endif
David Benjamin123db572016-11-03 16:59:25 -04002346
Adam Langley46db7af2017-02-01 15:49:37 -08002347 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
2348 if (!ssl_ctx) {
2349 return false;
2350 }
David Benjamin123db572016-11-03 16:59:25 -04002351 bssl::UniquePtr<SSL_SESSION> server_session(
Adam Langley46db7af2017-02-01 15:49:37 -08002352 SSL_SESSION_from_bytes(plaintext.get(), len, ssl_ctx.get()));
David Benjamin123db572016-11-03 16:59:25 -04002353 if (!server_session) {
2354 return false;
2355 }
2356
2357 *out = server_session->time;
2358 return true;
2359}
2360
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002361TEST_P(SSLVersionTest, SessionTimeout) {
2362 for (bool server_test : {false, true}) {
2363 SCOPED_TRACE(server_test);
David Benjamin721e8b72016-08-03 13:13:17 -04002364
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002365 ResetContexts();
2366 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2367 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
2368
David Benjamin17b30832017-01-28 14:00:32 -05002369 static const time_t kStartTime = 1000;
David Benjamin0fef3052016-11-18 15:11:10 +09002370 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002371
David Benjamin17b30832017-01-28 14:00:32 -05002372 // We are willing to use a longer lifetime for TLS 1.3 sessions as
2373 // resumptions still perform ECDHE.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002374 const time_t timeout = version() == TLS1_3_VERSION
David Benjamin17b30832017-01-28 14:00:32 -05002375 ? SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT
2376 : SSL_DEFAULT_SESSION_TIMEOUT;
2377
David Benjamin17b30832017-01-28 14:00:32 -05002378 // Both client and server must enforce session timeouts. We configure the
2379 // other side with a frozen clock so it never expires tickets.
David Benjamin0fef3052016-11-18 15:11:10 +09002380 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002381 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2382 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002383 } else {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002384 SSL_CTX_set_current_time_cb(client_ctx_.get(), CurrentTimeCallback);
2385 SSL_CTX_set_current_time_cb(server_ctx_.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002386 }
2387
2388 // Configure a ticket callback which renews tickets.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002389 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002390
2391 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002392 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2393 ASSERT_TRUE(session);
David Benjamin0fef3052016-11-18 15:11:10 +09002394
2395 // Advance the clock just behind the timeout.
David Benjamin17b30832017-01-28 14:00:32 -05002396 g_current_time.tv_sec += timeout - 1;
David Benjamin0fef3052016-11-18 15:11:10 +09002397
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002398 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2399 session.get(),
2400 true /* expect session reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002401
2402 // Advance the clock one more second.
2403 g_current_time.tv_sec++;
2404
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002405 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2406 session.get(),
2407 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002408
2409 // Rewind the clock to before the session was minted.
2410 g_current_time.tv_sec = kStartTime - 1;
2411
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002412 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2413 session.get(),
2414 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002415
2416 // SSL 3.0 cannot renew sessions.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002417 if (version() == SSL3_VERSION) {
David Benjamin0fef3052016-11-18 15:11:10 +09002418 continue;
2419 }
2420
2421 // Renew the session 10 seconds before expiration.
David Benjamin17b30832017-01-28 14:00:32 -05002422 time_t new_start_time = kStartTime + timeout - 10;
2423 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002424 bssl::UniquePtr<SSL_SESSION> new_session = ExpectSessionRenewed(
2425 client_ctx_.get(), server_ctx_.get(), session.get());
2426 ASSERT_TRUE(new_session);
David Benjamin0fef3052016-11-18 15:11:10 +09002427
2428 // This new session is not the same object as before.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002429 EXPECT_NE(session.get(), new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002430
2431 // Check the sessions have timestamps measured from issuance.
2432 long session_time = 0;
2433 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002434 ASSERT_TRUE(GetServerTicketTime(&session_time, new_session.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09002435 } else {
2436 session_time = new_session->time;
2437 }
David Benjamin721e8b72016-08-03 13:13:17 -04002438
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002439 ASSERT_EQ(session_time, g_current_time.tv_sec);
David Benjamin721e8b72016-08-03 13:13:17 -04002440
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002441 if (version() == TLS1_3_VERSION) {
David Benjamin17b30832017-01-28 14:00:32 -05002442 // Renewal incorporates fresh key material in TLS 1.3, so we extend the
2443 // lifetime TLS 1.3.
2444 g_current_time.tv_sec = new_start_time + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002445 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2446 new_session.get(),
2447 true /* expect session reused */));
David Benjamin721e8b72016-08-03 13:13:17 -04002448
David Benjamin17b30832017-01-28 14:00:32 -05002449 // The new session expires after the new timeout.
2450 g_current_time.tv_sec = new_start_time + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002451 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2452 new_session.get(),
2453 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002454
2455 // Renew the session until it begins just past the auth timeout.
2456 time_t auth_end_time = kStartTime + SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
2457 while (new_start_time < auth_end_time - 1000) {
2458 // Get as close as possible to target start time.
2459 new_start_time =
2460 std::min(auth_end_time - 1000, new_start_time + timeout - 1);
2461 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002462 new_session = ExpectSessionRenewed(client_ctx_.get(), server_ctx_.get(),
David Benjamin17b30832017-01-28 14:00:32 -05002463 new_session.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002464 ASSERT_TRUE(new_session);
David Benjamin17b30832017-01-28 14:00:32 -05002465 }
2466
2467 // Now the session's lifetime is bound by the auth timeout.
2468 g_current_time.tv_sec = auth_end_time - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002469 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2470 new_session.get(),
2471 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002472
2473 g_current_time.tv_sec = auth_end_time + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002474 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2475 new_session.get(),
2476 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002477 } else {
2478 // The new session is usable just before the old expiration.
2479 g_current_time.tv_sec = kStartTime + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002480 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2481 new_session.get(),
2482 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002483
2484 // Renewal does not extend the lifetime, so it is not usable beyond the
2485 // old expiration.
2486 g_current_time.tv_sec = kStartTime + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002487 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2488 new_session.get(),
2489 false /* expect session not reused */));
David Benjamin1b22f852016-10-27 16:36:32 -04002490 }
David Benjamin721e8b72016-08-03 13:13:17 -04002491 }
David Benjamin721e8b72016-08-03 13:13:17 -04002492}
2493
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002494TEST_P(SSLVersionTest, DefaultTicketKeyInitialization) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002495 static const uint8_t kZeroKey[kTicketKeyLen] = {};
2496 uint8_t ticket_key[kTicketKeyLen];
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002497 ASSERT_EQ(1, SSL_CTX_get_tlsext_ticket_keys(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002498 kTicketKeyLen));
2499 ASSERT_NE(0, OPENSSL_memcmp(ticket_key, kZeroKey, kTicketKeyLen));
2500}
2501
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002502TEST_P(SSLVersionTest, DefaultTicketKeyRotation) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002503 if (GetParam().version == SSL3_VERSION) {
2504 return;
2505 }
2506
2507 static const time_t kStartTime = 1001;
2508 g_current_time.tv_sec = kStartTime;
2509 uint8_t ticket_key[kTicketKeyLen];
2510
David Benjaminc11ea9422017-08-29 16:33:21 -04002511 // We use session reuse as a proxy for ticket decryption success, hence
2512 // disable session timeouts.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002513 SSL_CTX_set_timeout(server_ctx_.get(), std::numeric_limits<uint32_t>::max());
2514 SSL_CTX_set_session_psk_dhe_timeout(server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002515 std::numeric_limits<uint32_t>::max());
2516
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002517 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2518 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002519
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002520 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2521 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_OFF);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002522
David Benjaminc11ea9422017-08-29 16:33:21 -04002523 // Initialize ticket_key with the current key.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002524 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2525 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002526
David Benjaminc11ea9422017-08-29 16:33:21 -04002527 // Verify ticket resumption actually works.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002528 bssl::UniquePtr<SSL> client, server;
2529 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002530 CreateClientSession(client_ctx_.get(), server_ctx_.get());
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002531 ASSERT_TRUE(session);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002532 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002533 session.get(), true /* reused */));
2534
David Benjaminc11ea9422017-08-29 16:33:21 -04002535 // Advance time to just before key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002536 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002537 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002538 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002539 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002540 false /* NOT changed */));
2541
David Benjaminc11ea9422017-08-29 16:33:21 -04002542 // Force key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002543 g_current_time.tv_sec += 1;
2544 bssl::UniquePtr<SSL_SESSION> new_session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002545 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2546 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2547 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002548
David Benjaminc11ea9422017-08-29 16:33:21 -04002549 // Resumption with both old and new ticket should work.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002550 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002551 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002552 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002553 new_session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002554 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002555 false /* NOT changed */));
2556
David Benjaminc11ea9422017-08-29 16:33:21 -04002557 // Force key rotation again. Resumption with the old ticket now fails.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002558 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002559 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002560 session.get(), false /* NOT reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002561 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2562 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002563
David Benjaminc11ea9422017-08-29 16:33:21 -04002564 // But resumption with the newer session still works.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002565 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002566 new_session.get(), true /* reused */));
2567}
2568
David Benjamin0fc37ef2016-08-17 15:29:46 -04002569static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002570 SSL_CTX *ctx = reinterpret_cast<SSL_CTX *>(arg);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002571 SSL_set_SSL_CTX(ssl, ctx);
2572 return SSL_TLSEXT_ERR_OK;
2573}
2574
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002575TEST_P(SSLVersionTest, SNICallback) {
David Benjamin0fef3052016-11-18 15:11:10 +09002576 // SSL 3.0 lacks extensions.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002577 if (version() == SSL3_VERSION) {
2578 return;
David Benjamin0fef3052016-11-18 15:11:10 +09002579 }
2580
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002581 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002582 ASSERT_TRUE(cert2);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002583 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002584 ASSERT_TRUE(key2);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002585
David Benjamin0fef3052016-11-18 15:11:10 +09002586 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
2587 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002588
David Benjamin83a32122017-02-14 18:34:54 -05002589 static const uint8_t kSCTList[] = {0, 6, 0, 4, 5, 6, 7, 8};
2590 static const uint8_t kOCSPResponse[] = {1, 2, 3, 4};
2591
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002592 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
2593 ASSERT_TRUE(server_ctx2);
2594 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()));
2595 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()));
2596 ASSERT_TRUE(SSL_CTX_set_signed_cert_timestamp_list(
2597 server_ctx2.get(), kSCTList, sizeof(kSCTList)));
2598 ASSERT_TRUE(SSL_CTX_set_ocsp_response(server_ctx2.get(), kOCSPResponse,
2599 sizeof(kOCSPResponse)));
2600 // Historically signing preferences would be lost in some cases with the
2601 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2602 // this doesn't happen when |version| is TLS 1.2, configure the private
2603 // key to only sign SHA-256.
2604 ASSERT_TRUE(SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
2605 &kECDSAWithSHA256, 1));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002606
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002607 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), SwitchContext);
2608 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002609
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002610 SSL_CTX_enable_signed_cert_timestamps(client_ctx_.get());
2611 SSL_CTX_enable_ocsp_stapling(client_ctx_.get());
David Benjamin83a32122017-02-14 18:34:54 -05002612
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002613 ASSERT_TRUE(Connect());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002614
David Benjamin0fef3052016-11-18 15:11:10 +09002615 // The client should have received |cert2|.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002616 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client_.get()));
2617 ASSERT_TRUE(peer);
2618 EXPECT_EQ(X509_cmp(peer.get(), cert2.get()), 0);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002619
David Benjamin83a32122017-02-14 18:34:54 -05002620 // The client should have received |server_ctx2|'s SCT list.
2621 const uint8_t *data;
2622 size_t len;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002623 SSL_get0_signed_cert_timestamp_list(client_.get(), &data, &len);
2624 EXPECT_EQ(Bytes(kSCTList), Bytes(data, len));
David Benjamin83a32122017-02-14 18:34:54 -05002625
2626 // The client should have received |server_ctx2|'s OCSP response.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002627 SSL_get0_ocsp_response(client_.get(), &data, &len);
2628 EXPECT_EQ(Bytes(kOCSPResponse), Bytes(data, len));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002629}
2630
David Benjaminf0d8e222017-02-04 10:58:26 -05002631// Test that the early callback can swap the maximum version.
2632TEST(SSLTest, EarlyCallbackVersionSwitch) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002633 bssl::UniquePtr<X509> cert = GetTestCertificate();
2634 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2635 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2636 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002637 ASSERT_TRUE(cert);
2638 ASSERT_TRUE(key);
2639 ASSERT_TRUE(server_ctx);
2640 ASSERT_TRUE(client_ctx);
2641 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
2642 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
2643 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
2644 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
David Benjamin99620572016-08-30 00:35:36 -04002645
David Benjaminf0d8e222017-02-04 10:58:26 -05002646 SSL_CTX_set_select_certificate_cb(
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002647 server_ctx.get(),
2648 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
David Benjaminf0d8e222017-02-04 10:58:26 -05002649 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002650 return ssl_select_cert_error;
David Benjaminf0d8e222017-02-04 10:58:26 -05002651 }
2652
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002653 return ssl_select_cert_success;
David Benjaminf0d8e222017-02-04 10:58:26 -05002654 });
David Benjamin99620572016-08-30 00:35:36 -04002655
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002656 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05002657 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04002658 server_ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002659 EXPECT_EQ(TLS1_2_VERSION, SSL_version(client.get()));
David Benjamin99620572016-08-30 00:35:36 -04002660}
2661
David Benjaminf0d8e222017-02-04 10:58:26 -05002662TEST(SSLTest, SetVersion) {
David Benjamin2dc02042016-09-19 19:57:37 -04002663 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002664 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002665
David Benjaminf0d8e222017-02-04 10:58:26 -05002666 // Set valid TLS versions.
2667 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2668 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
2669 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2670 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002671
David Benjaminf0d8e222017-02-04 10:58:26 -05002672 // Invalid TLS versions are rejected.
2673 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2674 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x0200));
2675 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2676 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2677 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x0200));
2678 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002679
David Benjaminf0d8e222017-02-04 10:58:26 -05002680 // Zero is the default version.
2681 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002682 EXPECT_EQ(TLS1_2_VERSION, ctx->conf_max_version);
David Benjaminf0d8e222017-02-04 10:58:26 -05002683 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002684 EXPECT_EQ(TLS1_VERSION, ctx->conf_min_version);
David Benjamin3cfeb952017-03-01 16:48:38 -05002685
2686 // SSL 3.0 and TLS 1.3 are available, but not by default.
2687 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002688 EXPECT_EQ(SSL3_VERSION, ctx->conf_min_version);
David Benjamin3cfeb952017-03-01 16:48:38 -05002689 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002690 EXPECT_EQ(TLS1_3_VERSION, ctx->conf_max_version);
David Benjamine34bcc92016-09-21 16:53:09 -04002691
David Benjamin353577c2017-06-29 15:54:58 -04002692 // TLS1_3_DRAFT_VERSION is not an API-level version.
2693 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_DRAFT_VERSION));
2694 ERR_clear_error();
2695
David Benjamin2dc02042016-09-19 19:57:37 -04002696 ctx.reset(SSL_CTX_new(DTLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002697 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002698
David Benjaminf0d8e222017-02-04 10:58:26 -05002699 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2700 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION));
2701 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2702 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002703
David Benjaminf0d8e222017-02-04 10:58:26 -05002704 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2705 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2706 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2707 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2708 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2709 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2710 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2711 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002712
David Benjaminf0d8e222017-02-04 10:58:26 -05002713 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002714 EXPECT_EQ(TLS1_2_VERSION, ctx->conf_max_version);
David Benjaminf0d8e222017-02-04 10:58:26 -05002715 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002716 EXPECT_EQ(TLS1_1_VERSION, ctx->conf_min_version);
David Benjamin2dc02042016-09-19 19:57:37 -04002717}
2718
David Benjamin458334a2016-12-15 13:53:25 -05002719static const char *GetVersionName(uint16_t version) {
2720 switch (version) {
2721 case SSL3_VERSION:
2722 return "SSLv3";
2723 case TLS1_VERSION:
2724 return "TLSv1";
2725 case TLS1_1_VERSION:
2726 return "TLSv1.1";
2727 case TLS1_2_VERSION:
2728 return "TLSv1.2";
2729 case TLS1_3_VERSION:
2730 return "TLSv1.3";
2731 case DTLS1_VERSION:
2732 return "DTLSv1";
2733 case DTLS1_2_VERSION:
2734 return "DTLSv1.2";
2735 default:
2736 return "???";
2737 }
2738}
2739
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002740TEST_P(SSLVersionTest, Version) {
2741 ASSERT_TRUE(Connect());
David Benjamincb18ac22016-09-27 14:09:15 -04002742
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002743 EXPECT_EQ(SSL_version(client_.get()), version());
2744 EXPECT_EQ(SSL_version(server_.get()), version());
David Benjamincb18ac22016-09-27 14:09:15 -04002745
David Benjamin458334a2016-12-15 13:53:25 -05002746 // Test the version name is reported as expected.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002747 const char *version_name = GetVersionName(version());
2748 EXPECT_EQ(strcmp(version_name, SSL_get_version(client_.get())), 0);
2749 EXPECT_EQ(strcmp(version_name, SSL_get_version(server_.get())), 0);
David Benjamin458334a2016-12-15 13:53:25 -05002750
2751 // Test SSL_SESSION reports the same name.
2752 const char *client_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002753 SSL_SESSION_get_version(SSL_get_session(client_.get()));
David Benjamin458334a2016-12-15 13:53:25 -05002754 const char *server_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002755 SSL_SESSION_get_version(SSL_get_session(server_.get()));
2756 EXPECT_EQ(strcmp(version_name, client_name), 0);
2757 EXPECT_EQ(strcmp(version_name, server_name), 0);
David Benjamincb18ac22016-09-27 14:09:15 -04002758}
2759
David Benjamin9ef31f02016-10-31 18:01:13 -04002760// Tests that that |SSL_get_pending_cipher| is available during the ALPN
2761// selection callback.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002762TEST_P(SSLVersionTest, ALPNCipherAvailable) {
David Benjamin0fef3052016-11-18 15:11:10 +09002763 // SSL 3.0 lacks extensions.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002764 if (version() == SSL3_VERSION) {
2765 return;
David Benjamin0fef3052016-11-18 15:11:10 +09002766 }
2767
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002768 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2769
David Benjamin9ef31f02016-10-31 18:01:13 -04002770 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002771 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
2772 sizeof(kALPNProtos)),
2773 0);
David Benjamin0fef3052016-11-18 15:11:10 +09002774
2775 // The ALPN callback does not fail the handshake on error, so have the
2776 // callback write a boolean.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002777 std::pair<uint16_t, bool> callback_state(version(), false);
David Benjamin0fef3052016-11-18 15:11:10 +09002778 SSL_CTX_set_alpn_select_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002779 server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09002780 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
2781 unsigned in_len, void *arg) -> int {
2782 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
2783 if (SSL_get_pending_cipher(ssl) != nullptr &&
2784 SSL_version(ssl) == state->first) {
2785 state->second = true;
2786 }
2787 return SSL_TLSEXT_ERR_NOACK;
2788 },
2789 &callback_state);
2790
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002791 ASSERT_TRUE(Connect());
David Benjamin0fef3052016-11-18 15:11:10 +09002792
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002793 ASSERT_TRUE(callback_state.second);
David Benjamin0fef3052016-11-18 15:11:10 +09002794}
2795
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002796TEST_P(SSLVersionTest, SSLClearSessionResumption) {
David Benjaminb79cc842016-12-07 15:57:14 -05002797 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
2798 // API pattern.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002799 if (version() == TLS1_3_VERSION) {
2800 return;
David Benjaminb79cc842016-12-07 15:57:14 -05002801 }
2802
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002803 ASSERT_TRUE(Connect());
David Benjaminb79cc842016-12-07 15:57:14 -05002804
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002805 EXPECT_FALSE(SSL_session_reused(client_.get()));
2806 EXPECT_FALSE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002807
2808 // Reset everything.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002809 ASSERT_TRUE(SSL_clear(client_.get()));
2810 ASSERT_TRUE(SSL_clear(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002811
2812 // Attempt to connect a second time.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002813 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002814
2815 // |SSL_clear| should implicitly offer the previous session to the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002816 EXPECT_TRUE(SSL_session_reused(client_.get()));
2817 EXPECT_TRUE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002818}
2819
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002820static bool ChainsEqual(STACK_OF(X509) * chain,
2821 const std::vector<X509 *> &expected) {
David Benjamin1444c3a2016-12-20 17:23:11 -05002822 if (sk_X509_num(chain) != expected.size()) {
2823 return false;
2824 }
2825
2826 for (size_t i = 0; i < expected.size(); i++) {
2827 if (X509_cmp(sk_X509_value(chain, i), expected[i]) != 0) {
2828 return false;
2829 }
2830 }
2831
2832 return true;
2833}
2834
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002835TEST_P(SSLVersionTest, AutoChain) {
2836 cert_ = GetChainTestCertificate();
2837 ASSERT_TRUE(cert_);
2838 key_ = GetChainTestKey();
2839 ASSERT_TRUE(key_);
David Benjamin1444c3a2016-12-20 17:23:11 -05002840 bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002841 ASSERT_TRUE(intermediate);
2842
2843 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2844 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin1444c3a2016-12-20 17:23:11 -05002845
2846 // Configure both client and server to accept any certificate. Add
2847 // |intermediate| to the cert store.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002848 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx_.get()),
2849 intermediate.get()));
2850 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(server_ctx_.get()),
2851 intermediate.get()));
2852 SSL_CTX_set_verify(client_ctx_.get(),
2853 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2854 nullptr);
2855 SSL_CTX_set_verify(server_ctx_.get(),
2856 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2857 nullptr);
2858 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
2859 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjamin1444c3a2016-12-20 17:23:11 -05002860
2861 // By default, the client and server should each only send the leaf.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002862 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002863
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002864 EXPECT_TRUE(
2865 ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()), {cert_.get()}));
2866 EXPECT_TRUE(
2867 ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()), {cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002868
2869 // If auto-chaining is enabled, then the intermediate is sent.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002870 SSL_CTX_clear_mode(client_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
2871 SSL_CTX_clear_mode(server_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
2872 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002873
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002874 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
2875 {cert_.get(), intermediate.get()}));
2876 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
2877 {cert_.get(), intermediate.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002878
2879 // Auto-chaining does not override explicitly-configured intermediates.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002880 ASSERT_TRUE(SSL_CTX_add1_chain_cert(client_ctx_.get(), cert_.get()));
2881 ASSERT_TRUE(SSL_CTX_add1_chain_cert(server_ctx_.get(), cert_.get()));
2882 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002883
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002884 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
2885 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002886
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002887 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
2888 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002889}
2890
David Benjamin48063c22017-01-01 23:56:36 -05002891static bool ExpectBadWriteRetry() {
2892 int err = ERR_get_error();
2893 if (ERR_GET_LIB(err) != ERR_LIB_SSL ||
2894 ERR_GET_REASON(err) != SSL_R_BAD_WRITE_RETRY) {
2895 char buf[ERR_ERROR_STRING_BUF_LEN];
2896 ERR_error_string_n(err, buf, sizeof(buf));
2897 fprintf(stderr, "Wanted SSL_R_BAD_WRITE_RETRY, got: %s.\n", buf);
2898 return false;
2899 }
2900
2901 if (ERR_peek_error() != 0) {
2902 fprintf(stderr, "Unexpected error following SSL_R_BAD_WRITE_RETRY.\n");
2903 return false;
2904 }
2905
2906 return true;
2907}
2908
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002909TEST_P(SSLVersionTest, SSLWriteRetry) {
2910 if (is_dtls()) {
2911 return;
David Benjamin48063c22017-01-01 23:56:36 -05002912 }
2913
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002914 for (bool enable_partial_write : {false, true}) {
2915 SCOPED_TRACE(enable_partial_write);
2916
David Benjamin48063c22017-01-01 23:56:36 -05002917 // Connect a client and server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002918 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2919
2920 ASSERT_TRUE(Connect());
David Benjamin48063c22017-01-01 23:56:36 -05002921
2922 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002923 SSL_set_mode(client_.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002924 }
2925
2926 // Write without reading until the buffer is full and we have an unfinished
2927 // write. Keep a count so we may reread it again later. "hello!" will be
2928 // written in two chunks, "hello" and "!".
2929 char data[] = "hello!";
2930 static const int kChunkLen = 5; // The length of "hello".
2931 unsigned count = 0;
2932 for (;;) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002933 int ret = SSL_write(client_.get(), data, kChunkLen);
David Benjamin48063c22017-01-01 23:56:36 -05002934 if (ret <= 0) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002935 ASSERT_EQ(SSL_get_error(client_.get(), ret), SSL_ERROR_WANT_WRITE);
2936 break;
David Benjamin48063c22017-01-01 23:56:36 -05002937 }
2938
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002939 ASSERT_EQ(ret, 5);
David Benjamin48063c22017-01-01 23:56:36 -05002940
2941 count++;
2942 }
2943
2944 // Retrying with the same parameters is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002945 ASSERT_EQ(
2946 SSL_get_error(client_.get(), SSL_write(client_.get(), data, kChunkLen)),
2947 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002948
2949 // Retrying with the same buffer but shorter length is not legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002950 ASSERT_EQ(SSL_get_error(client_.get(),
2951 SSL_write(client_.get(), data, kChunkLen - 1)),
2952 SSL_ERROR_SSL);
2953 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002954
2955 // Retrying with a different buffer pointer is not legal.
2956 char data2[] = "hello";
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002957 ASSERT_EQ(SSL_get_error(client_.get(),
2958 SSL_write(client_.get(), data2, kChunkLen)),
2959 SSL_ERROR_SSL);
2960 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002961
2962 // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002963 SSL_set_mode(client_.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
2964 ASSERT_EQ(SSL_get_error(client_.get(),
2965 SSL_write(client_.get(), data2, kChunkLen)),
2966 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002967
2968 // |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| does not disable length checks.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002969 ASSERT_EQ(SSL_get_error(client_.get(),
2970 SSL_write(client_.get(), data2, kChunkLen - 1)),
2971 SSL_ERROR_SSL);
2972 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002973
2974 // Retrying with a larger buffer is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002975 ASSERT_EQ(SSL_get_error(client_.get(),
2976 SSL_write(client_.get(), data, kChunkLen + 1)),
2977 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002978
2979 // Drain the buffer.
2980 char buf[20];
2981 for (unsigned i = 0; i < count; i++) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002982 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
2983 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
David Benjamin48063c22017-01-01 23:56:36 -05002984 }
2985
2986 // Now that there is space, a retry with a larger buffer should flush the
2987 // pending record, skip over that many bytes of input (on assumption they
2988 // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE
2989 // is set, this will complete in two steps.
2990 char data3[] = "_____!";
2991 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002992 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen);
2993 ASSERT_EQ(SSL_write(client_.get(), data3 + kChunkLen, 1), 1);
2994 } else {
2995 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen + 1);
David Benjamin48063c22017-01-01 23:56:36 -05002996 }
2997
2998 // Check the last write was correct. The data will be spread over two
2999 // records, so SSL_read returns twice.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003000 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
3001 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
3002 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), 1);
3003 ASSERT_EQ(buf[0], '!');
David Benjamin48063c22017-01-01 23:56:36 -05003004 }
David Benjamin48063c22017-01-01 23:56:36 -05003005}
3006
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003007TEST_P(SSLVersionTest, RecordCallback) {
3008 for (bool test_server : {true, false}) {
3009 SCOPED_TRACE(test_server);
3010 ResetContexts();
David Benjamin5df5be12017-06-22 19:43:11 -04003011
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003012 bool read_seen = false;
3013 bool write_seen = false;
3014 auto cb = [&](int is_write, int cb_version, int cb_type, const void *buf,
3015 size_t len, SSL *ssl) {
3016 if (cb_type != SSL3_RT_HEADER) {
3017 return;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003018 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003019
3020 // The callback does not report a version for records.
3021 EXPECT_EQ(0, cb_version);
3022
3023 if (is_write) {
3024 write_seen = true;
3025 } else {
3026 read_seen = true;
3027 }
3028
3029 // Sanity-check that the record header is plausible.
3030 CBS cbs;
3031 CBS_init(&cbs, reinterpret_cast<const uint8_t *>(buf), len);
3032 uint8_t type;
3033 uint16_t record_version, length;
3034 ASSERT_TRUE(CBS_get_u8(&cbs, &type));
3035 ASSERT_TRUE(CBS_get_u16(&cbs, &record_version));
3036 EXPECT_TRUE(record_version == version() ||
3037 record_version == (is_dtls() ? DTLS1_VERSION : TLS1_VERSION))
3038 << "Invalid record version: " << record_version;
3039 if (is_dtls()) {
3040 uint16_t epoch;
3041 ASSERT_TRUE(CBS_get_u16(&cbs, &epoch));
3042 EXPECT_TRUE(epoch == 0 || epoch == 1) << "Invalid epoch: " << epoch;
3043 ASSERT_TRUE(CBS_skip(&cbs, 6));
3044 }
3045 ASSERT_TRUE(CBS_get_u16(&cbs, &length));
3046 EXPECT_EQ(0u, CBS_len(&cbs));
3047 };
3048 using CallbackType = decltype(cb);
3049 SSL_CTX *ctx = test_server ? server_ctx_.get() : client_ctx_.get();
3050 SSL_CTX_set_msg_callback(
3051 ctx, [](int is_write, int cb_version, int cb_type, const void *buf,
3052 size_t len, SSL *ssl, void *arg) {
3053 CallbackType *cb_ptr = reinterpret_cast<CallbackType *>(arg);
3054 (*cb_ptr)(is_write, cb_version, cb_type, buf, len, ssl);
3055 });
3056 SSL_CTX_set_msg_callback_arg(ctx, &cb);
3057
3058 ASSERT_TRUE(Connect());
3059
3060 EXPECT_TRUE(read_seen);
3061 EXPECT_TRUE(write_seen);
David Benjamin0fef3052016-11-18 15:11:10 +09003062 }
David Benjamin9ef31f02016-10-31 18:01:13 -04003063}
3064
David Benjamina8614602017-09-06 15:40:19 -04003065TEST_P(SSLVersionTest, GetServerName) {
3066 // No extensions in SSL 3.0.
3067 if (version() == SSL3_VERSION) {
3068 return;
3069 }
3070
3071 ClientConfig config;
3072 config.servername = "host1";
3073
3074 SSL_CTX_set_tlsext_servername_callback(
3075 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
3076 // During the handshake, |SSL_get_servername| must match |config|.
3077 ClientConfig *config_p = reinterpret_cast<ClientConfig *>(arg);
3078 EXPECT_STREQ(config_p->servername.c_str(),
3079 SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name));
3080 return SSL_TLSEXT_ERR_OK;
3081 });
3082 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), &config);
3083
3084 ASSERT_TRUE(Connect(config));
3085 // After the handshake, it must also be available.
3086 EXPECT_STREQ(config.servername.c_str(),
3087 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3088
3089 // Establish a session under host1.
3090 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3091 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3092 bssl::UniquePtr<SSL_SESSION> session =
3093 CreateClientSession(client_ctx_.get(), server_ctx_.get(), config);
3094
3095 // If the client resumes a session with a different name, |SSL_get_servername|
3096 // must return the new name.
3097 ASSERT_TRUE(session);
3098 config.session = session.get();
3099 config.servername = "host2";
3100 ASSERT_TRUE(Connect(config));
3101 EXPECT_STREQ(config.servername.c_str(),
3102 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3103}
3104
David Benjamin3d8f0802017-09-06 16:12:52 -04003105// Test that session cache mode bits are honored in the client session callback.
3106TEST_P(SSLVersionTest, ClientSessionCacheMode) {
3107 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_OFF);
3108 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3109
3110 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_CLIENT);
3111 EXPECT_TRUE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3112
3113 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_SERVER);
3114 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3115}
3116
Adam Langleye1e78132017-01-31 15:24:31 -08003117TEST(SSLTest, AddChainCertHack) {
3118 // Ensure that we don't accidently break the hack that we have in place to
3119 // keep curl and serf happy when they use an |X509| even after transfering
3120 // ownership.
3121
3122 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3123 ASSERT_TRUE(ctx);
3124 X509 *cert = GetTestCertificate().release();
3125 ASSERT_TRUE(cert);
3126 SSL_CTX_add0_chain_cert(ctx.get(), cert);
3127
3128 // This should not trigger a use-after-free.
3129 X509_cmp(cert, cert);
3130}
3131
David Benjaminb2ff2622017-02-03 17:06:18 -05003132TEST(SSLTest, GetCertificate) {
3133 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3134 ASSERT_TRUE(ctx);
3135 bssl::UniquePtr<X509> cert = GetTestCertificate();
3136 ASSERT_TRUE(cert);
3137 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
3138 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3139 ASSERT_TRUE(ssl);
3140
3141 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
3142 ASSERT_TRUE(cert2);
3143 X509 *cert3 = SSL_get_certificate(ssl.get());
3144 ASSERT_TRUE(cert3);
3145
3146 // The old and new certificates must be identical.
3147 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
3148 EXPECT_EQ(0, X509_cmp(cert.get(), cert3));
3149
3150 uint8_t *der = nullptr;
3151 long der_len = i2d_X509(cert.get(), &der);
3152 ASSERT_LT(0, der_len);
3153 bssl::UniquePtr<uint8_t> free_der(der);
3154
3155 uint8_t *der2 = nullptr;
3156 long der2_len = i2d_X509(cert2, &der2);
3157 ASSERT_LT(0, der2_len);
3158 bssl::UniquePtr<uint8_t> free_der2(der2);
3159
3160 uint8_t *der3 = nullptr;
3161 long der3_len = i2d_X509(cert3, &der3);
3162 ASSERT_LT(0, der3_len);
3163 bssl::UniquePtr<uint8_t> free_der3(der3);
3164
3165 // They must also encode identically.
David Benjamin7d7554b2017-02-04 11:48:59 -05003166 EXPECT_EQ(Bytes(der, der_len), Bytes(der2, der2_len));
3167 EXPECT_EQ(Bytes(der, der_len), Bytes(der3, der3_len));
David Benjaminb2ff2622017-02-03 17:06:18 -05003168}
3169
Adam Langleyd04ca952017-02-28 11:26:51 -08003170TEST(SSLTest, SetChainAndKeyMismatch) {
3171 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_with_buffers_method()));
3172 ASSERT_TRUE(ctx);
3173
3174 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3175 ASSERT_TRUE(key);
3176 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3177 ASSERT_TRUE(leaf);
3178 std::vector<CRYPTO_BUFFER*> chain = {
3179 leaf.get(),
3180 };
3181
3182 // Should fail because |GetTestKey| doesn't match the chain-test certificate.
3183 ASSERT_FALSE(SSL_CTX_set_chain_and_key(ctx.get(), &chain[0], chain.size(),
3184 key.get(), nullptr));
3185 ERR_clear_error();
3186}
3187
3188TEST(SSLTest, SetChainAndKey) {
3189 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3190 ASSERT_TRUE(client_ctx);
3191 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3192 ASSERT_TRUE(server_ctx);
3193
3194 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3195 ASSERT_TRUE(key);
3196 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3197 ASSERT_TRUE(leaf);
3198 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3199 GetChainTestIntermediateBuffer();
3200 ASSERT_TRUE(intermediate);
3201 std::vector<CRYPTO_BUFFER*> chain = {
3202 leaf.get(), intermediate.get(),
3203 };
3204 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3205 chain.size(), key.get(), nullptr));
3206
David Benjamin3a1dd462017-07-11 16:13:10 -04003207 SSL_CTX_set_custom_verify(
3208 client_ctx.get(), SSL_VERIFY_PEER,
3209 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3210 return ssl_verify_ok;
3211 });
Adam Langleyd04ca952017-02-28 11:26:51 -08003212
3213 bssl::UniquePtr<SSL> client, server;
3214 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003215 server_ctx.get()));
Adam Langleyd04ca952017-02-28 11:26:51 -08003216}
3217
David Benjamin71dfad42017-07-16 17:27:39 -04003218TEST(SSLTest, ClientCABuffers) {
3219 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3220 ASSERT_TRUE(client_ctx);
3221 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3222 ASSERT_TRUE(server_ctx);
3223
3224 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3225 ASSERT_TRUE(key);
3226 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3227 ASSERT_TRUE(leaf);
3228 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3229 GetChainTestIntermediateBuffer();
3230 ASSERT_TRUE(intermediate);
3231 std::vector<CRYPTO_BUFFER *> chain = {
3232 leaf.get(),
3233 intermediate.get(),
3234 };
3235 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3236 chain.size(), key.get(), nullptr));
3237
3238 bssl::UniquePtr<CRYPTO_BUFFER> ca_name(
3239 CRYPTO_BUFFER_new(kTestName, sizeof(kTestName), nullptr));
3240 ASSERT_TRUE(ca_name);
3241 bssl::UniquePtr<STACK_OF(CRYPTO_BUFFER)> ca_names(
3242 sk_CRYPTO_BUFFER_new_null());
3243 ASSERT_TRUE(ca_names);
3244 ASSERT_TRUE(sk_CRYPTO_BUFFER_push(ca_names.get(), ca_name.get()));
3245 ca_name.release();
3246 SSL_CTX_set0_client_CAs(server_ctx.get(), ca_names.release());
3247
3248 // Configure client and server to accept all certificates.
3249 SSL_CTX_set_custom_verify(
3250 client_ctx.get(), SSL_VERIFY_PEER,
3251 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3252 return ssl_verify_ok;
3253 });
3254 SSL_CTX_set_custom_verify(
3255 server_ctx.get(), SSL_VERIFY_PEER,
3256 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3257 return ssl_verify_ok;
3258 });
3259
3260 bool cert_cb_called = false;
3261 SSL_CTX_set_cert_cb(
3262 client_ctx.get(),
3263 [](SSL *ssl, void *arg) -> int {
3264 STACK_OF(CRYPTO_BUFFER) *peer_names =
3265 SSL_get0_server_requested_CAs(ssl);
3266 EXPECT_EQ(1u, sk_CRYPTO_BUFFER_num(peer_names));
3267 CRYPTO_BUFFER *peer_name = sk_CRYPTO_BUFFER_value(peer_names, 0);
3268 EXPECT_EQ(Bytes(kTestName), Bytes(CRYPTO_BUFFER_data(peer_name),
3269 CRYPTO_BUFFER_len(peer_name)));
3270 *reinterpret_cast<bool *>(arg) = true;
3271 return 1;
3272 },
3273 &cert_cb_called);
3274
3275 bssl::UniquePtr<SSL> client, server;
3276 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003277 server_ctx.get()));
David Benjamin71dfad42017-07-16 17:27:39 -04003278 EXPECT_TRUE(cert_cb_called);
3279}
3280
David Benjamin91222b82017-03-09 20:10:56 -05003281// Configuring the empty cipher list, though an error, should still modify the
3282// configuration.
3283TEST(SSLTest, EmptyCipherList) {
3284 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3285 ASSERT_TRUE(ctx);
3286
3287 // Initially, the cipher list is not empty.
3288 EXPECT_NE(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3289
3290 // Configuring the empty cipher list fails.
3291 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), ""));
3292 ERR_clear_error();
3293
3294 // But the cipher list is still updated to empty.
3295 EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3296}
3297
Adam Langley4c341d02017-03-08 19:33:21 -08003298// ssl_test_ticket_aead_failure_mode enumerates the possible ways in which the
3299// test |SSL_TICKET_AEAD_METHOD| can fail.
3300enum ssl_test_ticket_aead_failure_mode {
3301 ssl_test_ticket_aead_ok = 0,
3302 ssl_test_ticket_aead_seal_fail,
3303 ssl_test_ticket_aead_open_soft_fail,
3304 ssl_test_ticket_aead_open_hard_fail,
3305};
3306
3307struct ssl_test_ticket_aead_state {
3308 unsigned retry_count;
3309 ssl_test_ticket_aead_failure_mode failure_mode;
3310};
3311
3312static int ssl_test_ticket_aead_ex_index_dup(CRYPTO_EX_DATA *to,
3313 const CRYPTO_EX_DATA *from,
3314 void **from_d, int index,
3315 long argl, void *argp) {
3316 abort();
3317}
3318
3319static void ssl_test_ticket_aead_ex_index_free(void *parent, void *ptr,
3320 CRYPTO_EX_DATA *ad, int index,
3321 long argl, void *argp) {
3322 auto state = reinterpret_cast<ssl_test_ticket_aead_state*>(ptr);
3323 if (state == nullptr) {
3324 return;
3325 }
3326
3327 OPENSSL_free(state);
3328}
3329
3330static CRYPTO_once_t g_ssl_test_ticket_aead_ex_index_once = CRYPTO_ONCE_INIT;
3331static int g_ssl_test_ticket_aead_ex_index;
3332
3333static int ssl_test_ticket_aead_get_ex_index() {
3334 CRYPTO_once(&g_ssl_test_ticket_aead_ex_index_once, [] {
3335 g_ssl_test_ticket_aead_ex_index = SSL_get_ex_new_index(
3336 0, nullptr, nullptr, ssl_test_ticket_aead_ex_index_dup,
3337 ssl_test_ticket_aead_ex_index_free);
3338 });
3339 return g_ssl_test_ticket_aead_ex_index;
3340}
3341
3342static size_t ssl_test_ticket_aead_max_overhead(SSL *ssl) {
3343 return 1;
3344}
3345
3346static int ssl_test_ticket_aead_seal(SSL *ssl, uint8_t *out, size_t *out_len,
3347 size_t max_out_len, const uint8_t *in,
3348 size_t in_len) {
3349 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3350 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3351
3352 if (state->failure_mode == ssl_test_ticket_aead_seal_fail ||
3353 max_out_len < in_len + 1) {
3354 return 0;
3355 }
3356
3357 OPENSSL_memmove(out, in, in_len);
3358 out[in_len] = 0xff;
3359 *out_len = in_len + 1;
3360
3361 return 1;
3362}
3363
3364static ssl_ticket_aead_result_t ssl_test_ticket_aead_open(
3365 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len,
3366 const uint8_t *in, size_t in_len) {
3367 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3368 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3369
3370 if (state->retry_count > 0) {
3371 state->retry_count--;
3372 return ssl_ticket_aead_retry;
3373 }
3374
3375 switch (state->failure_mode) {
3376 case ssl_test_ticket_aead_ok:
3377 break;
3378 case ssl_test_ticket_aead_seal_fail:
3379 // If |seal| failed then there shouldn't be any ticket to try and
3380 // decrypt.
3381 abort();
3382 break;
3383 case ssl_test_ticket_aead_open_soft_fail:
3384 return ssl_ticket_aead_ignore_ticket;
3385 case ssl_test_ticket_aead_open_hard_fail:
3386 return ssl_ticket_aead_error;
3387 }
3388
3389 if (in_len == 0 || in[in_len - 1] != 0xff) {
3390 return ssl_ticket_aead_ignore_ticket;
3391 }
3392
3393 if (max_out_len < in_len - 1) {
3394 return ssl_ticket_aead_error;
3395 }
3396
3397 OPENSSL_memmove(out, in, in_len - 1);
3398 *out_len = in_len - 1;
3399 return ssl_ticket_aead_success;
3400}
3401
3402static const SSL_TICKET_AEAD_METHOD kSSLTestTicketMethod = {
3403 ssl_test_ticket_aead_max_overhead,
3404 ssl_test_ticket_aead_seal,
3405 ssl_test_ticket_aead_open,
3406};
3407
3408static void ConnectClientAndServerWithTicketMethod(
3409 bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
3410 SSL_CTX *client_ctx, SSL_CTX *server_ctx, unsigned retry_count,
3411 ssl_test_ticket_aead_failure_mode failure_mode, SSL_SESSION *session) {
3412 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
3413 ASSERT_TRUE(client);
3414 ASSERT_TRUE(server);
3415 SSL_set_connect_state(client.get());
3416 SSL_set_accept_state(server.get());
3417
3418 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3419 OPENSSL_malloc(sizeof(ssl_test_ticket_aead_state)));
3420 ASSERT_TRUE(state);
3421 OPENSSL_memset(state, 0, sizeof(ssl_test_ticket_aead_state));
3422 state->retry_count = retry_count;
3423 state->failure_mode = failure_mode;
3424
3425 ASSERT_TRUE(SSL_set_ex_data(server.get(), ssl_test_ticket_aead_get_ex_index(),
3426 state));
3427
3428 SSL_set_session(client.get(), session);
3429
3430 BIO *bio1, *bio2;
3431 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
3432
3433 // SSL_set_bio takes ownership.
3434 SSL_set_bio(client.get(), bio1, bio1);
3435 SSL_set_bio(server.get(), bio2, bio2);
3436
3437 if (CompleteHandshakes(client.get(), server.get())) {
3438 *out_client = std::move(client);
3439 *out_server = std::move(server);
3440 } else {
3441 out_client->reset();
3442 out_server->reset();
3443 }
3444}
3445
3446class TicketAEADMethodTest
3447 : public ::testing::TestWithParam<testing::tuple<
3448 uint16_t, unsigned, ssl_test_ticket_aead_failure_mode>> {};
3449
3450TEST_P(TicketAEADMethodTest, Resume) {
3451 bssl::UniquePtr<X509> cert = GetTestCertificate();
3452 ASSERT_TRUE(cert);
3453 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3454 ASSERT_TRUE(key);
3455
3456 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
3457 ASSERT_TRUE(server_ctx);
3458 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
3459 ASSERT_TRUE(client_ctx);
3460
3461 const uint16_t version = testing::get<0>(GetParam());
3462 const unsigned retry_count = testing::get<1>(GetParam());
3463 const ssl_test_ticket_aead_failure_mode failure_mode =
3464 testing::get<2>(GetParam());
3465
3466 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3467 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3468 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), version));
3469 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), version));
3470 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), version));
3471 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), version));
3472
3473 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
3474 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
3475 SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
3476 SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
David Benjamin707af292017-03-10 17:47:18 -05003477 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langley4c341d02017-03-08 19:33:21 -08003478
3479 SSL_CTX_set_ticket_aead_method(server_ctx.get(), &kSSLTestTicketMethod);
3480
3481 bssl::UniquePtr<SSL> client, server;
3482 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3483 server_ctx.get(), retry_count,
3484 failure_mode, nullptr);
3485 switch (failure_mode) {
3486 case ssl_test_ticket_aead_ok:
3487 case ssl_test_ticket_aead_open_hard_fail:
3488 case ssl_test_ticket_aead_open_soft_fail:
3489 ASSERT_TRUE(client);
3490 break;
3491 case ssl_test_ticket_aead_seal_fail:
3492 EXPECT_FALSE(client);
3493 return;
3494 }
3495 EXPECT_FALSE(SSL_session_reused(client.get()));
3496 EXPECT_FALSE(SSL_session_reused(server.get()));
3497
David Benjamin707af292017-03-10 17:47:18 -05003498 // Run the read loop to account for post-handshake tickets in TLS 1.3.
3499 SSL_read(client.get(), nullptr, 0);
3500
3501 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
Adam Langley4c341d02017-03-08 19:33:21 -08003502 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3503 server_ctx.get(), retry_count,
David Benjamin707af292017-03-10 17:47:18 -05003504 failure_mode, session.get());
Adam Langley4c341d02017-03-08 19:33:21 -08003505 switch (failure_mode) {
3506 case ssl_test_ticket_aead_ok:
3507 ASSERT_TRUE(client);
3508 EXPECT_TRUE(SSL_session_reused(client.get()));
3509 EXPECT_TRUE(SSL_session_reused(server.get()));
3510 break;
3511 case ssl_test_ticket_aead_seal_fail:
3512 abort();
3513 break;
3514 case ssl_test_ticket_aead_open_hard_fail:
3515 EXPECT_FALSE(client);
3516 break;
3517 case ssl_test_ticket_aead_open_soft_fail:
3518 ASSERT_TRUE(client);
3519 EXPECT_FALSE(SSL_session_reused(client.get()));
3520 EXPECT_FALSE(SSL_session_reused(server.get()));
3521 }
3522}
3523
3524INSTANTIATE_TEST_CASE_P(
3525 TicketAEADMethodTests, TicketAEADMethodTest,
3526 testing::Combine(
David Benjamin707af292017-03-10 17:47:18 -05003527 testing::Values(TLS1_2_VERSION, TLS1_3_VERSION),
Adam Langley4c341d02017-03-08 19:33:21 -08003528 testing::Values(0, 1, 2),
3529 testing::Values(ssl_test_ticket_aead_ok,
3530 ssl_test_ticket_aead_seal_fail,
3531 ssl_test_ticket_aead_open_soft_fail,
3532 ssl_test_ticket_aead_open_hard_fail)));
3533
David Benjamin3cfeb952017-03-01 16:48:38 -05003534TEST(SSLTest, SSL3Method) {
3535 bssl::UniquePtr<X509> cert = GetTestCertificate();
3536 ASSERT_TRUE(cert);
3537
3538 // For compatibility, SSLv3_method should work up to SSL_CTX_new and SSL_new.
3539 bssl::UniquePtr<SSL_CTX> ssl3_ctx(SSL_CTX_new(SSLv3_method()));
3540 ASSERT_TRUE(ssl3_ctx);
3541 ASSERT_TRUE(SSL_CTX_use_certificate(ssl3_ctx.get(), cert.get()));
3542 bssl::UniquePtr<SSL> ssl(SSL_new(ssl3_ctx.get()));
3543 EXPECT_TRUE(ssl);
3544
3545 // Create a normal TLS context to test against.
3546 bssl::UniquePtr<SSL_CTX> tls_ctx(SSL_CTX_new(TLS_method()));
3547 ASSERT_TRUE(tls_ctx);
3548 ASSERT_TRUE(SSL_CTX_use_certificate(tls_ctx.get(), cert.get()));
3549
3550 // However, handshaking an SSLv3_method server should fail to resolve the
3551 // version range. Explicit calls to SSL_CTX_set_min_proto_version are the only
3552 // way to enable SSL 3.0.
3553 bssl::UniquePtr<SSL> client, server;
3554 EXPECT_FALSE(ConnectClientAndServer(&client, &server, tls_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003555 ssl3_ctx.get()));
David Benjamin3cfeb952017-03-01 16:48:38 -05003556 uint32_t err = ERR_get_error();
3557 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
3558 EXPECT_EQ(SSL_R_NO_SUPPORTED_VERSIONS_ENABLED, ERR_GET_REASON(err));
3559
3560 // Likewise for SSLv3_method clients.
3561 EXPECT_FALSE(ConnectClientAndServer(&client, &server, ssl3_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003562 tls_ctx.get()));
David Benjamin3cfeb952017-03-01 16:48:38 -05003563 err = ERR_get_error();
3564 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
3565 EXPECT_EQ(SSL_R_NO_SUPPORTED_VERSIONS_ENABLED, ERR_GET_REASON(err));
3566}
3567
David Benjaminca743582017-06-15 17:51:35 -04003568TEST(SSLTest, SelectNextProto) {
3569 uint8_t *result;
3570 uint8_t result_len;
3571
3572 // If there is an overlap, it should be returned.
3573 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3574 SSL_select_next_proto(&result, &result_len,
3575 (const uint8_t *)"\1a\2bb\3ccc", 9,
3576 (const uint8_t *)"\1x\1y\1a\1z", 8));
3577 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
3578
3579 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3580 SSL_select_next_proto(&result, &result_len,
3581 (const uint8_t *)"\1a\2bb\3ccc", 9,
3582 (const uint8_t *)"\1x\1y\2bb\1z", 9));
3583 EXPECT_EQ(Bytes("bb"), Bytes(result, result_len));
3584
3585 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3586 SSL_select_next_proto(&result, &result_len,
3587 (const uint8_t *)"\1a\2bb\3ccc", 9,
3588 (const uint8_t *)"\1x\1y\3ccc\1z", 10));
3589 EXPECT_EQ(Bytes("ccc"), Bytes(result, result_len));
3590
3591 // Peer preference order takes precedence over local.
3592 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3593 SSL_select_next_proto(&result, &result_len,
3594 (const uint8_t *)"\1a\2bb\3ccc", 9,
3595 (const uint8_t *)"\3ccc\2bb\1a", 9));
3596 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
3597
3598 // If there is no overlap, return the first local protocol.
3599 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
3600 SSL_select_next_proto(&result, &result_len,
3601 (const uint8_t *)"\1a\2bb\3ccc", 9,
3602 (const uint8_t *)"\1x\2yy\3zzz", 9));
3603 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
3604
3605 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
3606 SSL_select_next_proto(&result, &result_len, nullptr, 0,
3607 (const uint8_t *)"\1x\2yy\3zzz", 9));
3608 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
3609}
3610
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003611TEST(SSLTest, SealRecord) {
3612 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3613 server_ctx(SSL_CTX_new(TLS_method()));
3614 ASSERT_TRUE(client_ctx);
3615 ASSERT_TRUE(server_ctx);
3616
3617 bssl::UniquePtr<X509> cert = GetTestCertificate();
3618 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3619 ASSERT_TRUE(cert);
3620 ASSERT_TRUE(key);
3621 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3622 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3623
3624 bssl::UniquePtr<SSL> client, server;
3625 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003626 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003627
3628 const std::vector<uint8_t> record = {1, 2, 3, 4, 5};
3629 std::vector<uint8_t> prefix(
3630 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003631 body(record.size()),
3632 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003633 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3634 bssl::MakeSpan(body), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003635 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003636
3637 std::vector<uint8_t> sealed;
3638 sealed.insert(sealed.end(), prefix.begin(), prefix.end());
3639 sealed.insert(sealed.end(), body.begin(), body.end());
3640 sealed.insert(sealed.end(), suffix.begin(), suffix.end());
3641 std::vector<uint8_t> sealed_copy = sealed;
3642
3643 bssl::Span<uint8_t> plaintext;
3644 size_t record_len;
3645 uint8_t alert = 255;
3646 EXPECT_EQ(bssl::OpenRecord(server.get(), &plaintext, &record_len, &alert,
3647 bssl::MakeSpan(sealed)),
3648 bssl::OpenRecordResult::kOK);
3649 EXPECT_EQ(record_len, sealed.size());
3650 EXPECT_EQ(plaintext, record);
3651 EXPECT_EQ(255, alert);
3652}
3653
3654TEST(SSLTest, SealRecordInPlace) {
3655 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3656 server_ctx(SSL_CTX_new(TLS_method()));
3657 ASSERT_TRUE(client_ctx);
3658 ASSERT_TRUE(server_ctx);
3659
3660 bssl::UniquePtr<X509> cert = GetTestCertificate();
3661 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3662 ASSERT_TRUE(cert);
3663 ASSERT_TRUE(key);
3664 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3665 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3666
3667 bssl::UniquePtr<SSL> client, server;
3668 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003669 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003670
3671 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
3672 std::vector<uint8_t> record = plaintext;
3673 std::vector<uint8_t> prefix(
3674 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003675 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003676 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3677 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003678 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003679 record.insert(record.begin(), prefix.begin(), prefix.end());
3680 record.insert(record.end(), suffix.begin(), suffix.end());
3681
3682 bssl::Span<uint8_t> result;
3683 size_t record_len;
3684 uint8_t alert;
3685 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
3686 bssl::MakeSpan(record)),
3687 bssl::OpenRecordResult::kOK);
3688 EXPECT_EQ(record_len, record.size());
3689 EXPECT_EQ(plaintext, result);
3690}
3691
3692TEST(SSLTest, SealRecordTrailingData) {
3693 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3694 server_ctx(SSL_CTX_new(TLS_method()));
3695 ASSERT_TRUE(client_ctx);
3696 ASSERT_TRUE(server_ctx);
3697
3698 bssl::UniquePtr<X509> cert = GetTestCertificate();
3699 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3700 ASSERT_TRUE(cert);
3701 ASSERT_TRUE(key);
3702 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3703 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3704
3705 bssl::UniquePtr<SSL> client, server;
3706 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003707 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003708
3709 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
3710 std::vector<uint8_t> record = plaintext;
3711 std::vector<uint8_t> prefix(
3712 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003713 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003714 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3715 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003716 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003717 record.insert(record.begin(), prefix.begin(), prefix.end());
3718 record.insert(record.end(), suffix.begin(), suffix.end());
3719 record.insert(record.end(), {5, 4, 3, 2, 1});
3720
3721 bssl::Span<uint8_t> result;
3722 size_t record_len;
3723 uint8_t alert;
3724 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
3725 bssl::MakeSpan(record)),
3726 bssl::OpenRecordResult::kOK);
3727 EXPECT_EQ(record_len, record.size() - 5);
3728 EXPECT_EQ(plaintext, result);
3729}
3730
3731TEST(SSLTest, SealRecordInvalidSpanSize) {
3732 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3733 server_ctx(SSL_CTX_new(TLS_method()));
3734 ASSERT_TRUE(client_ctx);
3735 ASSERT_TRUE(server_ctx);
3736
3737 bssl::UniquePtr<X509> cert = GetTestCertificate();
3738 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3739 ASSERT_TRUE(cert);
3740 ASSERT_TRUE(key);
3741 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3742 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3743
3744 bssl::UniquePtr<SSL> client, server;
3745 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003746 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003747
3748 std::vector<uint8_t> record = {1, 2, 3, 4, 5};
3749 std::vector<uint8_t> prefix(
3750 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003751 body(record.size()),
3752 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003753
3754 auto expect_err = []() {
3755 int err = ERR_get_error();
3756 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
3757 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_BUFFER_TOO_SMALL);
3758 ERR_clear_error();
3759 };
3760 EXPECT_FALSE(bssl::SealRecord(
3761 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003762 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003763 expect_err();
3764 EXPECT_FALSE(bssl::SealRecord(
3765 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003766 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003767 expect_err();
3768
3769 EXPECT_FALSE(
3770 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3771 bssl::MakeSpan(record.data(), record.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003772 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003773 expect_err();
3774 EXPECT_FALSE(
3775 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3776 bssl::MakeSpan(record.data(), record.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003777 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003778 expect_err();
3779
3780 EXPECT_FALSE(bssl::SealRecord(
3781 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003782 bssl::MakeSpan(suffix.data(), suffix.size() - 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003783 expect_err();
3784 EXPECT_FALSE(bssl::SealRecord(
3785 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003786 bssl::MakeSpan(suffix.data(), suffix.size() + 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003787 expect_err();
3788}
3789
David Benjamin617b8182017-08-29 15:33:10 -04003790// The client should gracefully handle no suitable ciphers being enabled.
3791TEST(SSLTest, NoCiphersAvailable) {
3792 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3793 ASSERT_TRUE(ctx);
3794
3795 // Configure |client_ctx| with a cipher list that does not intersect with its
3796 // version configuration.
3797 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
3798 ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
3799 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
3800
3801 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3802 ASSERT_TRUE(ssl);
3803 SSL_set_connect_state(ssl.get());
3804
3805 UniquePtr<BIO> rbio(BIO_new(BIO_s_mem())), wbio(BIO_new(BIO_s_mem()));
3806 ASSERT_TRUE(rbio);
3807 ASSERT_TRUE(wbio);
3808 SSL_set0_rbio(ssl.get(), rbio.release());
3809 SSL_set0_wbio(ssl.get(), wbio.release());
3810
3811 int ret = SSL_do_handshake(ssl.get());
3812 EXPECT_EQ(-1, ret);
3813 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), ret));
3814 uint32_t err = ERR_get_error();
3815 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
3816 EXPECT_EQ(SSL_R_NO_CIPHERS_AVAILABLE, ERR_GET_REASON(err));
3817}
3818
David Benjamin96628432017-01-19 19:05:47 -05003819// TODO(davidben): Convert this file to GTest properly.
3820TEST(SSLTest, AllTests) {
David Benjamine11726a2017-04-23 12:14:28 -04003821 if (!TestSSL_SESSIONEncoding(kOpenSSLSession) ||
Adam Langley10f97f32016-07-12 08:09:33 -07003822 !TestSSL_SESSIONEncoding(kCustomSession) ||
3823 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
3824 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
3825 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
3826 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
Steven Valdeza833c352016-11-01 13:39:36 -04003827 // Test the padding extension at TLS 1.2.
3828 !TestPaddingExtension(TLS1_2_VERSION, TLS1_2_VERSION) ||
3829 // Test the padding extension at TLS 1.3 with a TLS 1.2 session, so there
3830 // will be no PSK binder after the padding extension.
3831 !TestPaddingExtension(TLS1_3_VERSION, TLS1_2_VERSION) ||
3832 // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
3833 // will be a PSK binder after the padding extension.
3834 !TestPaddingExtension(TLS1_3_VERSION, TLS1_3_DRAFT_VERSION) ||
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003835 !TestClientHello()) {
David Benjamin96628432017-01-19 19:05:47 -05003836 ADD_FAILURE() << "Tests failed";
David Benjaminbb0a17c2014-09-20 15:35:39 -04003837 }
David Benjamin2e521212014-07-16 14:37:51 -04003838}
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003839
3840} // namespace
3841} // namespace bssl