blob: 10bc215c15b4092462535f6715f79c608b39b096 [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 Benjaminb1b76ae2017-09-21 17:03:34 -0400831 int prf_nid;
David Benjamin6fff3862017-06-21 21:07:04 -0400832 } kTests[] = {
David Benjamin348f0d82017-08-10 16:06:27 -0400833 {
834 SSL3_CK_RSA_DES_192_CBC3_SHA,
835 "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
836 NID_des_ede3_cbc,
837 NID_sha1,
838 NID_kx_rsa,
839 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400840 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400841 },
842 {
843 TLS1_CK_RSA_WITH_AES_128_SHA,
844 "TLS_RSA_WITH_AES_128_CBC_SHA",
845 NID_aes_128_cbc,
846 NID_sha1,
847 NID_kx_rsa,
848 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400849 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400850 },
851 {
852 TLS1_CK_PSK_WITH_AES_256_CBC_SHA,
853 "TLS_PSK_WITH_AES_256_CBC_SHA",
854 NID_aes_256_cbc,
855 NID_sha1,
856 NID_kx_psk,
857 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400858 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400859 },
860 {
861 TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
862 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
863 NID_aes_128_cbc,
864 NID_sha256,
865 NID_kx_ecdhe,
866 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400867 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400868 },
869 {
870 TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
871 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
872 NID_aes_256_cbc,
873 NID_sha384,
874 NID_kx_ecdhe,
875 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400876 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -0400877 },
878 {
879 TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
880 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
881 NID_aes_128_gcm,
882 NID_undef,
883 NID_kx_ecdhe,
884 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400885 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400886 },
887 {
888 TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
889 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
890 NID_aes_128_gcm,
891 NID_undef,
892 NID_kx_ecdhe,
893 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400894 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400895 },
896 {
897 TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
898 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
899 NID_aes_256_gcm,
900 NID_undef,
901 NID_kx_ecdhe,
902 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400903 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -0400904 },
905 {
906 TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
907 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
908 NID_aes_128_cbc,
909 NID_sha1,
910 NID_kx_ecdhe,
911 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400912 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400913 },
914 {
915 TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
916 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
917 NID_chacha20_poly1305,
918 NID_undef,
919 NID_kx_ecdhe,
920 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400921 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400922 },
923 {
924 TLS1_CK_AES_256_GCM_SHA384,
925 "TLS_AES_256_GCM_SHA384",
926 NID_aes_256_gcm,
927 NID_undef,
928 NID_kx_any,
929 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400930 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -0400931 },
932 {
933 TLS1_CK_AES_128_GCM_SHA256,
934 "TLS_AES_128_GCM_SHA256",
935 NID_aes_128_gcm,
936 NID_undef,
937 NID_kx_any,
938 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400939 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400940 },
941 {
942 TLS1_CK_CHACHA20_POLY1305_SHA256,
943 "TLS_CHACHA20_POLY1305_SHA256",
944 NID_chacha20_poly1305,
945 NID_undef,
946 NID_kx_any,
947 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400948 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400949 },
David Benjamin6fff3862017-06-21 21:07:04 -0400950 };
David Benjamin65226252015-02-05 16:49:47 -0500951
David Benjamin6fff3862017-06-21 21:07:04 -0400952 for (const auto &t : kTests) {
953 SCOPED_TRACE(t.standard_name);
David Benjamine11726a2017-04-23 12:14:28 -0400954
955 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(t.id & 0xffff);
956 ASSERT_TRUE(cipher);
David Benjamin6fff3862017-06-21 21:07:04 -0400957 EXPECT_STREQ(t.standard_name, SSL_CIPHER_standard_name(cipher));
958
David Benjamine11726a2017-04-23 12:14:28 -0400959 bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
960 ASSERT_TRUE(rfc_name);
David Benjamin6fff3862017-06-21 21:07:04 -0400961 EXPECT_STREQ(t.standard_name, rfc_name.get());
David Benjamin348f0d82017-08-10 16:06:27 -0400962
963 EXPECT_EQ(t.cipher_nid, SSL_CIPHER_get_cipher_nid(cipher));
964 EXPECT_EQ(t.digest_nid, SSL_CIPHER_get_digest_nid(cipher));
965 EXPECT_EQ(t.kx_nid, SSL_CIPHER_get_kx_nid(cipher));
966 EXPECT_EQ(t.auth_nid, SSL_CIPHER_get_auth_nid(cipher));
David Benjaminb1b76ae2017-09-21 17:03:34 -0400967 EXPECT_EQ(t.prf_nid, SSL_CIPHER_get_prf_nid(cipher));
David Benjamin65226252015-02-05 16:49:47 -0500968 }
David Benjamin65226252015-02-05 16:49:47 -0500969}
970
Steven Valdeza833c352016-11-01 13:39:36 -0400971// CreateSessionWithTicket returns a sample |SSL_SESSION| with the specified
972// version and ticket length or nullptr on failure.
973static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(uint16_t version,
974 size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -0400975 std::vector<uint8_t> der;
976 if (!DecodeBase64(&der, kOpenSSLSession)) {
977 return nullptr;
978 }
Adam Langley46db7af2017-02-01 15:49:37 -0800979
980 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
981 if (!ssl_ctx) {
982 return nullptr;
983 }
Steven Valdeza833c352016-11-01 13:39:36 -0400984 bssl::UniquePtr<SSL_SESSION> session(
Adam Langley46db7af2017-02-01 15:49:37 -0800985 SSL_SESSION_from_bytes(der.data(), der.size(), ssl_ctx.get()));
David Benjamin422fe082015-07-21 22:03:43 -0400986 if (!session) {
987 return nullptr;
988 }
989
Steven Valdeza833c352016-11-01 13:39:36 -0400990 session->ssl_version = version;
991
David Benjamin422fe082015-07-21 22:03:43 -0400992 // Swap out the ticket for a garbage one.
993 OPENSSL_free(session->tlsext_tick);
994 session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len));
995 if (session->tlsext_tick == nullptr) {
996 return nullptr;
997 }
David Benjamin17cf2cb2016-12-13 01:07:13 -0500998 OPENSSL_memset(session->tlsext_tick, 'a', ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -0400999 session->tlsext_ticklen = ticket_len;
David Benjamin1269ddd2015-10-18 15:18:55 -04001000
1001 // Fix up the timeout.
David Benjamin9b63f292016-11-15 00:44:05 -05001002#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
1003 session->time = 1234;
1004#else
David Benjamin1269ddd2015-10-18 15:18:55 -04001005 session->time = time(NULL);
David Benjamin9b63f292016-11-15 00:44:05 -05001006#endif
David Benjamin422fe082015-07-21 22:03:43 -04001007 return session;
1008}
1009
David Benjaminafc64de2016-07-19 17:12:41 +02001010static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001011 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +02001012 if (!bio) {
1013 return false;
1014 }
1015 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -04001016 BIO_up_ref(bio.get());
1017 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +02001018 int ret = SSL_connect(ssl);
1019 if (ret > 0) {
1020 // SSL_connect should fail without a BIO to write to.
1021 return false;
1022 }
1023 ERR_clear_error();
1024
1025 const uint8_t *client_hello;
1026 size_t client_hello_len;
1027 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
1028 return false;
1029 }
1030 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
1031 return true;
1032}
1033
Steven Valdeza833c352016-11-01 13:39:36 -04001034// GetClientHelloLen creates a client SSL connection with the specified version
1035// and ticket length. It returns the length of the ClientHello, not including
1036// the record header, on success and zero on error.
1037static size_t GetClientHelloLen(uint16_t max_version, uint16_t session_version,
1038 size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001039 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Steven Valdeza833c352016-11-01 13:39:36 -04001040 bssl::UniquePtr<SSL_SESSION> session =
1041 CreateSessionWithTicket(session_version, ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -04001042 if (!ctx || !session) {
1043 return 0;
1044 }
Steven Valdeza833c352016-11-01 13:39:36 -04001045
1046 // Set a one-element cipher list so the baseline ClientHello is unpadded.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001047 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
Steven Valdez2c62fe92016-10-14 12:08:12 -04001048 if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -08001049 !SSL_set_strict_cipher_list(ssl.get(), "ECDHE-RSA-AES128-GCM-SHA256") ||
Steven Valdeza833c352016-11-01 13:39:36 -04001050 !SSL_set_max_proto_version(ssl.get(), max_version)) {
David Benjamin422fe082015-07-21 22:03:43 -04001051 return 0;
1052 }
Steven Valdeza833c352016-11-01 13:39:36 -04001053
David Benjaminafc64de2016-07-19 17:12:41 +02001054 std::vector<uint8_t> client_hello;
1055 if (!GetClientHello(ssl.get(), &client_hello) ||
1056 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -04001057 return 0;
1058 }
Steven Valdeza833c352016-11-01 13:39:36 -04001059
David Benjaminafc64de2016-07-19 17:12:41 +02001060 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -04001061}
1062
1063struct PaddingTest {
1064 size_t input_len, padded_len;
1065};
1066
1067static const PaddingTest kPaddingTests[] = {
1068 // ClientHellos of length below 0x100 do not require padding.
1069 {0xfe, 0xfe},
1070 {0xff, 0xff},
1071 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
1072 {0x100, 0x200},
1073 {0x123, 0x200},
1074 {0x1fb, 0x200},
1075 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
1076 // padding extension takes a minimum of four bytes plus one required content
1077 // byte. (To work around yet more server bugs, we avoid empty final
1078 // extensions.)
1079 {0x1fc, 0x201},
1080 {0x1fd, 0x202},
1081 {0x1fe, 0x203},
1082 {0x1ff, 0x204},
1083 // Finally, larger ClientHellos need no padding.
1084 {0x200, 0x200},
1085 {0x201, 0x201},
1086};
1087
Steven Valdeza833c352016-11-01 13:39:36 -04001088static bool TestPaddingExtension(uint16_t max_version,
1089 uint16_t session_version) {
David Benjamin422fe082015-07-21 22:03:43 -04001090 // Sample a baseline length.
Steven Valdeza833c352016-11-01 13:39:36 -04001091 size_t base_len = GetClientHelloLen(max_version, session_version, 1);
David Benjamin422fe082015-07-21 22:03:43 -04001092 if (base_len == 0) {
1093 return false;
1094 }
1095
1096 for (const PaddingTest &test : kPaddingTests) {
1097 if (base_len > test.input_len) {
Steven Valdeza833c352016-11-01 13:39:36 -04001098 fprintf(stderr,
1099 "Baseline ClientHello too long (max_version = %04x, "
1100 "session_version = %04x).\n",
1101 max_version, session_version);
David Benjamin422fe082015-07-21 22:03:43 -04001102 return false;
1103 }
1104
Steven Valdeza833c352016-11-01 13:39:36 -04001105 size_t padded_len = GetClientHelloLen(max_version, session_version,
1106 1 + test.input_len - base_len);
David Benjamin422fe082015-07-21 22:03:43 -04001107 if (padded_len != test.padded_len) {
Steven Valdeza833c352016-11-01 13:39:36 -04001108 fprintf(stderr,
1109 "%u-byte ClientHello padded to %u bytes, not %u (max_version = "
1110 "%04x, session_version = %04x).\n",
David Benjamin422fe082015-07-21 22:03:43 -04001111 static_cast<unsigned>(test.input_len),
1112 static_cast<unsigned>(padded_len),
Steven Valdeza833c352016-11-01 13:39:36 -04001113 static_cast<unsigned>(test.padded_len), max_version,
1114 session_version);
David Benjamin422fe082015-07-21 22:03:43 -04001115 return false;
1116 }
1117 }
Steven Valdeza833c352016-11-01 13:39:36 -04001118
David Benjamin422fe082015-07-21 22:03:43 -04001119 return true;
1120}
1121
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001122static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001123 static const char kCertPEM[] =
1124 "-----BEGIN CERTIFICATE-----\n"
1125 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1126 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1127 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1128 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1129 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1130 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1131 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1132 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1133 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1134 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1135 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1136 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1137 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1138 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001139 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
David Benjamin1444c3a2016-12-20 17:23:11 -05001140 return bssl::UniquePtr<X509>(
1141 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjaminde942382016-02-11 12:02:01 -05001142}
1143
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001144static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001145 static const char kKeyPEM[] =
1146 "-----BEGIN RSA PRIVATE KEY-----\n"
1147 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1148 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1149 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1150 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1151 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1152 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1153 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1154 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1155 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1156 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1157 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1158 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1159 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1160 "-----END RSA PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001161 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1162 return bssl::UniquePtr<EVP_PKEY>(
David Benjaminde942382016-02-11 12:02:01 -05001163 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1164}
1165
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001166static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001167 static const char kCertPEM[] =
1168 "-----BEGIN CERTIFICATE-----\n"
1169 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1170 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1171 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1172 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1173 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1174 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1175 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1176 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1177 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1178 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1179 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001180 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1181 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjamin0fc37ef2016-08-17 15:29:46 -04001182}
1183
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001184static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001185 static const char kKeyPEM[] =
1186 "-----BEGIN PRIVATE KEY-----\n"
1187 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1188 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1189 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1190 "-----END PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001191 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1192 return bssl::UniquePtr<EVP_PKEY>(
David Benjamin0fc37ef2016-08-17 15:29:46 -04001193 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1194}
1195
Adam Langleyd04ca952017-02-28 11:26:51 -08001196static bssl::UniquePtr<CRYPTO_BUFFER> BufferFromPEM(const char *pem) {
1197 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1198 char *name, *header;
1199 uint8_t *data;
1200 long data_len;
1201 if (!PEM_read_bio(bio.get(), &name, &header, &data,
1202 &data_len)) {
1203 return nullptr;
1204 }
1205 OPENSSL_free(name);
1206 OPENSSL_free(header);
1207
1208 auto ret = bssl::UniquePtr<CRYPTO_BUFFER>(
1209 CRYPTO_BUFFER_new(data, data_len, nullptr));
1210 OPENSSL_free(data);
1211 return ret;
1212}
1213
1214static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestCertificateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001215 static const char kCertPEM[] =
1216 "-----BEGIN CERTIFICATE-----\n"
1217 "MIIC0jCCAbqgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQiBD\n"
1218 "QTAeFw0xNjAyMjgyMDI3MDNaFw0yNjAyMjUyMDI3MDNaMBgxFjAUBgNVBAMMDUNs\n"
1219 "aWVudCBDZXJ0IEEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRvaz8\n"
1220 "CC/cshpCafJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/\n"
1221 "kLRcH89M/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3\n"
1222 "tHb+xs2PSs8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+c\n"
1223 "IDs2rQ+lP7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1\n"
1224 "z7C8jU50Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9V\n"
1225 "iLeXANgZi+Xx9KgfAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI\n"
1226 "KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBFEVbmYl+2RtNw\n"
1227 "rDftRDF1v2QUbcN2ouSnQDHxeDQdSgasLzT3ui8iYu0Rw2WWcZ0DV5e0ztGPhWq7\n"
1228 "AO0B120aFRMOY+4+bzu9Q2FFkQqc7/fKTvTDzIJI5wrMnFvUfzzvxh3OHWMYSs/w\n"
1229 "giq33hTKeHEq6Jyk3btCny0Ycecyc3yGXH10sizUfiHlhviCkDuESk8mFDwDDzqW\n"
1230 "ZF0IipzFbEDHoIxLlm3GQxpiLoEV4k8KYJp3R5KBLFyxM6UGPz8h72mIPCJp2RuK\n"
1231 "MYgF91UDvVzvnYm6TfseM2+ewKirC00GOrZ7rEcFvtxnKSqYf4ckqfNdSU1Y+RRC\n"
1232 "1ngWZ7Ih\n"
1233 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001234 return BufferFromPEM(kCertPEM);
David Benjamin1444c3a2016-12-20 17:23:11 -05001235}
1236
Adam Langleyd04ca952017-02-28 11:26:51 -08001237static bssl::UniquePtr<X509> X509FromBuffer(
1238 bssl::UniquePtr<CRYPTO_BUFFER> buffer) {
1239 if (!buffer) {
1240 return nullptr;
1241 }
1242 const uint8_t *derp = CRYPTO_BUFFER_data(buffer.get());
1243 return bssl::UniquePtr<X509>(
1244 d2i_X509(NULL, &derp, CRYPTO_BUFFER_len(buffer.get())));
1245}
1246
1247static bssl::UniquePtr<X509> GetChainTestCertificate() {
1248 return X509FromBuffer(GetChainTestCertificateBuffer());
1249}
1250
1251static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestIntermediateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001252 static const char kCertPEM[] =
1253 "-----BEGIN CERTIFICATE-----\n"
1254 "MIICwjCCAaqgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS\n"
1255 "b290IENBMB4XDTE2MDIyODIwMjcwM1oXDTI2MDIyNTIwMjcwM1owDzENMAsGA1UE\n"
1256 "AwwEQiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALsSCYmDip2D\n"
1257 "GkjFxw7ykz26JSjELkl6ArlYjFJ3aT/SCh8qbS4gln7RH8CPBd78oFdfhIKQrwtZ\n"
1258 "3/q21ykD9BAS3qHe2YdcJfm8/kWAy5DvXk6NXU4qX334KofBAEpgdA/igEFq1P1l\n"
1259 "HAuIfZCpMRfT+i5WohVsGi8f/NgpRvVaMONLNfgw57mz1lbtFeBEISmX0kbsuJxF\n"
1260 "Qj/Bwhi5/0HAEXG8e7zN4cEx0yPRvmOATRdVb/8dW2pwOHRJq9R5M0NUkIsTSnL7\n"
1261 "6N/z8hRAHMsV3IudC5Yd7GXW1AGu9a+iKU+Q4xcZCoj0DC99tL4VKujrV1kAeqsM\n"
1262 "cz5/dKzi6+cCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
1263 "AQYwDQYJKoZIhvcNAQELBQADggEBAIIeZiEeNhWWQ8Y4D+AGDwqUUeG8NjCbKrXQ\n"
1264 "BlHg5wZ8xftFaiP1Dp/UAezmx2LNazdmuwrYB8lm3FVTyaPDTKEGIPS4wJKHgqH1\n"
1265 "QPDhqNm85ey7TEtI9oYjsNim/Rb+iGkIAMXaxt58SzxbjvP0kMr1JfJIZbic9vye\n"
1266 "NwIspMFIpP3FB8ywyu0T0hWtCQgL4J47nigCHpOu58deP88fS/Nyz/fyGVWOZ76b\n"
1267 "WhWwgM3P3X95fQ3d7oFPR/bVh0YV+Cf861INwplokXgXQ3/TCQ+HNXeAMWn3JLWv\n"
1268 "XFwk8owk9dq/kQGdndGgy3KTEW4ctPX5GNhf3LJ9Q7dLji4ReQ4=\n"
1269 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001270 return BufferFromPEM(kCertPEM);
1271}
1272
1273static bssl::UniquePtr<X509> GetChainTestIntermediate() {
1274 return X509FromBuffer(GetChainTestIntermediateBuffer());
David Benjamin1444c3a2016-12-20 17:23:11 -05001275}
1276
1277static bssl::UniquePtr<EVP_PKEY> GetChainTestKey() {
1278 static const char kKeyPEM[] =
1279 "-----BEGIN PRIVATE KEY-----\n"
1280 "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRvaz8CC/cshpC\n"
1281 "afJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/kLRcH89M\n"
1282 "/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3tHb+xs2P\n"
1283 "Ss8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+cIDs2rQ+l\n"
1284 "P7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1z7C8jU50\n"
1285 "Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9ViLeXANgZ\n"
1286 "i+Xx9KgfAgMBAAECggEBAK0VjSJzkyPaamcyTVSWjo7GdaBGcK60lk657RjR+lK0\n"
1287 "YJ7pkej4oM2hdsVZFsP8Cs4E33nXLa/0pDsRov/qrp0WQm2skwqGMC1I/bZ0WRPk\n"
1288 "wHaDrBBfESWnJDX/AGpVtlyOjPmgmK6J2usMPihQUDkKdAYrVWJePrMIxt1q6BMe\n"
1289 "iczs3qriMmtY3bUc4UyUwJ5fhDLjshHvfuIpYQyI6EXZM6dZksn9LylXJnigY6QJ\n"
1290 "HxOYO0BDwOsZ8yQ8J8afLk88i0GizEkgE1z3REtQUwgWfxr1WV/ud+T6/ZhSAgH9\n"
1291 "042mQvSFZnIUSEsmCvjhWuAunfxHKCTcAoYISWfzWpkCgYEA7gpf3HHU5Tn+CgUn\n"
1292 "1X5uGpG3DmcMgfeGgs2r2f/IIg/5Ac1dfYILiybL1tN9zbyLCJfcbFpWBc9hJL6f\n"
1293 "CPc5hUiwWFJqBJewxQkC1Ae/HakHbip+IZ+Jr0842O4BAArvixk4Lb7/N2Ct9sTE\n"
1294 "NJO6RtK9lbEZ5uK61DglHy8CS2UCgYEA4ZC1o36kPAMQBggajgnucb2yuUEelk0f\n"
1295 "AEr+GI32MGE+93xMr7rAhBoqLg4AITyIfEnOSQ5HwagnIHonBbv1LV/Gf9ursx8Z\n"
1296 "YOGbvT8zzzC+SU1bkDzdjAYnFQVGIjMtKOBJ3K07++ypwX1fr4QsQ8uKL8WSOWwt\n"
1297 "Z3Bym6XiZzMCgYADnhy+2OwHX85AkLt+PyGlPbmuelpyTzS4IDAQbBa6jcuW/2wA\n"
1298 "UE2km75VUXmD+u2R/9zVuLm99NzhFhSMqlUxdV1YukfqMfP5yp1EY6m/5aW7QuIP\n"
1299 "2MDa7TVL9rIFMiVZ09RKvbBbQxjhuzPQKL6X/PPspnhiTefQ+dl2k9xREQKBgHDS\n"
1300 "fMfGNEeAEKezrfSVqxphE9/tXms3L+ZpnCaT+yu/uEr5dTIAawKoQ6i9f/sf1/Sy\n"
1301 "xedsqR+IB+oKrzIDDWMgoJybN4pkZ8E5lzhVQIjFjKgFdWLzzqyW9z1gYfABQPlN\n"
1302 "FiS20WX0vgP1vcKAjdNrHzc9zyHBpgQzDmAj3NZZAoGBAI8vKCKdH7w3aL5CNkZQ\n"
1303 "2buIeWNA2HZazVwAGG5F2TU/LmXfRKnG6dX5bkU+AkBZh56jNZy//hfFSewJB4Kk\n"
1304 "buB7ERSdaNbO21zXt9FEA3+z0RfMd/Zv2vlIWOSB5nzl/7UKti3sribK6s9ZVLfi\n"
1305 "SxpiPQ8d/hmSGwn4ksrWUsJD\n"
1306 "-----END PRIVATE KEY-----\n";
1307 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1308 return bssl::UniquePtr<EVP_PKEY>(
1309 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1310}
1311
David Benjaminc79ae7a2017-08-29 16:09:44 -04001312// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
1313// before configuring as a server.
1314TEST(SSLTest, ClientCAList) {
1315 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1316 ASSERT_TRUE(ctx);
1317 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1318 ASSERT_TRUE(ssl);
1319
1320 bssl::UniquePtr<X509_NAME> name(X509_NAME_new());
1321 ASSERT_TRUE(name);
1322
1323 bssl::UniquePtr<X509_NAME> name_dup(X509_NAME_dup(name.get()));
1324 ASSERT_TRUE(name_dup);
1325
1326 bssl::UniquePtr<STACK_OF(X509_NAME)> stack(sk_X509_NAME_new_null());
1327 ASSERT_TRUE(stack);
1328
1329 ASSERT_TRUE(sk_X509_NAME_push(stack.get(), name_dup.get()));
1330 name_dup.release();
1331
1332 // |SSL_set_client_CA_list| takes ownership.
1333 SSL_set_client_CA_list(ssl.get(), stack.release());
1334
1335 STACK_OF(X509_NAME) *result = SSL_get_client_CA_list(ssl.get());
1336 ASSERT_TRUE(result);
1337 ASSERT_EQ(1u, sk_X509_NAME_num(result));
1338 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(result, 0), name.get()));
1339}
1340
1341TEST(SSLTest, AddClientCA) {
1342 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1343 ASSERT_TRUE(ctx);
1344 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1345 ASSERT_TRUE(ssl);
1346
1347 bssl::UniquePtr<X509> cert1 = GetTestCertificate();
1348 bssl::UniquePtr<X509> cert2 = GetChainTestCertificate();
1349 ASSERT_TRUE(cert1 && cert2);
1350 X509_NAME *name1 = X509_get_subject_name(cert1.get());
1351 X509_NAME *name2 = X509_get_subject_name(cert2.get());
1352
1353 EXPECT_EQ(0u, sk_X509_NAME_num(SSL_get_client_CA_list(ssl.get())));
1354
1355 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1356 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert2.get()));
1357
1358 STACK_OF(X509_NAME) *list = SSL_get_client_CA_list(ssl.get());
1359 ASSERT_EQ(2u, sk_X509_NAME_num(list));
1360 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1361 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1362
1363 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1364
1365 list = SSL_get_client_CA_list(ssl.get());
1366 ASSERT_EQ(3u, sk_X509_NAME_num(list));
1367 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1368 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1369 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 2), name1));
1370}
1371
1372static void AppendSession(SSL_SESSION *session, void *arg) {
1373 std::vector<SSL_SESSION*> *out =
1374 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
1375 out->push_back(session);
1376}
1377
1378// CacheEquals returns true if |ctx|'s session cache consists of |expected|, in
1379// order.
1380static bool CacheEquals(SSL_CTX *ctx,
1381 const std::vector<SSL_SESSION*> &expected) {
1382 // Check the linked list.
1383 SSL_SESSION *ptr = ctx->session_cache_head;
1384 for (SSL_SESSION *session : expected) {
1385 if (ptr != session) {
1386 return false;
1387 }
1388 // TODO(davidben): This is an absurd way to denote the end of the list.
1389 if (ptr->next ==
1390 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
1391 ptr = nullptr;
1392 } else {
1393 ptr = ptr->next;
1394 }
1395 }
1396 if (ptr != nullptr) {
1397 return false;
1398 }
1399
1400 // Check the hash table.
1401 std::vector<SSL_SESSION*> actual, expected_copy;
1402 lh_SSL_SESSION_doall_arg(SSL_CTX_sessions(ctx), AppendSession, &actual);
1403 expected_copy = expected;
1404
1405 std::sort(actual.begin(), actual.end());
1406 std::sort(expected_copy.begin(), expected_copy.end());
1407
1408 return actual == expected_copy;
1409}
1410
1411static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
1412 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
1413 if (!ssl_ctx) {
1414 return nullptr;
1415 }
1416 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new(ssl_ctx.get()));
1417 if (!ret) {
1418 return nullptr;
1419 }
1420
1421 ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
1422 OPENSSL_memset(ret->session_id, 0, ret->session_id_length);
1423 OPENSSL_memcpy(ret->session_id, &number, sizeof(number));
1424 return ret;
1425}
1426
1427// Test that the internal session cache behaves as expected.
1428TEST(SSLTest, InternalSessionCache) {
1429 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1430 ASSERT_TRUE(ctx);
1431
1432 // Prepare 10 test sessions.
1433 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
1434 for (int i = 0; i < 10; i++) {
1435 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
1436 ASSERT_TRUE(session);
1437 sessions.push_back(std::move(session));
1438 }
1439
1440 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1441
1442 // Insert all the test sessions.
1443 for (const auto &session : sessions) {
1444 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), session.get()));
1445 }
1446
1447 // Only the last five should be in the list.
1448 ASSERT_TRUE(CacheEquals(
1449 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
1450 sessions[6].get(), sessions[5].get()}));
1451
1452 // Inserting an element already in the cache should fail and leave the cache
1453 // unchanged.
1454 ASSERT_FALSE(SSL_CTX_add_session(ctx.get(), sessions[7].get()));
1455 ASSERT_TRUE(CacheEquals(
1456 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
1457 sessions[6].get(), sessions[5].get()}));
1458
1459 // Although collisions should be impossible (256-bit session IDs), the cache
1460 // must handle them gracefully.
1461 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
1462 ASSERT_TRUE(collision);
1463 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), collision.get()));
1464 ASSERT_TRUE(CacheEquals(
1465 ctx.get(), {collision.get(), sessions[9].get(), sessions[8].get(),
1466 sessions[6].get(), sessions[5].get()}));
1467
1468 // Removing sessions behaves correctly.
1469 ASSERT_TRUE(SSL_CTX_remove_session(ctx.get(), sessions[6].get()));
1470 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
1471 sessions[8].get(), sessions[5].get()}));
1472
1473 // Removing sessions requires an exact match.
1474 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[0].get()));
1475 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[7].get()));
1476
1477 // The cache remains unchanged.
1478 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
1479 sessions[8].get(), sessions[5].get()}));
1480}
1481
1482static uint16_t EpochFromSequence(uint64_t seq) {
1483 return static_cast<uint16_t>(seq >> 48);
1484}
1485
David Benjamin71dfad42017-07-16 17:27:39 -04001486static const uint8_t kTestName[] = {
1487 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
1488 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
1489 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
1490 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
1491 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
1492 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64,
1493};
1494
David Benjaminb79cc842016-12-07 15:57:14 -05001495static bool CompleteHandshakes(SSL *client, SSL *server) {
1496 // Drive both their handshakes to completion.
1497 for (;;) {
1498 int client_ret = SSL_do_handshake(client);
1499 int client_err = SSL_get_error(client, client_ret);
1500 if (client_err != SSL_ERROR_NONE &&
1501 client_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001502 client_err != SSL_ERROR_WANT_WRITE &&
1503 client_err != SSL_ERROR_PENDING_TICKET) {
David Benjaminb79cc842016-12-07 15:57:14 -05001504 fprintf(stderr, "Client error: %d\n", client_err);
1505 return false;
1506 }
1507
1508 int server_ret = SSL_do_handshake(server);
1509 int server_err = SSL_get_error(server, server_ret);
1510 if (server_err != SSL_ERROR_NONE &&
1511 server_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001512 server_err != SSL_ERROR_WANT_WRITE &&
1513 server_err != SSL_ERROR_PENDING_TICKET) {
David Benjaminb79cc842016-12-07 15:57:14 -05001514 fprintf(stderr, "Server error: %d\n", server_err);
1515 return false;
1516 }
1517
1518 if (client_ret == 1 && server_ret == 1) {
1519 break;
1520 }
1521 }
1522
1523 return true;
1524}
1525
David Benjamina8614602017-09-06 15:40:19 -04001526struct ClientConfig {
1527 SSL_SESSION *session = nullptr;
1528 std::string servername;
1529};
1530
David Benjaminb79cc842016-12-07 15:57:14 -05001531static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client,
1532 bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001533 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
David Benjamina8614602017-09-06 15:40:19 -04001534 const ClientConfig &config = ClientConfig()) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001535 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001536 if (!client || !server) {
1537 return false;
1538 }
1539 SSL_set_connect_state(client.get());
1540 SSL_set_accept_state(server.get());
1541
David Benjamina8614602017-09-06 15:40:19 -04001542 if (config.session) {
1543 SSL_set_session(client.get(), config.session);
1544 }
1545 if (!config.servername.empty() &&
1546 !SSL_set_tlsext_host_name(client.get(), config.servername.c_str())) {
1547 return false;
1548 }
David Benjamina20e5352016-08-02 19:09:41 -04001549
David Benjaminde942382016-02-11 12:02:01 -05001550 BIO *bio1, *bio2;
1551 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1552 return false;
1553 }
1554 // SSL_set_bio takes ownership.
1555 SSL_set_bio(client.get(), bio1, bio1);
1556 SSL_set_bio(server.get(), bio2, bio2);
1557
David Benjaminb79cc842016-12-07 15:57:14 -05001558 if (!CompleteHandshakes(client.get(), server.get())) {
1559 return false;
David Benjaminde942382016-02-11 12:02:01 -05001560 }
1561
David Benjamin686bb192016-05-10 15:15:41 -04001562 *out_client = std::move(client);
1563 *out_server = std::move(server);
1564 return true;
1565}
1566
David Benjaminc11ea9422017-08-29 16:33:21 -04001567// SSLVersionTest executes its test cases under all available protocol versions.
1568// Test cases call |Connect| to create a connection using context objects with
1569// the protocol version fixed to the current version under test.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001570class SSLVersionTest : public ::testing::TestWithParam<VersionParam> {
1571 protected:
1572 SSLVersionTest() : cert_(GetTestCertificate()), key_(GetTestKey()) {}
1573
1574 void SetUp() { ResetContexts(); }
1575
1576 bssl::UniquePtr<SSL_CTX> CreateContext() const {
1577 const SSL_METHOD *method = is_dtls() ? DTLS_method() : TLS_method();
1578 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
1579 if (!ctx || !SSL_CTX_set_min_proto_version(ctx.get(), version()) ||
1580 !SSL_CTX_set_max_proto_version(ctx.get(), version())) {
1581 return nullptr;
1582 }
1583 return ctx;
David Benjamin0fef3052016-11-18 15:11:10 +09001584 }
David Benjamin686bb192016-05-10 15:15:41 -04001585
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001586 void ResetContexts() {
1587 ASSERT_TRUE(cert_);
1588 ASSERT_TRUE(key_);
1589 client_ctx_ = CreateContext();
1590 ASSERT_TRUE(client_ctx_);
1591 server_ctx_ = CreateContext();
1592 ASSERT_TRUE(server_ctx_);
1593 // Set up a server cert. Client certs can be set up explicitly.
1594 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09001595 }
David Benjamin686bb192016-05-10 15:15:41 -04001596
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001597 bool UseCertAndKey(SSL_CTX *ctx) const {
1598 return SSL_CTX_use_certificate(ctx, cert_.get()) &&
1599 SSL_CTX_use_PrivateKey(ctx, key_.get());
David Benjamin0fef3052016-11-18 15:11:10 +09001600 }
David Benjamin686bb192016-05-10 15:15:41 -04001601
David Benjamina8614602017-09-06 15:40:19 -04001602 bool Connect(const ClientConfig &config = ClientConfig()) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001603 return ConnectClientAndServer(&client_, &server_, client_ctx_.get(),
David Benjamina8614602017-09-06 15:40:19 -04001604 server_ctx_.get(), config);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001605 }
1606
1607 uint16_t version() const { return GetParam().version; }
1608
1609 bool is_dtls() const {
1610 return GetParam().ssl_method == VersionParam::is_dtls;
1611 }
1612
1613 bssl::UniquePtr<SSL> client_, server_;
1614 bssl::UniquePtr<SSL_CTX> server_ctx_, client_ctx_;
1615 bssl::UniquePtr<X509> cert_;
1616 bssl::UniquePtr<EVP_PKEY> key_;
1617};
1618
1619INSTANTIATE_TEST_CASE_P(WithVersion, SSLVersionTest,
1620 testing::ValuesIn(kAllVersions),
1621 [](const testing::TestParamInfo<VersionParam> &i) {
1622 return i.param.name;
1623 });
1624
1625TEST_P(SSLVersionTest, SequenceNumber) {
1626 ASSERT_TRUE(Connect());
1627
David Benjamin0fef3052016-11-18 15:11:10 +09001628 // Drain any post-handshake messages to ensure there are no unread records
1629 // on either end.
1630 uint8_t byte = 0;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001631 ASSERT_LE(SSL_read(client_.get(), &byte, 1), 0);
1632 ASSERT_LE(SSL_read(server_.get(), &byte, 1), 0);
David Benjaminde942382016-02-11 12:02:01 -05001633
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001634 uint64_t client_read_seq = SSL_get_read_sequence(client_.get());
1635 uint64_t client_write_seq = SSL_get_write_sequence(client_.get());
1636 uint64_t server_read_seq = SSL_get_read_sequence(server_.get());
1637 uint64_t server_write_seq = SSL_get_write_sequence(server_.get());
Steven Valdez2c62fe92016-10-14 12:08:12 -04001638
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001639 if (is_dtls()) {
David Benjamin0fef3052016-11-18 15:11:10 +09001640 // Both client and server must be at epoch 1.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001641 EXPECT_EQ(EpochFromSequence(client_read_seq), 1);
1642 EXPECT_EQ(EpochFromSequence(client_write_seq), 1);
1643 EXPECT_EQ(EpochFromSequence(server_read_seq), 1);
1644 EXPECT_EQ(EpochFromSequence(server_write_seq), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09001645
1646 // The next record to be written should exceed the largest received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001647 EXPECT_GT(client_write_seq, server_read_seq);
1648 EXPECT_GT(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09001649 } else {
1650 // The next record to be written should equal the next to be received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001651 EXPECT_EQ(client_write_seq, server_read_seq);
1652 EXPECT_EQ(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09001653 }
1654
1655 // Send a record from client to server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001656 EXPECT_EQ(SSL_write(client_.get(), &byte, 1), 1);
1657 EXPECT_EQ(SSL_read(server_.get(), &byte, 1), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09001658
1659 // The client write and server read sequence numbers should have
1660 // incremented.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001661 EXPECT_EQ(client_write_seq + 1, SSL_get_write_sequence(client_.get()));
1662 EXPECT_EQ(server_read_seq + 1, SSL_get_read_sequence(server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05001663}
1664
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001665TEST_P(SSLVersionTest, OneSidedShutdown) {
David Benjamin68f37b72016-11-18 15:14:42 +09001666 // SSL_shutdown is a no-op in DTLS.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001667 if (is_dtls()) {
1668 return;
David Benjamin686bb192016-05-10 15:15:41 -04001669 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001670 ASSERT_TRUE(Connect());
David Benjamin686bb192016-05-10 15:15:41 -04001671
1672 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1673 // one side has shut down.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001674 ASSERT_EQ(SSL_shutdown(client_.get()), 0);
David Benjamin686bb192016-05-10 15:15:41 -04001675
1676 // Reading from the server should consume the EOF.
1677 uint8_t byte;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001678 ASSERT_EQ(SSL_read(server_.get(), &byte, 1), 0);
1679 ASSERT_EQ(SSL_get_error(server_.get(), 0), SSL_ERROR_ZERO_RETURN);
David Benjamin686bb192016-05-10 15:15:41 -04001680
1681 // However, the server may continue to write data and then shut down the
1682 // connection.
1683 byte = 42;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001684 ASSERT_EQ(SSL_write(server_.get(), &byte, 1), 1);
1685 ASSERT_EQ(SSL_read(client_.get(), &byte, 1), 1);
1686 ASSERT_EQ(byte, 42);
David Benjamin686bb192016-05-10 15:15:41 -04001687
1688 // The server may then shutdown the connection.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001689 EXPECT_EQ(SSL_shutdown(server_.get()), 1);
1690 EXPECT_EQ(SSL_shutdown(client_.get()), 1);
David Benjamin686bb192016-05-10 15:15:41 -04001691}
David Benjamin68f37b72016-11-18 15:14:42 +09001692
David Benjaminf0d8e222017-02-04 10:58:26 -05001693TEST(SSLTest, SessionDuplication) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001694 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1695 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001696 ASSERT_TRUE(client_ctx);
1697 ASSERT_TRUE(server_ctx);
Steven Valdez87eab492016-06-27 16:34:59 -04001698
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001699 bssl::UniquePtr<X509> cert = GetTestCertificate();
1700 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminf0d8e222017-02-04 10:58:26 -05001701 ASSERT_TRUE(cert);
1702 ASSERT_TRUE(key);
1703 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
1704 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04001705
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001706 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05001707 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04001708 server_ctx.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04001709
1710 SSL_SESSION *session0 = SSL_get_session(client.get());
David Benjamin31b0c9b2017-07-20 14:49:15 -04001711 bssl::UniquePtr<SSL_SESSION> session1 =
1712 bssl::SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL);
David Benjaminf0d8e222017-02-04 10:58:26 -05001713 ASSERT_TRUE(session1);
David Benjamin4501bd52016-08-01 13:39:41 -04001714
Steven Valdez84b5c002016-08-25 16:30:58 -04001715 session1->not_resumable = 0;
1716
Steven Valdez87eab492016-06-27 16:34:59 -04001717 uint8_t *s0_bytes, *s1_bytes;
1718 size_t s0_len, s1_len;
1719
David Benjaminf0d8e222017-02-04 10:58:26 -05001720 ASSERT_TRUE(SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001721 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001722
David Benjaminf0d8e222017-02-04 10:58:26 -05001723 ASSERT_TRUE(SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001724 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001725
David Benjamin7d7554b2017-02-04 11:48:59 -05001726 EXPECT_EQ(Bytes(s0_bytes, s0_len), Bytes(s1_bytes, s1_len));
Steven Valdez87eab492016-06-27 16:34:59 -04001727}
David Benjamin686bb192016-05-10 15:15:41 -04001728
David Benjaminf0d8e222017-02-04 10:58:26 -05001729static void ExpectFDs(const SSL *ssl, int rfd, int wfd) {
David Benjaminca743582017-06-15 17:51:35 -04001730 EXPECT_EQ(rfd, SSL_get_fd(ssl));
David Benjaminf0d8e222017-02-04 10:58:26 -05001731 EXPECT_EQ(rfd, SSL_get_rfd(ssl));
1732 EXPECT_EQ(wfd, SSL_get_wfd(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04001733
1734 // The wrapper BIOs are always equal when fds are equal, even if set
1735 // individually.
David Benjaminf0d8e222017-02-04 10:58:26 -05001736 if (rfd == wfd) {
1737 EXPECT_EQ(SSL_get_rbio(ssl), SSL_get_wbio(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04001738 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001739}
1740
David Benjaminf0d8e222017-02-04 10:58:26 -05001741TEST(SSLTest, SetFD) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001742 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001743 ASSERT_TRUE(ctx);
David Benjamin5c0fb882016-06-14 14:03:51 -04001744
1745 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001746 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001747 ASSERT_TRUE(ssl);
1748 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1749 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
1750 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04001751
1752 // Test setting the same FD.
1753 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001754 ASSERT_TRUE(ssl);
1755 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1756 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001757
1758 // Test setting the same FD one side at a time.
1759 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001760 ASSERT_TRUE(ssl);
1761 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1762 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1763 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001764
1765 // Test setting the same FD in the other order.
1766 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001767 ASSERT_TRUE(ssl);
1768 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1769 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1770 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001771
David Benjamin5c0fb882016-06-14 14:03:51 -04001772 // Test changing the read FD partway through.
1773 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001774 ASSERT_TRUE(ssl);
1775 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1776 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 2));
1777 ExpectFDs(ssl.get(), 2, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001778
1779 // Test changing the write FD partway through.
1780 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001781 ASSERT_TRUE(ssl);
1782 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1783 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
1784 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04001785
1786 // Test a no-op change to the read FD partway through.
1787 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001788 ASSERT_TRUE(ssl);
1789 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1790 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1791 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001792
1793 // Test a no-op change to the write FD partway through.
1794 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001795 ASSERT_TRUE(ssl);
1796 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1797 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1798 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001799
1800 // ASan builds will implicitly test that the internal |BIO| reference-counting
1801 // is correct.
David Benjamin5c0fb882016-06-14 14:03:51 -04001802}
1803
David Benjaminf0d8e222017-02-04 10:58:26 -05001804TEST(SSLTest, SetBIO) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001805 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001806 ASSERT_TRUE(ctx);
David Benjamin4501bd52016-08-01 13:39:41 -04001807
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001808 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1809 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04001810 bio3(BIO_new(BIO_s_mem()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001811 ASSERT_TRUE(ssl);
1812 ASSERT_TRUE(bio1);
1813 ASSERT_TRUE(bio2);
1814 ASSERT_TRUE(bio3);
David Benjamin4501bd52016-08-01 13:39:41 -04001815
1816 // SSL_set_bio takes one reference when the parameters are the same.
1817 BIO_up_ref(bio1.get());
1818 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1819
1820 // Repeating the call does nothing.
1821 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1822
1823 // It takes one reference each when the parameters are different.
1824 BIO_up_ref(bio2.get());
1825 BIO_up_ref(bio3.get());
1826 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1827
1828 // Repeating the call does nothing.
1829 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1830
1831 // It takes one reference when changing only wbio.
1832 BIO_up_ref(bio1.get());
1833 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1834
1835 // It takes one reference when changing only rbio and the two are different.
1836 BIO_up_ref(bio3.get());
1837 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1838
1839 // If setting wbio to rbio, it takes no additional references.
1840 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1841
1842 // From there, wbio may be switched to something else.
1843 BIO_up_ref(bio1.get());
1844 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1845
1846 // If setting rbio to wbio, it takes no additional references.
1847 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1848
1849 // From there, rbio may be switched to something else, but, for historical
1850 // reasons, it takes a reference to both parameters.
1851 BIO_up_ref(bio1.get());
1852 BIO_up_ref(bio2.get());
1853 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1854
1855 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1856 // is correct.
David Benjamin4501bd52016-08-01 13:39:41 -04001857}
1858
David Benjamin25490f22016-07-14 00:22:54 -04001859static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1860
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001861TEST_P(SSLVersionTest, GetPeerCertificate) {
1862 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04001863
David Benjamin0fef3052016-11-18 15:11:10 +09001864 // Configure both client and server to accept any certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001865 SSL_CTX_set_verify(client_ctx_.get(),
1866 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1867 nullptr);
1868 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
1869 SSL_CTX_set_verify(server_ctx_.get(),
1870 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1871 nullptr);
1872 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjaminadd5e522016-07-14 00:33:24 -04001873
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001874 ASSERT_TRUE(Connect());
David Benjaminadd5e522016-07-14 00:33:24 -04001875
David Benjamin0fef3052016-11-18 15:11:10 +09001876 // Client and server should both see the leaf certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001877 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1878 ASSERT_TRUE(peer);
1879 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04001880
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001881 peer.reset(SSL_get_peer_certificate(client_.get()));
1882 ASSERT_TRUE(peer);
1883 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04001884
David Benjamine664a532017-07-20 20:19:36 -04001885 // However, for historical reasons, the X509 chain includes the leaf on the
David Benjamin0fef3052016-11-18 15:11:10 +09001886 // client, but does not on the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001887 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(client_.get())), 1u);
1888 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(client_.get())),
1889 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04001890
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001891 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(server_.get())), 0u);
1892 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(server_.get())),
1893 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04001894}
1895
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001896TEST_P(SSLVersionTest, NoPeerCertificate) {
1897 SSL_CTX_set_verify(server_ctx_.get(), SSL_VERIFY_PEER, nullptr);
1898 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
1899 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
David Benjamine664a532017-07-20 20:19:36 -04001900
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001901 ASSERT_TRUE(Connect());
David Benjamine664a532017-07-20 20:19:36 -04001902
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001903 // Server should not see a peer certificate.
1904 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1905 ASSERT_FALSE(peer);
1906 ASSERT_FALSE(SSL_get0_peer_certificates(server_.get()));
David Benjamine664a532017-07-20 20:19:36 -04001907}
1908
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001909TEST_P(SSLVersionTest, RetainOnlySHA256OfCerts) {
David Benjamin25490f22016-07-14 00:22:54 -04001910 uint8_t *cert_der = NULL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001911 int cert_der_len = i2d_X509(cert_.get(), &cert_der);
1912 ASSERT_GE(cert_der_len, 0);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001913 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04001914
1915 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1916 SHA256(cert_der, cert_der_len, cert_sha256);
1917
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001918 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
1919
David Benjamin0fef3052016-11-18 15:11:10 +09001920 // Configure both client and server to accept any certificate, but the
1921 // server must retain only the SHA-256 of the peer.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001922 SSL_CTX_set_verify(client_ctx_.get(),
1923 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1924 nullptr);
1925 SSL_CTX_set_verify(server_ctx_.get(),
1926 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1927 nullptr);
1928 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
1929 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
1930 SSL_CTX_set_retain_only_sha256_of_client_certs(server_ctx_.get(), 1);
David Benjamin25490f22016-07-14 00:22:54 -04001931
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001932 ASSERT_TRUE(Connect());
David Benjamin25490f22016-07-14 00:22:54 -04001933
David Benjamin0fef3052016-11-18 15:11:10 +09001934 // The peer certificate has been dropped.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001935 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1936 EXPECT_FALSE(peer);
David Benjamin25490f22016-07-14 00:22:54 -04001937
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001938 SSL_SESSION *session = SSL_get_session(server_.get());
1939 EXPECT_TRUE(session->peer_sha256_valid);
David Benjamin25490f22016-07-14 00:22:54 -04001940
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001941 EXPECT_EQ(Bytes(cert_sha256), Bytes(session->peer_sha256));
David Benjamin25490f22016-07-14 00:22:54 -04001942}
1943
David Benjaminafc64de2016-07-19 17:12:41 +02001944static bool ClientHelloMatches(uint16_t version, const uint8_t *expected,
1945 size_t expected_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001946 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001947 // Our default cipher list varies by CPU capabilities, so manually place the
1948 // ChaCha20 ciphers in front.
Matthew Braithwaite7e06de52017-04-10 15:52:14 -07001949 const char* cipher_list = "CHACHA20:ALL";
David Benjamin2dc02042016-09-19 19:57:37 -04001950 if (!ctx ||
David Benjamin3cfeb952017-03-01 16:48:38 -05001951 // SSLv3 is off by default.
1952 !SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION) ||
David Benjamine4706902016-09-20 15:12:23 -04001953 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001954 !SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list)) {
David Benjaminafc64de2016-07-19 17:12:41 +02001955 return false;
1956 }
David Benjamin2dc02042016-09-19 19:57:37 -04001957
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001958 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +02001959 if (!ssl) {
1960 return false;
1961 }
1962 std::vector<uint8_t> client_hello;
1963 if (!GetClientHello(ssl.get(), &client_hello)) {
1964 return false;
1965 }
1966
1967 // Zero the client_random.
1968 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
1969 1 + 3 + // handshake message header
1970 2; // client_version
1971 if (client_hello.size() < kRandomOffset + SSL3_RANDOM_SIZE) {
1972 fprintf(stderr, "ClientHello for version %04x too short.\n", version);
1973 return false;
1974 }
David Benjamin17cf2cb2016-12-13 01:07:13 -05001975 OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
David Benjaminafc64de2016-07-19 17:12:41 +02001976
1977 if (client_hello.size() != expected_len ||
David Benjamin17cf2cb2016-12-13 01:07:13 -05001978 OPENSSL_memcmp(client_hello.data(), expected, expected_len) != 0) {
David Benjaminafc64de2016-07-19 17:12:41 +02001979 fprintf(stderr, "ClientHello for version %04x did not match:\n", version);
1980 fprintf(stderr, "Got:\n\t");
1981 for (size_t i = 0; i < client_hello.size(); i++) {
1982 fprintf(stderr, "0x%02x, ", client_hello[i]);
1983 }
1984 fprintf(stderr, "\nWanted:\n\t");
1985 for (size_t i = 0; i < expected_len; i++) {
1986 fprintf(stderr, "0x%02x, ", expected[i]);
1987 }
1988 fprintf(stderr, "\n");
1989 return false;
1990 }
1991
1992 return true;
1993}
1994
1995// Tests that our ClientHellos do not change unexpectedly.
1996static bool TestClientHello() {
1997 static const uint8_t kSSL3ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001998 0x16,
1999 0x03, 0x00,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07002000 0x00, 0x3b,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002001 0x01,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07002002 0x00, 0x00, 0x37,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002003 0x03, 0x00,
2004 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2005 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2006 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2007 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2008 0x00,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07002009 0x00, 0x10,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002010 0xc0, 0x09,
2011 0xc0, 0x13,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002012 0xc0, 0x0a,
2013 0xc0, 0x14,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002014 0x00, 0x2f,
2015 0x00, 0x35,
2016 0x00, 0x0a,
2017 0x00, 0xff, 0x01, 0x00,
David Benjaminafc64de2016-07-19 17:12:41 +02002018 };
2019 if (!ClientHelloMatches(SSL3_VERSION, kSSL3ClientHello,
2020 sizeof(kSSL3ClientHello))) {
2021 return false;
2022 }
2023
2024 static const uint8_t kTLS1ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002025 0x16,
2026 0x03, 0x01,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07002027 0x00, 0x5a,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002028 0x01,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07002029 0x00, 0x00, 0x56,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002030 0x03, 0x01,
2031 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2032 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2033 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2034 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2035 0x00,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07002036 0x00, 0x0e,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002037 0xc0, 0x09,
2038 0xc0, 0x13,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002039 0xc0, 0x0a,
2040 0xc0, 0x14,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002041 0x00, 0x2f,
2042 0x00, 0x35,
2043 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02002044 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
2045 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
2046 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
2047 };
2048 if (!ClientHelloMatches(TLS1_VERSION, kTLS1ClientHello,
2049 sizeof(kTLS1ClientHello))) {
2050 return false;
2051 }
2052
2053 static const uint8_t kTLS11ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002054 0x16,
2055 0x03, 0x01,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07002056 0x00, 0x5a,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002057 0x01,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07002058 0x00, 0x00, 0x56,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002059 0x03, 0x02,
2060 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2061 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2062 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2063 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2064 0x00,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07002065 0x00, 0x0e,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002066 0xc0, 0x09,
2067 0xc0, 0x13,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002068 0xc0, 0x0a,
2069 0xc0, 0x14,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07002070 0x00, 0x2f,
2071 0x00, 0x35,
2072 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02002073 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
2074 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
2075 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
2076 };
2077 if (!ClientHelloMatches(TLS1_1_VERSION, kTLS11ClientHello,
2078 sizeof(kTLS11ClientHello))) {
2079 return false;
2080 }
2081
David Benjamin3b584332017-01-24 22:47:18 -05002082 // kTLS12ClientHello assumes RSA-PSS, which is disabled for Android system
2083 // builds.
2084#if defined(BORINGSSL_ANDROID_SYSTEM)
2085 return true;
2086#endif
2087
David Benjaminafc64de2016-07-19 17:12:41 +02002088 static const uint8_t kTLS12ClientHello[] = {
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07002089 0x16,
2090 0x03, 0x01,
2091 0x00, 0x8e,
2092 0x01,
2093 0x00, 0x00, 0x8a,
2094 0x03, 0x03,
David Benjamin57e929f2016-08-30 00:30:38 -04002095 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2096 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07002097 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2098 0x00, 0x2a,
2099 0xcc, 0xa9,
2100 0xcc, 0xa8,
2101 0xc0, 0x2b,
2102 0xc0, 0x2f,
2103 0xc0, 0x2c,
2104 0xc0, 0x30,
2105 0xc0, 0x09,
2106 0xc0, 0x23,
2107 0xc0, 0x13,
2108 0xc0, 0x27,
2109 0xc0, 0x0a,
2110 0xc0, 0x24,
2111 0xc0, 0x14,
2112 0xc0, 0x28,
2113 0x00, 0x9c,
2114 0x00, 0x9d,
2115 0x00, 0x2f,
2116 0x00, 0x3c,
2117 0x00, 0x35,
2118 0x00, 0x3d,
2119 0x00, 0x0a,
2120 0x01, 0x00, 0x00, 0x37, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
2121 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04,
2122 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08,
2123 0x06, 0x06, 0x01, 0x02, 0x01, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
2124 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
David Benjaminafc64de2016-07-19 17:12:41 +02002125 };
2126 if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
2127 sizeof(kTLS12ClientHello))) {
2128 return false;
2129 }
2130
2131 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
2132 // implementation has settled enough that it won't change.
2133
2134 return true;
2135}
2136
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002137static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04002138
2139static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
2140 // Save the most recent session.
2141 g_last_session.reset(session);
2142 return 1;
2143}
2144
David Benjamina8614602017-09-06 15:40:19 -04002145static bssl::UniquePtr<SSL_SESSION> CreateClientSession(
2146 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2147 const ClientConfig &config = ClientConfig()) {
David Benjamina20e5352016-08-02 19:09:41 -04002148 g_last_session = nullptr;
2149 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2150
2151 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002152 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04002153 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
David Benjamina8614602017-09-06 15:40:19 -04002154 config)) {
David Benjamina20e5352016-08-02 19:09:41 -04002155 fprintf(stderr, "Failed to connect client and server.\n");
2156 return nullptr;
2157 }
2158
2159 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2160 SSL_read(client.get(), nullptr, 0);
2161
2162 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2163
2164 if (!g_last_session) {
2165 fprintf(stderr, "Client did not receive a session.\n");
2166 return nullptr;
2167 }
2168 return std::move(g_last_session);
2169}
2170
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002171static void ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2172 SSL_SESSION *session, bool want_reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002173 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002174 ClientConfig config;
2175 config.session = session;
2176 EXPECT_TRUE(
2177 ConnectClientAndServer(&client, &server, client_ctx, server_ctx, config));
David Benjamina20e5352016-08-02 19:09:41 -04002178
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002179 EXPECT_EQ(SSL_session_reused(client.get()), SSL_session_reused(server.get()));
David Benjamina20e5352016-08-02 19:09:41 -04002180
2181 bool was_reused = !!SSL_session_reused(client.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002182 EXPECT_EQ(was_reused, want_reused);
David Benjamina20e5352016-08-02 19:09:41 -04002183}
2184
David Benjamin3c51d9b2016-11-01 17:50:42 -04002185static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
2186 SSL_CTX *server_ctx,
2187 SSL_SESSION *session) {
2188 g_last_session = nullptr;
2189 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2190
2191 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002192 ClientConfig config;
2193 config.session = session;
2194 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
2195 config)) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002196 fprintf(stderr, "Failed to connect client and server.\n");
2197 return nullptr;
2198 }
2199
2200 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2201 fprintf(stderr, "Client and server were inconsistent.\n");
2202 return nullptr;
2203 }
2204
2205 if (!SSL_session_reused(client.get())) {
2206 fprintf(stderr, "Session was not reused.\n");
2207 return nullptr;
2208 }
2209
2210 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2211 SSL_read(client.get(), nullptr, 0);
2212
2213 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2214
2215 if (!g_last_session) {
2216 fprintf(stderr, "Client did not receive a renewed session.\n");
2217 return nullptr;
2218 }
2219 return std::move(g_last_session);
2220}
2221
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002222static void ExpectTicketKeyChanged(SSL_CTX *ctx, uint8_t *inout_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002223 bool changed) {
2224 uint8_t new_key[kTicketKeyLen];
David Benjaminc11ea9422017-08-29 16:33:21 -04002225 // May return 0, 1 or 48.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002226 ASSERT_EQ(SSL_CTX_get_tlsext_ticket_keys(ctx, new_key, kTicketKeyLen), 1);
2227 if (changed) {
2228 ASSERT_NE(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
2229 } else {
2230 ASSERT_EQ(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002231 }
2232 OPENSSL_memcpy(inout_key, new_key, kTicketKeyLen);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002233}
2234
David Benjamina933c382016-10-28 00:10:03 -04002235static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
2236 static const uint8_t kContext[] = {3};
2237
2238 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
2239 return SSL_TLSEXT_ERR_ALERT_FATAL;
2240 }
2241
2242 return SSL_TLSEXT_ERR_OK;
2243}
2244
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002245TEST_P(SSLVersionTest, SessionIDContext) {
David Benjamina20e5352016-08-02 19:09:41 -04002246 static const uint8_t kContext1[] = {1};
2247 static const uint8_t kContext2[] = {2};
2248
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002249 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2250 sizeof(kContext1)));
David Benjamina20e5352016-08-02 19:09:41 -04002251
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002252 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2253 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002254
David Benjamin0fef3052016-11-18 15:11:10 +09002255 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002256 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2257 ASSERT_TRUE(session);
David Benjamina20e5352016-08-02 19:09:41 -04002258
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002259 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2260 session.get(),
2261 true /* expect session reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002262
David Benjamin0fef3052016-11-18 15:11:10 +09002263 // Change the session ID context.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002264 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext2,
2265 sizeof(kContext2)));
David Benjamina20e5352016-08-02 19:09:41 -04002266
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002267 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2268 session.get(),
2269 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002270
David Benjamin0fef3052016-11-18 15:11:10 +09002271 // Change the session ID context back and install an SNI callback to switch
2272 // it.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002273 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2274 sizeof(kContext1)));
David Benjamina933c382016-10-28 00:10:03 -04002275
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002276 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09002277 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04002278
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002279 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2280 session.get(),
2281 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002282
David Benjamin0fef3052016-11-18 15:11:10 +09002283 // Switch the session ID context with the early callback instead.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002284 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), nullptr);
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002285 SSL_CTX_set_select_certificate_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002286 server_ctx_.get(),
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002287 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
2288 static const uint8_t kContext[] = {3};
2289
2290 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
2291 sizeof(kContext))) {
2292 return ssl_select_cert_error;
2293 }
2294
2295 return ssl_select_cert_success;
2296 });
David Benjamina933c382016-10-28 00:10:03 -04002297
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002298 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2299 session.get(),
2300 false /* expect session not reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002301}
2302
David Benjamin721e8b72016-08-03 13:13:17 -04002303static timeval g_current_time;
2304
2305static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2306 *out_clock = g_current_time;
2307}
2308
David Benjamin17b30832017-01-28 14:00:32 -05002309static void FrozenTimeCallback(const SSL *ssl, timeval *out_clock) {
2310 out_clock->tv_sec = 1000;
2311 out_clock->tv_usec = 0;
2312}
2313
David Benjamin3c51d9b2016-11-01 17:50:42 -04002314static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
2315 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
2316 int encrypt) {
2317 static const uint8_t kZeros[16] = {0};
2318
2319 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -05002320 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamin3c51d9b2016-11-01 17:50:42 -04002321 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -05002322 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002323 return 0;
2324 }
2325
2326 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
2327 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
2328 return -1;
2329 }
2330
2331 // Returning two from the callback in decrypt mode renews the
2332 // session in TLS 1.2 and below.
2333 return encrypt ? 1 : 2;
2334}
2335
David Benjamin123db572016-11-03 16:59:25 -04002336static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjamin123db572016-11-03 16:59:25 -04002337 if (session->tlsext_ticklen < 16 + 16 + SHA256_DIGEST_LENGTH) {
2338 return false;
2339 }
2340
David Benjamin123db572016-11-03 16:59:25 -04002341 const uint8_t *ciphertext = session->tlsext_tick + 16 + 16;
2342 size_t len = session->tlsext_ticklen - 16 - 16 - SHA256_DIGEST_LENGTH;
2343 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
2344
David Benjamin9b63f292016-11-15 00:44:05 -05002345#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
2346 // Fuzzer-mode tickets are unencrypted.
David Benjamin17cf2cb2016-12-13 01:07:13 -05002347 OPENSSL_memcpy(plaintext.get(), ciphertext, len);
David Benjamin9b63f292016-11-15 00:44:05 -05002348#else
2349 static const uint8_t kZeros[16] = {0};
2350 const uint8_t *iv = session->tlsext_tick + 16;
David Benjamin123db572016-11-03 16:59:25 -04002351 bssl::ScopedEVP_CIPHER_CTX ctx;
2352 int len1, len2;
2353 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
2354 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
2355 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
2356 return false;
2357 }
2358
2359 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05002360#endif
David Benjamin123db572016-11-03 16:59:25 -04002361
Adam Langley46db7af2017-02-01 15:49:37 -08002362 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
2363 if (!ssl_ctx) {
2364 return false;
2365 }
David Benjamin123db572016-11-03 16:59:25 -04002366 bssl::UniquePtr<SSL_SESSION> server_session(
Adam Langley46db7af2017-02-01 15:49:37 -08002367 SSL_SESSION_from_bytes(plaintext.get(), len, ssl_ctx.get()));
David Benjamin123db572016-11-03 16:59:25 -04002368 if (!server_session) {
2369 return false;
2370 }
2371
2372 *out = server_session->time;
2373 return true;
2374}
2375
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002376TEST_P(SSLVersionTest, SessionTimeout) {
2377 for (bool server_test : {false, true}) {
2378 SCOPED_TRACE(server_test);
David Benjamin721e8b72016-08-03 13:13:17 -04002379
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002380 ResetContexts();
2381 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2382 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
2383
David Benjamin17b30832017-01-28 14:00:32 -05002384 static const time_t kStartTime = 1000;
David Benjamin0fef3052016-11-18 15:11:10 +09002385 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002386
David Benjamin17b30832017-01-28 14:00:32 -05002387 // We are willing to use a longer lifetime for TLS 1.3 sessions as
2388 // resumptions still perform ECDHE.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002389 const time_t timeout = version() == TLS1_3_VERSION
David Benjamin17b30832017-01-28 14:00:32 -05002390 ? SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT
2391 : SSL_DEFAULT_SESSION_TIMEOUT;
2392
David Benjamin17b30832017-01-28 14:00:32 -05002393 // Both client and server must enforce session timeouts. We configure the
2394 // other side with a frozen clock so it never expires tickets.
David Benjamin0fef3052016-11-18 15:11:10 +09002395 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002396 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2397 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002398 } else {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002399 SSL_CTX_set_current_time_cb(client_ctx_.get(), CurrentTimeCallback);
2400 SSL_CTX_set_current_time_cb(server_ctx_.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002401 }
2402
2403 // Configure a ticket callback which renews tickets.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002404 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002405
2406 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002407 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2408 ASSERT_TRUE(session);
David Benjamin0fef3052016-11-18 15:11:10 +09002409
2410 // Advance the clock just behind the timeout.
David Benjamin17b30832017-01-28 14:00:32 -05002411 g_current_time.tv_sec += timeout - 1;
David Benjamin0fef3052016-11-18 15:11:10 +09002412
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002413 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2414 session.get(),
2415 true /* expect session reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002416
2417 // Advance the clock one more second.
2418 g_current_time.tv_sec++;
2419
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002420 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2421 session.get(),
2422 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002423
2424 // Rewind the clock to before the session was minted.
2425 g_current_time.tv_sec = kStartTime - 1;
2426
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002427 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2428 session.get(),
2429 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002430
2431 // SSL 3.0 cannot renew sessions.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002432 if (version() == SSL3_VERSION) {
David Benjamin0fef3052016-11-18 15:11:10 +09002433 continue;
2434 }
2435
2436 // Renew the session 10 seconds before expiration.
David Benjamin17b30832017-01-28 14:00:32 -05002437 time_t new_start_time = kStartTime + timeout - 10;
2438 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002439 bssl::UniquePtr<SSL_SESSION> new_session = ExpectSessionRenewed(
2440 client_ctx_.get(), server_ctx_.get(), session.get());
2441 ASSERT_TRUE(new_session);
David Benjamin0fef3052016-11-18 15:11:10 +09002442
2443 // This new session is not the same object as before.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002444 EXPECT_NE(session.get(), new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002445
2446 // Check the sessions have timestamps measured from issuance.
2447 long session_time = 0;
2448 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002449 ASSERT_TRUE(GetServerTicketTime(&session_time, new_session.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09002450 } else {
2451 session_time = new_session->time;
2452 }
David Benjamin721e8b72016-08-03 13:13:17 -04002453
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002454 ASSERT_EQ(session_time, g_current_time.tv_sec);
David Benjamin721e8b72016-08-03 13:13:17 -04002455
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002456 if (version() == TLS1_3_VERSION) {
David Benjamin17b30832017-01-28 14:00:32 -05002457 // Renewal incorporates fresh key material in TLS 1.3, so we extend the
2458 // lifetime TLS 1.3.
2459 g_current_time.tv_sec = new_start_time + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002460 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2461 new_session.get(),
2462 true /* expect session reused */));
David Benjamin721e8b72016-08-03 13:13:17 -04002463
David Benjamin17b30832017-01-28 14:00:32 -05002464 // The new session expires after the new timeout.
2465 g_current_time.tv_sec = new_start_time + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002466 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2467 new_session.get(),
2468 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002469
2470 // Renew the session until it begins just past the auth timeout.
2471 time_t auth_end_time = kStartTime + SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
2472 while (new_start_time < auth_end_time - 1000) {
2473 // Get as close as possible to target start time.
2474 new_start_time =
2475 std::min(auth_end_time - 1000, new_start_time + timeout - 1);
2476 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002477 new_session = ExpectSessionRenewed(client_ctx_.get(), server_ctx_.get(),
David Benjamin17b30832017-01-28 14:00:32 -05002478 new_session.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002479 ASSERT_TRUE(new_session);
David Benjamin17b30832017-01-28 14:00:32 -05002480 }
2481
2482 // Now the session's lifetime is bound by the auth timeout.
2483 g_current_time.tv_sec = auth_end_time - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002484 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2485 new_session.get(),
2486 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002487
2488 g_current_time.tv_sec = auth_end_time + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002489 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2490 new_session.get(),
2491 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002492 } else {
2493 // The new session is usable just before the old expiration.
2494 g_current_time.tv_sec = kStartTime + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002495 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2496 new_session.get(),
2497 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002498
2499 // Renewal does not extend the lifetime, so it is not usable beyond the
2500 // old expiration.
2501 g_current_time.tv_sec = kStartTime + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002502 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2503 new_session.get(),
2504 false /* expect session not reused */));
David Benjamin1b22f852016-10-27 16:36:32 -04002505 }
David Benjamin721e8b72016-08-03 13:13:17 -04002506 }
David Benjamin721e8b72016-08-03 13:13:17 -04002507}
2508
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002509TEST_P(SSLVersionTest, DefaultTicketKeyInitialization) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002510 static const uint8_t kZeroKey[kTicketKeyLen] = {};
2511 uint8_t ticket_key[kTicketKeyLen];
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002512 ASSERT_EQ(1, SSL_CTX_get_tlsext_ticket_keys(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002513 kTicketKeyLen));
2514 ASSERT_NE(0, OPENSSL_memcmp(ticket_key, kZeroKey, kTicketKeyLen));
2515}
2516
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002517TEST_P(SSLVersionTest, DefaultTicketKeyRotation) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002518 if (GetParam().version == SSL3_VERSION) {
2519 return;
2520 }
2521
2522 static const time_t kStartTime = 1001;
2523 g_current_time.tv_sec = kStartTime;
2524 uint8_t ticket_key[kTicketKeyLen];
2525
David Benjaminc11ea9422017-08-29 16:33:21 -04002526 // We use session reuse as a proxy for ticket decryption success, hence
2527 // disable session timeouts.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002528 SSL_CTX_set_timeout(server_ctx_.get(), std::numeric_limits<uint32_t>::max());
2529 SSL_CTX_set_session_psk_dhe_timeout(server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002530 std::numeric_limits<uint32_t>::max());
2531
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002532 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2533 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002534
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002535 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2536 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_OFF);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002537
David Benjaminc11ea9422017-08-29 16:33:21 -04002538 // Initialize ticket_key with the current key.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002539 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2540 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002541
David Benjaminc11ea9422017-08-29 16:33:21 -04002542 // Verify ticket resumption actually works.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002543 bssl::UniquePtr<SSL> client, server;
2544 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002545 CreateClientSession(client_ctx_.get(), server_ctx_.get());
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002546 ASSERT_TRUE(session);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002547 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002548 session.get(), true /* reused */));
2549
David Benjaminc11ea9422017-08-29 16:33:21 -04002550 // Advance time to just before key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002551 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL - 1;
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 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.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002558 g_current_time.tv_sec += 1;
2559 bssl::UniquePtr<SSL_SESSION> new_session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002560 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2561 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 // Resumption with both old and new ticket should work.
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 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002567 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002568 new_session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002569 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002570 false /* NOT changed */));
2571
David Benjaminc11ea9422017-08-29 16:33:21 -04002572 // Force key rotation again. Resumption with the old ticket now fails.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002573 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002574 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002575 session.get(), false /* NOT reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002576 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2577 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002578
David Benjaminc11ea9422017-08-29 16:33:21 -04002579 // But resumption with the newer session still works.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002580 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002581 new_session.get(), true /* reused */));
2582}
2583
David Benjamin0fc37ef2016-08-17 15:29:46 -04002584static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002585 SSL_CTX *ctx = reinterpret_cast<SSL_CTX *>(arg);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002586 SSL_set_SSL_CTX(ssl, ctx);
2587 return SSL_TLSEXT_ERR_OK;
2588}
2589
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002590TEST_P(SSLVersionTest, SNICallback) {
David Benjamin0fef3052016-11-18 15:11:10 +09002591 // SSL 3.0 lacks extensions.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002592 if (version() == SSL3_VERSION) {
2593 return;
David Benjamin0fef3052016-11-18 15:11:10 +09002594 }
2595
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002596 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002597 ASSERT_TRUE(cert2);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002598 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002599 ASSERT_TRUE(key2);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002600
David Benjamin0fef3052016-11-18 15:11:10 +09002601 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
2602 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002603
David Benjamin83a32122017-02-14 18:34:54 -05002604 static const uint8_t kSCTList[] = {0, 6, 0, 4, 5, 6, 7, 8};
2605 static const uint8_t kOCSPResponse[] = {1, 2, 3, 4};
2606
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002607 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
2608 ASSERT_TRUE(server_ctx2);
2609 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()));
2610 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()));
2611 ASSERT_TRUE(SSL_CTX_set_signed_cert_timestamp_list(
2612 server_ctx2.get(), kSCTList, sizeof(kSCTList)));
2613 ASSERT_TRUE(SSL_CTX_set_ocsp_response(server_ctx2.get(), kOCSPResponse,
2614 sizeof(kOCSPResponse)));
2615 // Historically signing preferences would be lost in some cases with the
2616 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2617 // this doesn't happen when |version| is TLS 1.2, configure the private
2618 // key to only sign SHA-256.
2619 ASSERT_TRUE(SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
2620 &kECDSAWithSHA256, 1));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002621
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002622 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), SwitchContext);
2623 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002624
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002625 SSL_CTX_enable_signed_cert_timestamps(client_ctx_.get());
2626 SSL_CTX_enable_ocsp_stapling(client_ctx_.get());
David Benjamin83a32122017-02-14 18:34:54 -05002627
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002628 ASSERT_TRUE(Connect());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002629
David Benjamin0fef3052016-11-18 15:11:10 +09002630 // The client should have received |cert2|.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002631 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client_.get()));
2632 ASSERT_TRUE(peer);
2633 EXPECT_EQ(X509_cmp(peer.get(), cert2.get()), 0);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002634
David Benjamin83a32122017-02-14 18:34:54 -05002635 // The client should have received |server_ctx2|'s SCT list.
2636 const uint8_t *data;
2637 size_t len;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002638 SSL_get0_signed_cert_timestamp_list(client_.get(), &data, &len);
2639 EXPECT_EQ(Bytes(kSCTList), Bytes(data, len));
David Benjamin83a32122017-02-14 18:34:54 -05002640
2641 // The client should have received |server_ctx2|'s OCSP response.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002642 SSL_get0_ocsp_response(client_.get(), &data, &len);
2643 EXPECT_EQ(Bytes(kOCSPResponse), Bytes(data, len));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002644}
2645
David Benjaminf0d8e222017-02-04 10:58:26 -05002646// Test that the early callback can swap the maximum version.
2647TEST(SSLTest, EarlyCallbackVersionSwitch) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002648 bssl::UniquePtr<X509> cert = GetTestCertificate();
2649 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2650 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2651 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002652 ASSERT_TRUE(cert);
2653 ASSERT_TRUE(key);
2654 ASSERT_TRUE(server_ctx);
2655 ASSERT_TRUE(client_ctx);
2656 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
2657 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
2658 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
2659 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
David Benjamin99620572016-08-30 00:35:36 -04002660
David Benjaminf0d8e222017-02-04 10:58:26 -05002661 SSL_CTX_set_select_certificate_cb(
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002662 server_ctx.get(),
2663 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
David Benjaminf0d8e222017-02-04 10:58:26 -05002664 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002665 return ssl_select_cert_error;
David Benjaminf0d8e222017-02-04 10:58:26 -05002666 }
2667
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002668 return ssl_select_cert_success;
David Benjaminf0d8e222017-02-04 10:58:26 -05002669 });
David Benjamin99620572016-08-30 00:35:36 -04002670
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002671 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05002672 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04002673 server_ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002674 EXPECT_EQ(TLS1_2_VERSION, SSL_version(client.get()));
David Benjamin99620572016-08-30 00:35:36 -04002675}
2676
David Benjaminf0d8e222017-02-04 10:58:26 -05002677TEST(SSLTest, SetVersion) {
David Benjamin2dc02042016-09-19 19:57:37 -04002678 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002679 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002680
David Benjaminf0d8e222017-02-04 10:58:26 -05002681 // Set valid TLS versions.
2682 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2683 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
2684 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2685 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002686
David Benjaminf0d8e222017-02-04 10:58:26 -05002687 // Invalid TLS versions are rejected.
2688 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2689 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x0200));
2690 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2691 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2692 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x0200));
2693 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002694
David Benjaminf0d8e222017-02-04 10:58:26 -05002695 // Zero is the default version.
2696 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002697 EXPECT_EQ(TLS1_2_VERSION, ctx->conf_max_version);
David Benjaminf0d8e222017-02-04 10:58:26 -05002698 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002699 EXPECT_EQ(TLS1_VERSION, ctx->conf_min_version);
David Benjamin3cfeb952017-03-01 16:48:38 -05002700
2701 // SSL 3.0 and TLS 1.3 are available, but not by default.
2702 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002703 EXPECT_EQ(SSL3_VERSION, ctx->conf_min_version);
David Benjamin3cfeb952017-03-01 16:48:38 -05002704 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002705 EXPECT_EQ(TLS1_3_VERSION, ctx->conf_max_version);
David Benjamine34bcc92016-09-21 16:53:09 -04002706
David Benjamin353577c2017-06-29 15:54:58 -04002707 // TLS1_3_DRAFT_VERSION is not an API-level version.
2708 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_DRAFT_VERSION));
2709 ERR_clear_error();
2710
David Benjamin2dc02042016-09-19 19:57:37 -04002711 ctx.reset(SSL_CTX_new(DTLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002712 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002713
David Benjaminf0d8e222017-02-04 10:58:26 -05002714 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2715 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION));
2716 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2717 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002718
David Benjaminf0d8e222017-02-04 10:58:26 -05002719 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2720 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2721 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2722 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2723 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2724 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2725 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2726 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002727
David Benjaminf0d8e222017-02-04 10:58:26 -05002728 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002729 EXPECT_EQ(TLS1_2_VERSION, ctx->conf_max_version);
David Benjaminf0d8e222017-02-04 10:58:26 -05002730 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002731 EXPECT_EQ(TLS1_1_VERSION, ctx->conf_min_version);
David Benjamin2dc02042016-09-19 19:57:37 -04002732}
2733
David Benjamin458334a2016-12-15 13:53:25 -05002734static const char *GetVersionName(uint16_t version) {
2735 switch (version) {
2736 case SSL3_VERSION:
2737 return "SSLv3";
2738 case TLS1_VERSION:
2739 return "TLSv1";
2740 case TLS1_1_VERSION:
2741 return "TLSv1.1";
2742 case TLS1_2_VERSION:
2743 return "TLSv1.2";
2744 case TLS1_3_VERSION:
2745 return "TLSv1.3";
2746 case DTLS1_VERSION:
2747 return "DTLSv1";
2748 case DTLS1_2_VERSION:
2749 return "DTLSv1.2";
2750 default:
2751 return "???";
2752 }
2753}
2754
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002755TEST_P(SSLVersionTest, Version) {
2756 ASSERT_TRUE(Connect());
David Benjamincb18ac22016-09-27 14:09:15 -04002757
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002758 EXPECT_EQ(SSL_version(client_.get()), version());
2759 EXPECT_EQ(SSL_version(server_.get()), version());
David Benjamincb18ac22016-09-27 14:09:15 -04002760
David Benjamin458334a2016-12-15 13:53:25 -05002761 // Test the version name is reported as expected.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002762 const char *version_name = GetVersionName(version());
2763 EXPECT_EQ(strcmp(version_name, SSL_get_version(client_.get())), 0);
2764 EXPECT_EQ(strcmp(version_name, SSL_get_version(server_.get())), 0);
David Benjamin458334a2016-12-15 13:53:25 -05002765
2766 // Test SSL_SESSION reports the same name.
2767 const char *client_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002768 SSL_SESSION_get_version(SSL_get_session(client_.get()));
David Benjamin458334a2016-12-15 13:53:25 -05002769 const char *server_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002770 SSL_SESSION_get_version(SSL_get_session(server_.get()));
2771 EXPECT_EQ(strcmp(version_name, client_name), 0);
2772 EXPECT_EQ(strcmp(version_name, server_name), 0);
David Benjamincb18ac22016-09-27 14:09:15 -04002773}
2774
David Benjamin9ef31f02016-10-31 18:01:13 -04002775// Tests that that |SSL_get_pending_cipher| is available during the ALPN
2776// selection callback.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002777TEST_P(SSLVersionTest, ALPNCipherAvailable) {
David Benjamin0fef3052016-11-18 15:11:10 +09002778 // SSL 3.0 lacks extensions.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002779 if (version() == SSL3_VERSION) {
2780 return;
David Benjamin0fef3052016-11-18 15:11:10 +09002781 }
2782
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002783 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2784
David Benjamin9ef31f02016-10-31 18:01:13 -04002785 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002786 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
2787 sizeof(kALPNProtos)),
2788 0);
David Benjamin0fef3052016-11-18 15:11:10 +09002789
2790 // The ALPN callback does not fail the handshake on error, so have the
2791 // callback write a boolean.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002792 std::pair<uint16_t, bool> callback_state(version(), false);
David Benjamin0fef3052016-11-18 15:11:10 +09002793 SSL_CTX_set_alpn_select_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002794 server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09002795 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
2796 unsigned in_len, void *arg) -> int {
2797 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
2798 if (SSL_get_pending_cipher(ssl) != nullptr &&
2799 SSL_version(ssl) == state->first) {
2800 state->second = true;
2801 }
2802 return SSL_TLSEXT_ERR_NOACK;
2803 },
2804 &callback_state);
2805
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002806 ASSERT_TRUE(Connect());
David Benjamin0fef3052016-11-18 15:11:10 +09002807
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002808 ASSERT_TRUE(callback_state.second);
David Benjamin0fef3052016-11-18 15:11:10 +09002809}
2810
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002811TEST_P(SSLVersionTest, SSLClearSessionResumption) {
David Benjaminb79cc842016-12-07 15:57:14 -05002812 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
2813 // API pattern.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002814 if (version() == TLS1_3_VERSION) {
2815 return;
David Benjaminb79cc842016-12-07 15:57:14 -05002816 }
2817
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002818 ASSERT_TRUE(Connect());
David Benjaminb79cc842016-12-07 15:57:14 -05002819
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002820 EXPECT_FALSE(SSL_session_reused(client_.get()));
2821 EXPECT_FALSE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002822
2823 // Reset everything.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002824 ASSERT_TRUE(SSL_clear(client_.get()));
2825 ASSERT_TRUE(SSL_clear(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002826
2827 // Attempt to connect a second time.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002828 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002829
2830 // |SSL_clear| should implicitly offer the previous session to the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002831 EXPECT_TRUE(SSL_session_reused(client_.get()));
2832 EXPECT_TRUE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002833}
2834
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002835static bool ChainsEqual(STACK_OF(X509) * chain,
2836 const std::vector<X509 *> &expected) {
David Benjamin1444c3a2016-12-20 17:23:11 -05002837 if (sk_X509_num(chain) != expected.size()) {
2838 return false;
2839 }
2840
2841 for (size_t i = 0; i < expected.size(); i++) {
2842 if (X509_cmp(sk_X509_value(chain, i), expected[i]) != 0) {
2843 return false;
2844 }
2845 }
2846
2847 return true;
2848}
2849
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002850TEST_P(SSLVersionTest, AutoChain) {
2851 cert_ = GetChainTestCertificate();
2852 ASSERT_TRUE(cert_);
2853 key_ = GetChainTestKey();
2854 ASSERT_TRUE(key_);
David Benjamin1444c3a2016-12-20 17:23:11 -05002855 bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002856 ASSERT_TRUE(intermediate);
2857
2858 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2859 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin1444c3a2016-12-20 17:23:11 -05002860
2861 // Configure both client and server to accept any certificate. Add
2862 // |intermediate| to the cert store.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002863 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx_.get()),
2864 intermediate.get()));
2865 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(server_ctx_.get()),
2866 intermediate.get()));
2867 SSL_CTX_set_verify(client_ctx_.get(),
2868 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2869 nullptr);
2870 SSL_CTX_set_verify(server_ctx_.get(),
2871 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2872 nullptr);
2873 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
2874 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjamin1444c3a2016-12-20 17:23:11 -05002875
2876 // By default, the client and server should each only send the leaf.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002877 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002878
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002879 EXPECT_TRUE(
2880 ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()), {cert_.get()}));
2881 EXPECT_TRUE(
2882 ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()), {cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002883
2884 // If auto-chaining is enabled, then the intermediate is sent.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002885 SSL_CTX_clear_mode(client_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
2886 SSL_CTX_clear_mode(server_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
2887 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002888
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002889 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
2890 {cert_.get(), intermediate.get()}));
2891 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
2892 {cert_.get(), intermediate.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002893
2894 // Auto-chaining does not override explicitly-configured intermediates.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002895 ASSERT_TRUE(SSL_CTX_add1_chain_cert(client_ctx_.get(), cert_.get()));
2896 ASSERT_TRUE(SSL_CTX_add1_chain_cert(server_ctx_.get(), cert_.get()));
2897 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002898
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002899 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
2900 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002901
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002902 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
2903 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002904}
2905
David Benjamin48063c22017-01-01 23:56:36 -05002906static bool ExpectBadWriteRetry() {
2907 int err = ERR_get_error();
2908 if (ERR_GET_LIB(err) != ERR_LIB_SSL ||
2909 ERR_GET_REASON(err) != SSL_R_BAD_WRITE_RETRY) {
2910 char buf[ERR_ERROR_STRING_BUF_LEN];
2911 ERR_error_string_n(err, buf, sizeof(buf));
2912 fprintf(stderr, "Wanted SSL_R_BAD_WRITE_RETRY, got: %s.\n", buf);
2913 return false;
2914 }
2915
2916 if (ERR_peek_error() != 0) {
2917 fprintf(stderr, "Unexpected error following SSL_R_BAD_WRITE_RETRY.\n");
2918 return false;
2919 }
2920
2921 return true;
2922}
2923
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002924TEST_P(SSLVersionTest, SSLWriteRetry) {
2925 if (is_dtls()) {
2926 return;
David Benjamin48063c22017-01-01 23:56:36 -05002927 }
2928
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002929 for (bool enable_partial_write : {false, true}) {
2930 SCOPED_TRACE(enable_partial_write);
2931
David Benjamin48063c22017-01-01 23:56:36 -05002932 // Connect a client and server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002933 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2934
2935 ASSERT_TRUE(Connect());
David Benjamin48063c22017-01-01 23:56:36 -05002936
2937 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002938 SSL_set_mode(client_.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002939 }
2940
2941 // Write without reading until the buffer is full and we have an unfinished
2942 // write. Keep a count so we may reread it again later. "hello!" will be
2943 // written in two chunks, "hello" and "!".
2944 char data[] = "hello!";
2945 static const int kChunkLen = 5; // The length of "hello".
2946 unsigned count = 0;
2947 for (;;) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002948 int ret = SSL_write(client_.get(), data, kChunkLen);
David Benjamin48063c22017-01-01 23:56:36 -05002949 if (ret <= 0) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002950 ASSERT_EQ(SSL_get_error(client_.get(), ret), SSL_ERROR_WANT_WRITE);
2951 break;
David Benjamin48063c22017-01-01 23:56:36 -05002952 }
2953
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002954 ASSERT_EQ(ret, 5);
David Benjamin48063c22017-01-01 23:56:36 -05002955
2956 count++;
2957 }
2958
2959 // Retrying with the same parameters is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002960 ASSERT_EQ(
2961 SSL_get_error(client_.get(), SSL_write(client_.get(), data, kChunkLen)),
2962 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002963
2964 // Retrying with the same buffer but shorter length is not legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002965 ASSERT_EQ(SSL_get_error(client_.get(),
2966 SSL_write(client_.get(), data, kChunkLen - 1)),
2967 SSL_ERROR_SSL);
2968 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002969
2970 // Retrying with a different buffer pointer is not legal.
2971 char data2[] = "hello";
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002972 ASSERT_EQ(SSL_get_error(client_.get(),
2973 SSL_write(client_.get(), data2, kChunkLen)),
2974 SSL_ERROR_SSL);
2975 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002976
2977 // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002978 SSL_set_mode(client_.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
2979 ASSERT_EQ(SSL_get_error(client_.get(),
2980 SSL_write(client_.get(), data2, kChunkLen)),
2981 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002982
2983 // |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| does not disable length checks.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002984 ASSERT_EQ(SSL_get_error(client_.get(),
2985 SSL_write(client_.get(), data2, kChunkLen - 1)),
2986 SSL_ERROR_SSL);
2987 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002988
2989 // Retrying with a larger buffer is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002990 ASSERT_EQ(SSL_get_error(client_.get(),
2991 SSL_write(client_.get(), data, kChunkLen + 1)),
2992 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002993
2994 // Drain the buffer.
2995 char buf[20];
2996 for (unsigned i = 0; i < count; i++) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002997 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
2998 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
David Benjamin48063c22017-01-01 23:56:36 -05002999 }
3000
3001 // Now that there is space, a retry with a larger buffer should flush the
3002 // pending record, skip over that many bytes of input (on assumption they
3003 // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE
3004 // is set, this will complete in two steps.
3005 char data3[] = "_____!";
3006 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003007 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen);
3008 ASSERT_EQ(SSL_write(client_.get(), data3 + kChunkLen, 1), 1);
3009 } else {
3010 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen + 1);
David Benjamin48063c22017-01-01 23:56:36 -05003011 }
3012
3013 // Check the last write was correct. The data will be spread over two
3014 // records, so SSL_read returns twice.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003015 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
3016 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
3017 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), 1);
3018 ASSERT_EQ(buf[0], '!');
David Benjamin48063c22017-01-01 23:56:36 -05003019 }
David Benjamin48063c22017-01-01 23:56:36 -05003020}
3021
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003022TEST_P(SSLVersionTest, RecordCallback) {
3023 for (bool test_server : {true, false}) {
3024 SCOPED_TRACE(test_server);
3025 ResetContexts();
David Benjamin5df5be12017-06-22 19:43:11 -04003026
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003027 bool read_seen = false;
3028 bool write_seen = false;
3029 auto cb = [&](int is_write, int cb_version, int cb_type, const void *buf,
3030 size_t len, SSL *ssl) {
3031 if (cb_type != SSL3_RT_HEADER) {
3032 return;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003033 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07003034
3035 // The callback does not report a version for records.
3036 EXPECT_EQ(0, cb_version);
3037
3038 if (is_write) {
3039 write_seen = true;
3040 } else {
3041 read_seen = true;
3042 }
3043
3044 // Sanity-check that the record header is plausible.
3045 CBS cbs;
3046 CBS_init(&cbs, reinterpret_cast<const uint8_t *>(buf), len);
3047 uint8_t type;
3048 uint16_t record_version, length;
3049 ASSERT_TRUE(CBS_get_u8(&cbs, &type));
3050 ASSERT_TRUE(CBS_get_u16(&cbs, &record_version));
3051 EXPECT_TRUE(record_version == version() ||
3052 record_version == (is_dtls() ? DTLS1_VERSION : TLS1_VERSION))
3053 << "Invalid record version: " << record_version;
3054 if (is_dtls()) {
3055 uint16_t epoch;
3056 ASSERT_TRUE(CBS_get_u16(&cbs, &epoch));
3057 EXPECT_TRUE(epoch == 0 || epoch == 1) << "Invalid epoch: " << epoch;
3058 ASSERT_TRUE(CBS_skip(&cbs, 6));
3059 }
3060 ASSERT_TRUE(CBS_get_u16(&cbs, &length));
3061 EXPECT_EQ(0u, CBS_len(&cbs));
3062 };
3063 using CallbackType = decltype(cb);
3064 SSL_CTX *ctx = test_server ? server_ctx_.get() : client_ctx_.get();
3065 SSL_CTX_set_msg_callback(
3066 ctx, [](int is_write, int cb_version, int cb_type, const void *buf,
3067 size_t len, SSL *ssl, void *arg) {
3068 CallbackType *cb_ptr = reinterpret_cast<CallbackType *>(arg);
3069 (*cb_ptr)(is_write, cb_version, cb_type, buf, len, ssl);
3070 });
3071 SSL_CTX_set_msg_callback_arg(ctx, &cb);
3072
3073 ASSERT_TRUE(Connect());
3074
3075 EXPECT_TRUE(read_seen);
3076 EXPECT_TRUE(write_seen);
David Benjamin0fef3052016-11-18 15:11:10 +09003077 }
David Benjamin9ef31f02016-10-31 18:01:13 -04003078}
3079
David Benjamina8614602017-09-06 15:40:19 -04003080TEST_P(SSLVersionTest, GetServerName) {
3081 // No extensions in SSL 3.0.
3082 if (version() == SSL3_VERSION) {
3083 return;
3084 }
3085
3086 ClientConfig config;
3087 config.servername = "host1";
3088
3089 SSL_CTX_set_tlsext_servername_callback(
3090 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
3091 // During the handshake, |SSL_get_servername| must match |config|.
3092 ClientConfig *config_p = reinterpret_cast<ClientConfig *>(arg);
3093 EXPECT_STREQ(config_p->servername.c_str(),
3094 SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name));
3095 return SSL_TLSEXT_ERR_OK;
3096 });
3097 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), &config);
3098
3099 ASSERT_TRUE(Connect(config));
3100 // After the handshake, it must also be available.
3101 EXPECT_STREQ(config.servername.c_str(),
3102 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3103
3104 // Establish a session under host1.
3105 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3106 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3107 bssl::UniquePtr<SSL_SESSION> session =
3108 CreateClientSession(client_ctx_.get(), server_ctx_.get(), config);
3109
3110 // If the client resumes a session with a different name, |SSL_get_servername|
3111 // must return the new name.
3112 ASSERT_TRUE(session);
3113 config.session = session.get();
3114 config.servername = "host2";
3115 ASSERT_TRUE(Connect(config));
3116 EXPECT_STREQ(config.servername.c_str(),
3117 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3118}
3119
David Benjamin3d8f0802017-09-06 16:12:52 -04003120// Test that session cache mode bits are honored in the client session callback.
3121TEST_P(SSLVersionTest, ClientSessionCacheMode) {
3122 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_OFF);
3123 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3124
3125 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_CLIENT);
3126 EXPECT_TRUE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3127
3128 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_SERVER);
3129 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3130}
3131
Adam Langleye1e78132017-01-31 15:24:31 -08003132TEST(SSLTest, AddChainCertHack) {
3133 // Ensure that we don't accidently break the hack that we have in place to
3134 // keep curl and serf happy when they use an |X509| even after transfering
3135 // ownership.
3136
3137 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3138 ASSERT_TRUE(ctx);
3139 X509 *cert = GetTestCertificate().release();
3140 ASSERT_TRUE(cert);
3141 SSL_CTX_add0_chain_cert(ctx.get(), cert);
3142
3143 // This should not trigger a use-after-free.
3144 X509_cmp(cert, cert);
3145}
3146
David Benjaminb2ff2622017-02-03 17:06:18 -05003147TEST(SSLTest, GetCertificate) {
3148 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3149 ASSERT_TRUE(ctx);
3150 bssl::UniquePtr<X509> cert = GetTestCertificate();
3151 ASSERT_TRUE(cert);
3152 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
3153 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3154 ASSERT_TRUE(ssl);
3155
3156 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
3157 ASSERT_TRUE(cert2);
3158 X509 *cert3 = SSL_get_certificate(ssl.get());
3159 ASSERT_TRUE(cert3);
3160
3161 // The old and new certificates must be identical.
3162 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
3163 EXPECT_EQ(0, X509_cmp(cert.get(), cert3));
3164
3165 uint8_t *der = nullptr;
3166 long der_len = i2d_X509(cert.get(), &der);
3167 ASSERT_LT(0, der_len);
3168 bssl::UniquePtr<uint8_t> free_der(der);
3169
3170 uint8_t *der2 = nullptr;
3171 long der2_len = i2d_X509(cert2, &der2);
3172 ASSERT_LT(0, der2_len);
3173 bssl::UniquePtr<uint8_t> free_der2(der2);
3174
3175 uint8_t *der3 = nullptr;
3176 long der3_len = i2d_X509(cert3, &der3);
3177 ASSERT_LT(0, der3_len);
3178 bssl::UniquePtr<uint8_t> free_der3(der3);
3179
3180 // They must also encode identically.
David Benjamin7d7554b2017-02-04 11:48:59 -05003181 EXPECT_EQ(Bytes(der, der_len), Bytes(der2, der2_len));
3182 EXPECT_EQ(Bytes(der, der_len), Bytes(der3, der3_len));
David Benjaminb2ff2622017-02-03 17:06:18 -05003183}
3184
Adam Langleyd04ca952017-02-28 11:26:51 -08003185TEST(SSLTest, SetChainAndKeyMismatch) {
3186 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_with_buffers_method()));
3187 ASSERT_TRUE(ctx);
3188
3189 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3190 ASSERT_TRUE(key);
3191 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3192 ASSERT_TRUE(leaf);
3193 std::vector<CRYPTO_BUFFER*> chain = {
3194 leaf.get(),
3195 };
3196
3197 // Should fail because |GetTestKey| doesn't match the chain-test certificate.
3198 ASSERT_FALSE(SSL_CTX_set_chain_and_key(ctx.get(), &chain[0], chain.size(),
3199 key.get(), nullptr));
3200 ERR_clear_error();
3201}
3202
3203TEST(SSLTest, SetChainAndKey) {
3204 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3205 ASSERT_TRUE(client_ctx);
3206 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3207 ASSERT_TRUE(server_ctx);
3208
3209 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3210 ASSERT_TRUE(key);
3211 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3212 ASSERT_TRUE(leaf);
3213 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3214 GetChainTestIntermediateBuffer();
3215 ASSERT_TRUE(intermediate);
3216 std::vector<CRYPTO_BUFFER*> chain = {
3217 leaf.get(), intermediate.get(),
3218 };
3219 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3220 chain.size(), key.get(), nullptr));
3221
David Benjamin3a1dd462017-07-11 16:13:10 -04003222 SSL_CTX_set_custom_verify(
3223 client_ctx.get(), SSL_VERIFY_PEER,
3224 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3225 return ssl_verify_ok;
3226 });
Adam Langleyd04ca952017-02-28 11:26:51 -08003227
3228 bssl::UniquePtr<SSL> client, server;
3229 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003230 server_ctx.get()));
Adam Langleyd04ca952017-02-28 11:26:51 -08003231}
3232
David Benjamin71dfad42017-07-16 17:27:39 -04003233TEST(SSLTest, ClientCABuffers) {
3234 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3235 ASSERT_TRUE(client_ctx);
3236 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3237 ASSERT_TRUE(server_ctx);
3238
3239 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3240 ASSERT_TRUE(key);
3241 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3242 ASSERT_TRUE(leaf);
3243 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3244 GetChainTestIntermediateBuffer();
3245 ASSERT_TRUE(intermediate);
3246 std::vector<CRYPTO_BUFFER *> chain = {
3247 leaf.get(),
3248 intermediate.get(),
3249 };
3250 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3251 chain.size(), key.get(), nullptr));
3252
3253 bssl::UniquePtr<CRYPTO_BUFFER> ca_name(
3254 CRYPTO_BUFFER_new(kTestName, sizeof(kTestName), nullptr));
3255 ASSERT_TRUE(ca_name);
3256 bssl::UniquePtr<STACK_OF(CRYPTO_BUFFER)> ca_names(
3257 sk_CRYPTO_BUFFER_new_null());
3258 ASSERT_TRUE(ca_names);
3259 ASSERT_TRUE(sk_CRYPTO_BUFFER_push(ca_names.get(), ca_name.get()));
3260 ca_name.release();
3261 SSL_CTX_set0_client_CAs(server_ctx.get(), ca_names.release());
3262
3263 // Configure client and server to accept all certificates.
3264 SSL_CTX_set_custom_verify(
3265 client_ctx.get(), SSL_VERIFY_PEER,
3266 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3267 return ssl_verify_ok;
3268 });
3269 SSL_CTX_set_custom_verify(
3270 server_ctx.get(), SSL_VERIFY_PEER,
3271 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3272 return ssl_verify_ok;
3273 });
3274
3275 bool cert_cb_called = false;
3276 SSL_CTX_set_cert_cb(
3277 client_ctx.get(),
3278 [](SSL *ssl, void *arg) -> int {
3279 STACK_OF(CRYPTO_BUFFER) *peer_names =
3280 SSL_get0_server_requested_CAs(ssl);
3281 EXPECT_EQ(1u, sk_CRYPTO_BUFFER_num(peer_names));
3282 CRYPTO_BUFFER *peer_name = sk_CRYPTO_BUFFER_value(peer_names, 0);
3283 EXPECT_EQ(Bytes(kTestName), Bytes(CRYPTO_BUFFER_data(peer_name),
3284 CRYPTO_BUFFER_len(peer_name)));
3285 *reinterpret_cast<bool *>(arg) = true;
3286 return 1;
3287 },
3288 &cert_cb_called);
3289
3290 bssl::UniquePtr<SSL> client, server;
3291 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003292 server_ctx.get()));
David Benjamin71dfad42017-07-16 17:27:39 -04003293 EXPECT_TRUE(cert_cb_called);
3294}
3295
David Benjamin91222b82017-03-09 20:10:56 -05003296// Configuring the empty cipher list, though an error, should still modify the
3297// configuration.
3298TEST(SSLTest, EmptyCipherList) {
3299 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3300 ASSERT_TRUE(ctx);
3301
3302 // Initially, the cipher list is not empty.
3303 EXPECT_NE(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3304
3305 // Configuring the empty cipher list fails.
3306 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), ""));
3307 ERR_clear_error();
3308
3309 // But the cipher list is still updated to empty.
3310 EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3311}
3312
Adam Langley4c341d02017-03-08 19:33:21 -08003313// ssl_test_ticket_aead_failure_mode enumerates the possible ways in which the
3314// test |SSL_TICKET_AEAD_METHOD| can fail.
3315enum ssl_test_ticket_aead_failure_mode {
3316 ssl_test_ticket_aead_ok = 0,
3317 ssl_test_ticket_aead_seal_fail,
3318 ssl_test_ticket_aead_open_soft_fail,
3319 ssl_test_ticket_aead_open_hard_fail,
3320};
3321
3322struct ssl_test_ticket_aead_state {
3323 unsigned retry_count;
3324 ssl_test_ticket_aead_failure_mode failure_mode;
3325};
3326
3327static int ssl_test_ticket_aead_ex_index_dup(CRYPTO_EX_DATA *to,
3328 const CRYPTO_EX_DATA *from,
3329 void **from_d, int index,
3330 long argl, void *argp) {
3331 abort();
3332}
3333
3334static void ssl_test_ticket_aead_ex_index_free(void *parent, void *ptr,
3335 CRYPTO_EX_DATA *ad, int index,
3336 long argl, void *argp) {
3337 auto state = reinterpret_cast<ssl_test_ticket_aead_state*>(ptr);
3338 if (state == nullptr) {
3339 return;
3340 }
3341
3342 OPENSSL_free(state);
3343}
3344
3345static CRYPTO_once_t g_ssl_test_ticket_aead_ex_index_once = CRYPTO_ONCE_INIT;
3346static int g_ssl_test_ticket_aead_ex_index;
3347
3348static int ssl_test_ticket_aead_get_ex_index() {
3349 CRYPTO_once(&g_ssl_test_ticket_aead_ex_index_once, [] {
3350 g_ssl_test_ticket_aead_ex_index = SSL_get_ex_new_index(
3351 0, nullptr, nullptr, ssl_test_ticket_aead_ex_index_dup,
3352 ssl_test_ticket_aead_ex_index_free);
3353 });
3354 return g_ssl_test_ticket_aead_ex_index;
3355}
3356
3357static size_t ssl_test_ticket_aead_max_overhead(SSL *ssl) {
3358 return 1;
3359}
3360
3361static int ssl_test_ticket_aead_seal(SSL *ssl, uint8_t *out, size_t *out_len,
3362 size_t max_out_len, const uint8_t *in,
3363 size_t in_len) {
3364 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3365 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3366
3367 if (state->failure_mode == ssl_test_ticket_aead_seal_fail ||
3368 max_out_len < in_len + 1) {
3369 return 0;
3370 }
3371
3372 OPENSSL_memmove(out, in, in_len);
3373 out[in_len] = 0xff;
3374 *out_len = in_len + 1;
3375
3376 return 1;
3377}
3378
3379static ssl_ticket_aead_result_t ssl_test_ticket_aead_open(
3380 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len,
3381 const uint8_t *in, size_t in_len) {
3382 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3383 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3384
3385 if (state->retry_count > 0) {
3386 state->retry_count--;
3387 return ssl_ticket_aead_retry;
3388 }
3389
3390 switch (state->failure_mode) {
3391 case ssl_test_ticket_aead_ok:
3392 break;
3393 case ssl_test_ticket_aead_seal_fail:
3394 // If |seal| failed then there shouldn't be any ticket to try and
3395 // decrypt.
3396 abort();
3397 break;
3398 case ssl_test_ticket_aead_open_soft_fail:
3399 return ssl_ticket_aead_ignore_ticket;
3400 case ssl_test_ticket_aead_open_hard_fail:
3401 return ssl_ticket_aead_error;
3402 }
3403
3404 if (in_len == 0 || in[in_len - 1] != 0xff) {
3405 return ssl_ticket_aead_ignore_ticket;
3406 }
3407
3408 if (max_out_len < in_len - 1) {
3409 return ssl_ticket_aead_error;
3410 }
3411
3412 OPENSSL_memmove(out, in, in_len - 1);
3413 *out_len = in_len - 1;
3414 return ssl_ticket_aead_success;
3415}
3416
3417static const SSL_TICKET_AEAD_METHOD kSSLTestTicketMethod = {
3418 ssl_test_ticket_aead_max_overhead,
3419 ssl_test_ticket_aead_seal,
3420 ssl_test_ticket_aead_open,
3421};
3422
3423static void ConnectClientAndServerWithTicketMethod(
3424 bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
3425 SSL_CTX *client_ctx, SSL_CTX *server_ctx, unsigned retry_count,
3426 ssl_test_ticket_aead_failure_mode failure_mode, SSL_SESSION *session) {
3427 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
3428 ASSERT_TRUE(client);
3429 ASSERT_TRUE(server);
3430 SSL_set_connect_state(client.get());
3431 SSL_set_accept_state(server.get());
3432
3433 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3434 OPENSSL_malloc(sizeof(ssl_test_ticket_aead_state)));
3435 ASSERT_TRUE(state);
3436 OPENSSL_memset(state, 0, sizeof(ssl_test_ticket_aead_state));
3437 state->retry_count = retry_count;
3438 state->failure_mode = failure_mode;
3439
3440 ASSERT_TRUE(SSL_set_ex_data(server.get(), ssl_test_ticket_aead_get_ex_index(),
3441 state));
3442
3443 SSL_set_session(client.get(), session);
3444
3445 BIO *bio1, *bio2;
3446 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
3447
3448 // SSL_set_bio takes ownership.
3449 SSL_set_bio(client.get(), bio1, bio1);
3450 SSL_set_bio(server.get(), bio2, bio2);
3451
3452 if (CompleteHandshakes(client.get(), server.get())) {
3453 *out_client = std::move(client);
3454 *out_server = std::move(server);
3455 } else {
3456 out_client->reset();
3457 out_server->reset();
3458 }
3459}
3460
3461class TicketAEADMethodTest
3462 : public ::testing::TestWithParam<testing::tuple<
3463 uint16_t, unsigned, ssl_test_ticket_aead_failure_mode>> {};
3464
3465TEST_P(TicketAEADMethodTest, Resume) {
3466 bssl::UniquePtr<X509> cert = GetTestCertificate();
3467 ASSERT_TRUE(cert);
3468 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3469 ASSERT_TRUE(key);
3470
3471 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
3472 ASSERT_TRUE(server_ctx);
3473 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
3474 ASSERT_TRUE(client_ctx);
3475
3476 const uint16_t version = testing::get<0>(GetParam());
3477 const unsigned retry_count = testing::get<1>(GetParam());
3478 const ssl_test_ticket_aead_failure_mode failure_mode =
3479 testing::get<2>(GetParam());
3480
3481 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3482 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3483 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), version));
3484 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), version));
3485 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), version));
3486 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), version));
3487
3488 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
3489 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
3490 SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
3491 SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
David Benjamin707af292017-03-10 17:47:18 -05003492 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langley4c341d02017-03-08 19:33:21 -08003493
3494 SSL_CTX_set_ticket_aead_method(server_ctx.get(), &kSSLTestTicketMethod);
3495
3496 bssl::UniquePtr<SSL> client, server;
3497 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3498 server_ctx.get(), retry_count,
3499 failure_mode, nullptr);
3500 switch (failure_mode) {
3501 case ssl_test_ticket_aead_ok:
3502 case ssl_test_ticket_aead_open_hard_fail:
3503 case ssl_test_ticket_aead_open_soft_fail:
3504 ASSERT_TRUE(client);
3505 break;
3506 case ssl_test_ticket_aead_seal_fail:
3507 EXPECT_FALSE(client);
3508 return;
3509 }
3510 EXPECT_FALSE(SSL_session_reused(client.get()));
3511 EXPECT_FALSE(SSL_session_reused(server.get()));
3512
David Benjamin707af292017-03-10 17:47:18 -05003513 // Run the read loop to account for post-handshake tickets in TLS 1.3.
3514 SSL_read(client.get(), nullptr, 0);
3515
3516 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
Adam Langley4c341d02017-03-08 19:33:21 -08003517 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3518 server_ctx.get(), retry_count,
David Benjamin707af292017-03-10 17:47:18 -05003519 failure_mode, session.get());
Adam Langley4c341d02017-03-08 19:33:21 -08003520 switch (failure_mode) {
3521 case ssl_test_ticket_aead_ok:
3522 ASSERT_TRUE(client);
3523 EXPECT_TRUE(SSL_session_reused(client.get()));
3524 EXPECT_TRUE(SSL_session_reused(server.get()));
3525 break;
3526 case ssl_test_ticket_aead_seal_fail:
3527 abort();
3528 break;
3529 case ssl_test_ticket_aead_open_hard_fail:
3530 EXPECT_FALSE(client);
3531 break;
3532 case ssl_test_ticket_aead_open_soft_fail:
3533 ASSERT_TRUE(client);
3534 EXPECT_FALSE(SSL_session_reused(client.get()));
3535 EXPECT_FALSE(SSL_session_reused(server.get()));
3536 }
3537}
3538
3539INSTANTIATE_TEST_CASE_P(
3540 TicketAEADMethodTests, TicketAEADMethodTest,
3541 testing::Combine(
David Benjamin707af292017-03-10 17:47:18 -05003542 testing::Values(TLS1_2_VERSION, TLS1_3_VERSION),
Adam Langley4c341d02017-03-08 19:33:21 -08003543 testing::Values(0, 1, 2),
3544 testing::Values(ssl_test_ticket_aead_ok,
3545 ssl_test_ticket_aead_seal_fail,
3546 ssl_test_ticket_aead_open_soft_fail,
3547 ssl_test_ticket_aead_open_hard_fail)));
3548
David Benjamin3cfeb952017-03-01 16:48:38 -05003549TEST(SSLTest, SSL3Method) {
3550 bssl::UniquePtr<X509> cert = GetTestCertificate();
3551 ASSERT_TRUE(cert);
3552
3553 // For compatibility, SSLv3_method should work up to SSL_CTX_new and SSL_new.
3554 bssl::UniquePtr<SSL_CTX> ssl3_ctx(SSL_CTX_new(SSLv3_method()));
3555 ASSERT_TRUE(ssl3_ctx);
3556 ASSERT_TRUE(SSL_CTX_use_certificate(ssl3_ctx.get(), cert.get()));
3557 bssl::UniquePtr<SSL> ssl(SSL_new(ssl3_ctx.get()));
3558 EXPECT_TRUE(ssl);
3559
3560 // Create a normal TLS context to test against.
3561 bssl::UniquePtr<SSL_CTX> tls_ctx(SSL_CTX_new(TLS_method()));
3562 ASSERT_TRUE(tls_ctx);
3563 ASSERT_TRUE(SSL_CTX_use_certificate(tls_ctx.get(), cert.get()));
3564
3565 // However, handshaking an SSLv3_method server should fail to resolve the
3566 // version range. Explicit calls to SSL_CTX_set_min_proto_version are the only
3567 // way to enable SSL 3.0.
3568 bssl::UniquePtr<SSL> client, server;
3569 EXPECT_FALSE(ConnectClientAndServer(&client, &server, tls_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003570 ssl3_ctx.get()));
David Benjamin3cfeb952017-03-01 16:48:38 -05003571 uint32_t err = ERR_get_error();
3572 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
3573 EXPECT_EQ(SSL_R_NO_SUPPORTED_VERSIONS_ENABLED, ERR_GET_REASON(err));
3574
3575 // Likewise for SSLv3_method clients.
3576 EXPECT_FALSE(ConnectClientAndServer(&client, &server, ssl3_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003577 tls_ctx.get()));
David Benjamin3cfeb952017-03-01 16:48:38 -05003578 err = ERR_get_error();
3579 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
3580 EXPECT_EQ(SSL_R_NO_SUPPORTED_VERSIONS_ENABLED, ERR_GET_REASON(err));
3581}
3582
David Benjaminca743582017-06-15 17:51:35 -04003583TEST(SSLTest, SelectNextProto) {
3584 uint8_t *result;
3585 uint8_t result_len;
3586
3587 // If there is an overlap, it should be returned.
3588 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3589 SSL_select_next_proto(&result, &result_len,
3590 (const uint8_t *)"\1a\2bb\3ccc", 9,
3591 (const uint8_t *)"\1x\1y\1a\1z", 8));
3592 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
3593
3594 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3595 SSL_select_next_proto(&result, &result_len,
3596 (const uint8_t *)"\1a\2bb\3ccc", 9,
3597 (const uint8_t *)"\1x\1y\2bb\1z", 9));
3598 EXPECT_EQ(Bytes("bb"), Bytes(result, result_len));
3599
3600 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3601 SSL_select_next_proto(&result, &result_len,
3602 (const uint8_t *)"\1a\2bb\3ccc", 9,
3603 (const uint8_t *)"\1x\1y\3ccc\1z", 10));
3604 EXPECT_EQ(Bytes("ccc"), Bytes(result, result_len));
3605
3606 // Peer preference order takes precedence over local.
3607 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3608 SSL_select_next_proto(&result, &result_len,
3609 (const uint8_t *)"\1a\2bb\3ccc", 9,
3610 (const uint8_t *)"\3ccc\2bb\1a", 9));
3611 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
3612
3613 // If there is no overlap, return the first local protocol.
3614 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
3615 SSL_select_next_proto(&result, &result_len,
3616 (const uint8_t *)"\1a\2bb\3ccc", 9,
3617 (const uint8_t *)"\1x\2yy\3zzz", 9));
3618 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
3619
3620 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
3621 SSL_select_next_proto(&result, &result_len, nullptr, 0,
3622 (const uint8_t *)"\1x\2yy\3zzz", 9));
3623 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
3624}
3625
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003626TEST(SSLTest, SealRecord) {
3627 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3628 server_ctx(SSL_CTX_new(TLS_method()));
3629 ASSERT_TRUE(client_ctx);
3630 ASSERT_TRUE(server_ctx);
3631
3632 bssl::UniquePtr<X509> cert = GetTestCertificate();
3633 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3634 ASSERT_TRUE(cert);
3635 ASSERT_TRUE(key);
3636 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3637 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3638
3639 bssl::UniquePtr<SSL> client, server;
3640 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003641 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003642
3643 const std::vector<uint8_t> record = {1, 2, 3, 4, 5};
3644 std::vector<uint8_t> prefix(
3645 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003646 body(record.size()),
3647 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003648 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3649 bssl::MakeSpan(body), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003650 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003651
3652 std::vector<uint8_t> sealed;
3653 sealed.insert(sealed.end(), prefix.begin(), prefix.end());
3654 sealed.insert(sealed.end(), body.begin(), body.end());
3655 sealed.insert(sealed.end(), suffix.begin(), suffix.end());
3656 std::vector<uint8_t> sealed_copy = sealed;
3657
3658 bssl::Span<uint8_t> plaintext;
3659 size_t record_len;
3660 uint8_t alert = 255;
3661 EXPECT_EQ(bssl::OpenRecord(server.get(), &plaintext, &record_len, &alert,
3662 bssl::MakeSpan(sealed)),
3663 bssl::OpenRecordResult::kOK);
3664 EXPECT_EQ(record_len, sealed.size());
3665 EXPECT_EQ(plaintext, record);
3666 EXPECT_EQ(255, alert);
3667}
3668
3669TEST(SSLTest, SealRecordInPlace) {
3670 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3671 server_ctx(SSL_CTX_new(TLS_method()));
3672 ASSERT_TRUE(client_ctx);
3673 ASSERT_TRUE(server_ctx);
3674
3675 bssl::UniquePtr<X509> cert = GetTestCertificate();
3676 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3677 ASSERT_TRUE(cert);
3678 ASSERT_TRUE(key);
3679 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3680 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3681
3682 bssl::UniquePtr<SSL> client, server;
3683 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003684 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003685
3686 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
3687 std::vector<uint8_t> record = plaintext;
3688 std::vector<uint8_t> prefix(
3689 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003690 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003691 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3692 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003693 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003694 record.insert(record.begin(), prefix.begin(), prefix.end());
3695 record.insert(record.end(), suffix.begin(), suffix.end());
3696
3697 bssl::Span<uint8_t> result;
3698 size_t record_len;
3699 uint8_t alert;
3700 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
3701 bssl::MakeSpan(record)),
3702 bssl::OpenRecordResult::kOK);
3703 EXPECT_EQ(record_len, record.size());
3704 EXPECT_EQ(plaintext, result);
3705}
3706
3707TEST(SSLTest, SealRecordTrailingData) {
3708 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3709 server_ctx(SSL_CTX_new(TLS_method()));
3710 ASSERT_TRUE(client_ctx);
3711 ASSERT_TRUE(server_ctx);
3712
3713 bssl::UniquePtr<X509> cert = GetTestCertificate();
3714 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3715 ASSERT_TRUE(cert);
3716 ASSERT_TRUE(key);
3717 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3718 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3719
3720 bssl::UniquePtr<SSL> client, server;
3721 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003722 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003723
3724 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
3725 std::vector<uint8_t> record = plaintext;
3726 std::vector<uint8_t> prefix(
3727 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003728 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003729 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3730 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003731 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003732 record.insert(record.begin(), prefix.begin(), prefix.end());
3733 record.insert(record.end(), suffix.begin(), suffix.end());
3734 record.insert(record.end(), {5, 4, 3, 2, 1});
3735
3736 bssl::Span<uint8_t> result;
3737 size_t record_len;
3738 uint8_t alert;
3739 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
3740 bssl::MakeSpan(record)),
3741 bssl::OpenRecordResult::kOK);
3742 EXPECT_EQ(record_len, record.size() - 5);
3743 EXPECT_EQ(plaintext, result);
3744}
3745
3746TEST(SSLTest, SealRecordInvalidSpanSize) {
3747 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3748 server_ctx(SSL_CTX_new(TLS_method()));
3749 ASSERT_TRUE(client_ctx);
3750 ASSERT_TRUE(server_ctx);
3751
3752 bssl::UniquePtr<X509> cert = GetTestCertificate();
3753 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3754 ASSERT_TRUE(cert);
3755 ASSERT_TRUE(key);
3756 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3757 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3758
3759 bssl::UniquePtr<SSL> client, server;
3760 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003761 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003762
3763 std::vector<uint8_t> record = {1, 2, 3, 4, 5};
3764 std::vector<uint8_t> prefix(
3765 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003766 body(record.size()),
3767 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003768
3769 auto expect_err = []() {
3770 int err = ERR_get_error();
3771 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
3772 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_BUFFER_TOO_SMALL);
3773 ERR_clear_error();
3774 };
3775 EXPECT_FALSE(bssl::SealRecord(
3776 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003777 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003778 expect_err();
3779 EXPECT_FALSE(bssl::SealRecord(
3780 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003781 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003782 expect_err();
3783
3784 EXPECT_FALSE(
3785 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3786 bssl::MakeSpan(record.data(), record.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003787 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003788 expect_err();
3789 EXPECT_FALSE(
3790 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3791 bssl::MakeSpan(record.data(), record.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003792 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003793 expect_err();
3794
3795 EXPECT_FALSE(bssl::SealRecord(
3796 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003797 bssl::MakeSpan(suffix.data(), suffix.size() - 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003798 expect_err();
3799 EXPECT_FALSE(bssl::SealRecord(
3800 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003801 bssl::MakeSpan(suffix.data(), suffix.size() + 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003802 expect_err();
3803}
3804
David Benjamin617b8182017-08-29 15:33:10 -04003805// The client should gracefully handle no suitable ciphers being enabled.
3806TEST(SSLTest, NoCiphersAvailable) {
3807 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3808 ASSERT_TRUE(ctx);
3809
3810 // Configure |client_ctx| with a cipher list that does not intersect with its
3811 // version configuration.
3812 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
3813 ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
3814 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
3815
3816 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3817 ASSERT_TRUE(ssl);
3818 SSL_set_connect_state(ssl.get());
3819
3820 UniquePtr<BIO> rbio(BIO_new(BIO_s_mem())), wbio(BIO_new(BIO_s_mem()));
3821 ASSERT_TRUE(rbio);
3822 ASSERT_TRUE(wbio);
3823 SSL_set0_rbio(ssl.get(), rbio.release());
3824 SSL_set0_wbio(ssl.get(), wbio.release());
3825
3826 int ret = SSL_do_handshake(ssl.get());
3827 EXPECT_EQ(-1, ret);
3828 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), ret));
3829 uint32_t err = ERR_get_error();
3830 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
3831 EXPECT_EQ(SSL_R_NO_CIPHERS_AVAILABLE, ERR_GET_REASON(err));
3832}
3833
David Benjaminaba057a2017-09-11 15:21:43 -04003834TEST(SSLTest, IsProbablyJava) {
3835 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3836 ASSERT_TRUE(ctx);
3837 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3838 ASSERT_TRUE(ssl);
3839
3840 const struct {
3841 const char *name;
3842 std::vector<uint8_t> in;
3843 bool is_probably_java;
3844 } kTests[] = {
3845 {"JDK 6 with IcedTea curve list",
3846 {0x03, 0x01, 0x59, 0xb3, 0x10, 0xea, 0x17, 0xfe, 0x9e, 0x69, 0x7e, 0x79,
3847 0xc7, 0x33, 0x10, 0x81, 0x73, 0x9e, 0xe7, 0xbf, 0x78, 0x4a, 0x33, 0x76,
3848 0x12, 0x1f, 0xc5, 0x6d, 0x28, 0x8d, 0xd7, 0x60, 0xf0, 0x5e, 0x00, 0x00,
3849 0x2c, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x35, 0xc0, 0x05, 0xc0, 0x0f, 0x00,
3850 0x39, 0x00, 0x38, 0xc0, 0x09, 0xc0, 0x13, 0x00, 0x2f, 0xc0, 0x04, 0xc0,
3851 0x0e, 0x00, 0x33, 0x00, 0x32, 0xc0, 0x08, 0xc0, 0x12, 0x00, 0x0a, 0xc0,
3852 0x03, 0xc0, 0x0d, 0x00, 0x16, 0x00, 0x13, 0x00, 0xff, 0x01, 0x00, 0x00,
3853 0x12, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x17, 0x00, 0x18, 0x00,
3854 0x19, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00},
3855 true},
3856 {"JDK 7 with IcedTea curve list",
3857 {0x03, 0x03, 0x59, 0xb3, 0x10, 0xc8, 0x03, 0x7d, 0x10, 0x5a, 0x6b, 0x6e,
3858 0x84, 0xa5, 0xbe, 0x6e, 0xe2, 0xd0, 0xb4, 0xb5, 0xcf, 0x6d, 0xa1, 0x58,
3859 0xb5, 0xc0, 0x05, 0x63, 0xf6, 0x81, 0xda, 0xc2, 0xa0, 0xb0, 0x00, 0x00,
3860 0x48, 0xc0, 0x24, 0xc0, 0x28, 0x00, 0x3d, 0xc0, 0x26, 0xc0, 0x2a, 0x00,
3861 0x6b, 0x00, 0x6a, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x35, 0xc0, 0x05, 0xc0,
3862 0x0f, 0x00, 0x39, 0x00, 0x38, 0xc0, 0x23, 0xc0, 0x27, 0x00, 0x3c, 0xc0,
3863 0x25, 0xc0, 0x29, 0x00, 0x67, 0x00, 0x40, 0xc0, 0x09, 0xc0, 0x13, 0x00,
3864 0x2f, 0xc0, 0x04, 0xc0, 0x0e, 0x00, 0x33, 0x00, 0x32, 0xc0, 0x08, 0xc0,
3865 0x12, 0x00, 0x0a, 0xc0, 0x03, 0xc0, 0x0d, 0x00, 0x16, 0x00, 0x13, 0x00,
3866 0xff, 0x01, 0x00, 0x00, 0x2e, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00,
3867 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
3868 0x0d, 0x00, 0x18, 0x00, 0x16, 0x06, 0x03, 0x06, 0x01, 0x05, 0x03, 0x05,
3869 0x01, 0x04, 0x03, 0x04, 0x01, 0x03, 0x03, 0x03, 0x01, 0x02, 0x03, 0x02,
3870 0x01, 0x02, 0x02},
3871 true},
3872 {"JDK 8",
3873 {0x03, 0x03, 0x59, 0xb3, 0x10, 0xfc, 0xc7, 0xcb, 0x36, 0x85, 0x8c, 0x00,
3874 0xd6, 0xa7, 0x5b, 0xfb, 0x98, 0xbe, 0xf9, 0xa3, 0xa0, 0x01, 0xff, 0x35,
3875 0xb9, 0x1a, 0xc1, 0x72, 0xf1, 0x51, 0x4b, 0x49, 0x96, 0x1a, 0x00, 0x00,
3876 0x70, 0xc0, 0x24, 0xc0, 0x28, 0x00, 0x3d, 0xc0, 0x26, 0xc0, 0x2a, 0x00,
3877 0x6b, 0x00, 0x6a, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x35, 0xc0, 0x05, 0xc0,
3878 0x0f, 0x00, 0x39, 0x00, 0x38, 0xc0, 0x23, 0xc0, 0x27, 0x00, 0x3c, 0xc0,
3879 0x25, 0xc0, 0x29, 0x00, 0x67, 0x00, 0x40, 0xc0, 0x09, 0xc0, 0x13, 0x00,
3880 0x2f, 0xc0, 0x04, 0xc0, 0x0e, 0x00, 0x33, 0x00, 0x32, 0xc0, 0x2c, 0xc0,
3881 0x2b, 0xc0, 0x30, 0x00, 0x9d, 0xc0, 0x2e, 0xc0, 0x32, 0x00, 0x9f, 0x00,
3882 0xa3, 0xc0, 0x2f, 0x00, 0x9c, 0xc0, 0x2d, 0xc0, 0x31, 0x00, 0x9e, 0x00,
3883 0xa2, 0xc0, 0x08, 0xc0, 0x12, 0x00, 0x0a, 0xc0, 0x03, 0xc0, 0x0d, 0x00,
3884 0x16, 0x00, 0x13, 0xc0, 0x07, 0xc0, 0x11, 0x00, 0x05, 0xc0, 0x02, 0xc0,
3885 0x0c, 0x00, 0x04, 0x00, 0xff, 0x01, 0x00, 0x00, 0x5c, 0x00, 0x0a, 0x00,
3886 0x34, 0x00, 0x32, 0x00, 0x17, 0x00, 0x01, 0x00, 0x03, 0x00, 0x13, 0x00,
3887 0x15, 0x00, 0x06, 0x00, 0x07, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x18, 0x00,
3888 0x0b, 0x00, 0x0c, 0x00, 0x19, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00,
3889 0x10, 0x00, 0x11, 0x00, 0x02, 0x00, 0x12, 0x00, 0x04, 0x00, 0x05, 0x00,
3890 0x14, 0x00, 0x08, 0x00, 0x16, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
3891 0x0d, 0x00, 0x1a, 0x00, 0x18, 0x06, 0x03, 0x06, 0x01, 0x05, 0x03, 0x05,
3892 0x01, 0x04, 0x03, 0x04, 0x01, 0x03, 0x03, 0x03, 0x01, 0x02, 0x03, 0x02,
3893 0x01, 0x02, 0x02, 0x01, 0x01},
3894 true},
3895 {"JDK 9",
3896 {0x03, 0x03, 0x0c, 0xe6, 0x06, 0xc6, 0x5d, 0x38, 0xb4, 0x5e, 0x3a, 0xd5,
3897 0xb0, 0x5f, 0x5b, 0x84, 0x3b, 0xff, 0x86, 0x4f, 0xb0, 0x3f, 0xc1, 0xfd,
3898 0x08, 0xf0, 0x97, 0xf3, 0x56, 0x44, 0x08, 0xe2, 0xdd, 0x2a, 0x00, 0x00,
3899 0x64, 0xc0, 0x2c, 0xc0, 0x2b, 0xc0, 0x30, 0x00, 0x9d, 0xc0, 0x2e, 0xc0,
3900 0x32, 0x00, 0x9f, 0x00, 0xa3, 0xc0, 0x2f, 0x00, 0x9c, 0xc0, 0x2d, 0xc0,
3901 0x31, 0x00, 0x9e, 0x00, 0xa2, 0xc0, 0x24, 0xc0, 0x28, 0x00, 0x3d, 0xc0,
3902 0x26, 0xc0, 0x2a, 0x00, 0x6b, 0x00, 0x6a, 0xc0, 0x0a, 0xc0, 0x14, 0x00,
3903 0x35, 0xc0, 0x05, 0xc0, 0x0f, 0x00, 0x39, 0x00, 0x38, 0xc0, 0x23, 0xc0,
3904 0x27, 0x00, 0x3c, 0xc0, 0x25, 0xc0, 0x29, 0x00, 0x67, 0x00, 0x40, 0xc0,
3905 0x09, 0xc0, 0x13, 0x00, 0x2f, 0xc0, 0x04, 0xc0, 0x0e, 0x00, 0x33, 0x00,
3906 0x32, 0xc0, 0x08, 0xc0, 0x12, 0x00, 0x0a, 0xc0, 0x03, 0xc0, 0x0d, 0x00,
3907 0x16, 0x00, 0x13, 0x00, 0xff, 0x01, 0x00, 0x00, 0x5d, 0x00, 0x0a, 0x00,
3908 0x16, 0x00, 0x14, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x09, 0x00,
3909 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x16, 0x00,
3910 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x0d, 0x00, 0x1c, 0x00, 0x1a, 0x06,
3911 0x03, 0x06, 0x01, 0x05, 0x03, 0x05, 0x01, 0x04, 0x03, 0x04, 0x01, 0x04,
3912 0x02, 0x03, 0x03, 0x03, 0x01, 0x03, 0x02, 0x02, 0x03, 0x02, 0x01, 0x02,
3913 0x02, 0x00, 0x11, 0x00, 0x10, 0x00, 0x0e, 0x02, 0x00, 0x04, 0x00, 0x00,
3914 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00,
3915 0x05, 0x01, 0x00, 0x00, 0x00, 0x00},
3916 true},
3917 {"JDK 9 with SNI and ALPN enabled and no SCSV cipher",
3918 {0x03, 0x03, 0x37, 0xa6, 0x4b, 0x58, 0x02, 0xd0, 0x77, 0xe4, 0x48, 0xaf,
3919 0x90, 0x50, 0x45, 0xd5, 0x2f, 0xe7, 0x98, 0x5d, 0x54, 0x93, 0x85, 0x3a,
3920 0xde, 0xb6, 0xaa, 0x47, 0xef, 0x7f, 0xb5, 0x52, 0xe6, 0xf8, 0x00, 0x00,
3921 0x02, 0xc0, 0x24, 0x01, 0x00, 0x00, 0x87, 0x00, 0x0a, 0x00, 0x16, 0x00,
3922 0x14, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x09, 0x00, 0x0a, 0x00,
3923 0x0b, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x16, 0x00, 0x0b, 0x00,
3924 0x02, 0x01, 0x00, 0x00, 0x0d, 0x00, 0x1c, 0x00, 0x1a, 0x06, 0x03, 0x06,
3925 0x01, 0x05, 0x03, 0x05, 0x01, 0x04, 0x03, 0x04, 0x01, 0x04, 0x02, 0x03,
3926 0x03, 0x03, 0x01, 0x03, 0x02, 0x02, 0x03, 0x02, 0x01, 0x02, 0x02, 0x00,
3927 0x00, 0x00, 0x10, 0x00, 0x0e, 0x00, 0x00, 0x0b, 0x65, 0x78, 0x61, 0x6d,
3928 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x11, 0x00, 0x10, 0x00,
3929 0x0e, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00,
3930 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00,
3931 0x00, 0x10, 0x00, 0x0d, 0x00, 0x0b, 0x07, 0x68, 0x74, 0x74, 0x70, 0x31,
3932 0x2e, 0x31, 0x02, 0x68, 0x32, 0xff, 0x01, 0x00, 0x01, 0x00},
3933 true},
3934 {"JDK 9 with EMS extension appended",
3935 {0x03, 0x03, 0x0c, 0xe6, 0x06, 0xc6, 0x5d, 0x38, 0xb4, 0x5e, 0x3a, 0xd5,
3936 0xb0, 0x5f, 0x5b, 0x84, 0x3b, 0xff, 0x86, 0x4f, 0xb0, 0x3f, 0xc1, 0xfd,
3937 0x08, 0xf0, 0x97, 0xf3, 0x56, 0x44, 0x08, 0xe2, 0xdd, 0x2a, 0x00, 0x00,
3938 0x64, 0xc0, 0x2c, 0xc0, 0x2b, 0xc0, 0x30, 0x00, 0x9d, 0xc0, 0x2e, 0xc0,
3939 0x32, 0x00, 0x9f, 0x00, 0xa3, 0xc0, 0x2f, 0x00, 0x9c, 0xc0, 0x2d, 0xc0,
3940 0x31, 0x00, 0x9e, 0x00, 0xa2, 0xc0, 0x24, 0xc0, 0x28, 0x00, 0x3d, 0xc0,
3941 0x26, 0xc0, 0x2a, 0x00, 0x6b, 0x00, 0x6a, 0xc0, 0x0a, 0xc0, 0x14, 0x00,
3942 0x35, 0xc0, 0x05, 0xc0, 0x0f, 0x00, 0x39, 0x00, 0x38, 0xc0, 0x23, 0xc0,
3943 0x27, 0x00, 0x3c, 0xc0, 0x25, 0xc0, 0x29, 0x00, 0x67, 0x00, 0x40, 0xc0,
3944 0x09, 0xc0, 0x13, 0x00, 0x2f, 0xc0, 0x04, 0xc0, 0x0e, 0x00, 0x33, 0x00,
3945 0x32, 0xc0, 0x08, 0xc0, 0x12, 0x00, 0x0a, 0xc0, 0x03, 0xc0, 0x0d, 0x00,
3946 0x16, 0x00, 0x13, 0x00, 0xff, 0x01, 0x00, 0x00, 0x61, 0x00, 0x0a, 0x00,
3947 0x16, 0x00, 0x14, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x09, 0x00,
3948 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x16, 0x00,
3949 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x0d, 0x00, 0x1c, 0x00, 0x1a, 0x06,
3950 0x03, 0x06, 0x01, 0x05, 0x03, 0x05, 0x01, 0x04, 0x03, 0x04, 0x01, 0x04,
3951 0x02, 0x03, 0x03, 0x03, 0x01, 0x03, 0x02, 0x02, 0x03, 0x02, 0x01, 0x02,
3952 0x02, 0x00, 0x11, 0x00, 0x10, 0x00, 0x0e, 0x02, 0x00, 0x04, 0x00, 0x00,
3953 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00,
3954 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00},
3955 false},
3956 {"Chrome 61",
3957 {0x03, 0x03, 0x33, 0x43, 0x8a, 0x6f, 0x76, 0xdd, 0x84, 0x3f, 0x8d, 0xaa,
3958 0x43, 0xf1, 0x86, 0xee, 0xdd, 0x97, 0x96, 0x54, 0xf6, 0x17, 0x2c, 0xde,
3959 0x69, 0xfe, 0x5e, 0x53, 0xaa, 0x47, 0xee, 0xad, 0xd7, 0x47, 0x00, 0x00,
3960 0x1c, 0x3a, 0x3a, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xcc,
3961 0xa9, 0xcc, 0xa8, 0xc0, 0x13, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d, 0x00,
3962 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x77, 0x8a, 0x8a, 0x00,
3963 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x0c,
3964 0x00, 0x00, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74,
3965 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x14,
3966 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05,
3967 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x00, 0x05, 0x00, 0x05,
3968 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x10, 0x00,
3969 0x0e, 0x00, 0x0c, 0x02, 0x68, 0x32, 0x08, 0x68, 0x74, 0x74, 0x70, 0x2f,
3970 0x31, 0x2e, 0x31, 0x75, 0x50, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01,
3971 0x00, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x08, 0x4a, 0x4a, 0x00, 0x1d, 0x00,
3972 0x17, 0x00, 0x18, 0x6a, 0x6a, 0x00, 0x01, 0x00},
3973 false},
3974 {"Firefox 55",
3975 {0x03, 0x03, 0x06, 0x8e, 0xf8, 0xf7, 0x7a, 0xfd, 0xce, 0x45, 0xb0, 0x39,
3976 0xbe, 0xa4, 0x55, 0x27, 0xe2, 0x80, 0xc4, 0x0a, 0xbd, 0xce, 0x56, 0x7a,
3977 0xbc, 0x1f, 0x26, 0x2f, 0xfa, 0xb9, 0xa1, 0x7e, 0xe6, 0xde, 0x00, 0x00,
3978 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x2c, 0xc0,
3979 0x30, 0xc0, 0x0a, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x14, 0x00, 0x33, 0x00,
3980 0x39, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x6a, 0x00,
3981 0x00, 0x00, 0x0e, 0x00, 0x0c, 0x00, 0x00, 0x09, 0x6c, 0x6f, 0x63, 0x61,
3982 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00,
3983 0x01, 0x00, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x1d, 0x00, 0x17,
3984 0x00, 0x18, 0x00, 0x19, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23,
3985 0x00, 0x00, 0x00, 0x10, 0x00, 0x0e, 0x00, 0x0c, 0x02, 0x68, 0x32, 0x08,
3986 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31, 0x00, 0x05, 0x00, 0x05,
3987 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x18, 0x00, 0x16, 0x04,
3988 0x03, 0x05, 0x03, 0x06, 0x03, 0x08, 0x04, 0x08, 0x05, 0x08, 0x06, 0x04,
3989 0x01, 0x05, 0x01, 0x06, 0x01, 0x02, 0x03, 0x02, 0x01},
3990 false},
3991 };
3992 for (const auto &t : kTests) {
3993 SCOPED_TRACE(t.name);
3994
3995 bssl::SSLMessage msg;
3996 msg.is_v2_hello = false;
3997 msg.type = SSL3_MT_CLIENT_HELLO;
3998 CBS_init(&msg.body, t.in.data(), t.in.size());
3999 CBS_init(&msg.raw, nullptr, 0); // unused
4000
4001 SSL_CLIENT_HELLO client_hello;
4002 ASSERT_TRUE(bssl::ssl_client_hello_init(ssl.get(), &client_hello, msg));
4003 EXPECT_EQ(t.is_probably_java, bssl::ssl_is_probably_java(&client_hello));
4004 }
4005}
4006
David Benjamin96628432017-01-19 19:05:47 -05004007// TODO(davidben): Convert this file to GTest properly.
4008TEST(SSLTest, AllTests) {
David Benjamine11726a2017-04-23 12:14:28 -04004009 if (!TestSSL_SESSIONEncoding(kOpenSSLSession) ||
Adam Langley10f97f32016-07-12 08:09:33 -07004010 !TestSSL_SESSIONEncoding(kCustomSession) ||
4011 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
4012 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
4013 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
4014 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
Steven Valdeza833c352016-11-01 13:39:36 -04004015 // Test the padding extension at TLS 1.2.
4016 !TestPaddingExtension(TLS1_2_VERSION, TLS1_2_VERSION) ||
4017 // Test the padding extension at TLS 1.3 with a TLS 1.2 session, so there
4018 // will be no PSK binder after the padding extension.
4019 !TestPaddingExtension(TLS1_3_VERSION, TLS1_2_VERSION) ||
4020 // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
4021 // will be a PSK binder after the padding extension.
4022 !TestPaddingExtension(TLS1_3_VERSION, TLS1_3_DRAFT_VERSION) ||
Martin Kreichgauer1a663262017-08-16 14:54:04 -07004023 !TestClientHello()) {
David Benjamin96628432017-01-19 19:05:47 -05004024 ADD_FAILURE() << "Tests failed";
David Benjaminbb0a17c2014-09-20 15:35:39 -04004025 }
David Benjamin2e521212014-07-16 14:37:51 -04004026}
Martin Kreichgauer72912d22017-08-04 12:06:43 -07004027
4028} // namespace
4029} // namespace bssl