blob: 4653f734c523d212ae595a488d90f85453e7d907 [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;
David Benjamin9eaa3bd2017-09-27 17:03:54 -04001402 lh_SSL_SESSION_doall_arg(ctx->sessions, AppendSession, &actual);
David Benjaminc79ae7a2017-08-29 16:09:44 -04001403 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 Benjamin737d2df2017-09-25 15:05:19 -04001944// Tests that our ClientHellos do not change unexpectedly. These are purely
1945// change detection tests. If they fail as part of an intentional ClientHello
1946// change, update the test vector.
1947TEST(SSLTest, ClientHello) {
1948 struct {
1949 uint16_t max_version;
1950 std::vector<uint8_t> expected;
1951 } kTests[] = {
1952 {SSL3_VERSION,
1953 {0x16, 0x03, 0x00, 0x00, 0x3b, 0x01, 0x00, 0x00, 0x37, 0x03, 0x00,
1954 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1955 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1956 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1957 0x00, 0x10, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00,
1958 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x00, 0xff, 0x01, 0x00}},
1959 {TLS1_VERSION,
1960 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x01, 0x00,
1961 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1962 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1963 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
1964 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001965 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1966 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
David Benjamin737d2df2017-09-25 15:05:19 -04001967 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18}},
1968 {TLS1_1_VERSION,
1969 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x02, 0x00,
1970 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1971 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1972 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
1973 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001974 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1975 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
David Benjamin737d2df2017-09-25 15:05:19 -04001976 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18}},
1977 // This test assumes RSA-PSS, which is disabled for Android system builds.
1978#if !defined(BORINGSSL_ANDROID_SYSTEM)
1979 {TLS1_2_VERSION,
1980 {0x16, 0x03, 0x01, 0x00, 0x8e, 0x01, 0x00, 0x00, 0x8a, 0x03, 0x03, 0x00,
1981 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1982 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1983 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0xcc, 0xa9,
1984 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xc0, 0x09,
1985 0xc0, 0x23, 0xc0, 0x13, 0xc0, 0x27, 0xc0, 0x0a, 0xc0, 0x24, 0xc0, 0x14,
1986 0xc0, 0x28, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x3c, 0x00, 0x35,
1987 0x00, 0x3d, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37, 0xff, 0x01, 0x00, 0x01,
1988 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
1989 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
1990 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x00, 0x0b, 0x00,
1991 0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00,
1992 0x17, 0x00, 0x18}},
David Benjamin3b584332017-01-24 22:47:18 -05001993#endif
David Benjamin737d2df2017-09-25 15:05:19 -04001994 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
1995 // implementation has settled enough that it won't change.
David Benjaminafc64de2016-07-19 17:12:41 +02001996 };
David Benjamin737d2df2017-09-25 15:05:19 -04001997
1998 for (const auto &t : kTests) {
1999 SCOPED_TRACE(t.max_version);
2000
2001 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2002 ASSERT_TRUE(ctx);
2003 // Our default cipher list varies by CPU capabilities, so manually place the
2004 // ChaCha20 ciphers in front.
2005 const char *cipher_list = "CHACHA20:ALL";
2006 // SSLv3 is off by default.
2007 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION));
2008 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), t.max_version));
2009 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list));
2010
2011 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
2012 ASSERT_TRUE(ssl);
2013 std::vector<uint8_t> client_hello;
2014 ASSERT_TRUE(GetClientHello(ssl.get(), &client_hello));
2015
2016 // Zero the client_random.
2017 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
2018 1 + 3 + // handshake message header
2019 2; // client_version
2020 ASSERT_GE(client_hello.size(), kRandomOffset + SSL3_RANDOM_SIZE);
2021 OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
2022
2023 if (client_hello != t.expected) {
2024 ADD_FAILURE() << "ClientHellos did not match.";
2025 // Print the value manually so it is easier to update the test vector.
2026 for (size_t i = 0; i < client_hello.size(); i += 12) {
2027 printf(" %c", i == 0 ? '{' : ' ');
2028 for (size_t j = i; j < client_hello.size() && j < i + 12; j++) {
2029 if (j > i) {
2030 printf(" ");
2031 }
2032 printf("0x%02x", client_hello[j]);
2033 if (j < client_hello.size() - 1) {
2034 printf(",");
2035 }
2036 }
2037 if (i + 12 >= client_hello.size()) {
2038 printf("}}");
2039 }
2040 printf("\n");
2041 }
2042 }
David Benjaminafc64de2016-07-19 17:12:41 +02002043 }
David Benjaminafc64de2016-07-19 17:12:41 +02002044}
2045
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002046static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04002047
2048static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
2049 // Save the most recent session.
2050 g_last_session.reset(session);
2051 return 1;
2052}
2053
David Benjamina8614602017-09-06 15:40:19 -04002054static bssl::UniquePtr<SSL_SESSION> CreateClientSession(
2055 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2056 const ClientConfig &config = ClientConfig()) {
David Benjamina20e5352016-08-02 19:09:41 -04002057 g_last_session = nullptr;
2058 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2059
2060 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002061 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04002062 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
David Benjamina8614602017-09-06 15:40:19 -04002063 config)) {
David Benjamina20e5352016-08-02 19:09:41 -04002064 fprintf(stderr, "Failed to connect client and server.\n");
2065 return nullptr;
2066 }
2067
2068 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2069 SSL_read(client.get(), nullptr, 0);
2070
2071 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2072
2073 if (!g_last_session) {
2074 fprintf(stderr, "Client did not receive a session.\n");
2075 return nullptr;
2076 }
2077 return std::move(g_last_session);
2078}
2079
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002080static void ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2081 SSL_SESSION *session, bool want_reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002082 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002083 ClientConfig config;
2084 config.session = session;
2085 EXPECT_TRUE(
2086 ConnectClientAndServer(&client, &server, client_ctx, server_ctx, config));
David Benjamina20e5352016-08-02 19:09:41 -04002087
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002088 EXPECT_EQ(SSL_session_reused(client.get()), SSL_session_reused(server.get()));
David Benjamina20e5352016-08-02 19:09:41 -04002089
2090 bool was_reused = !!SSL_session_reused(client.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002091 EXPECT_EQ(was_reused, want_reused);
David Benjamina20e5352016-08-02 19:09:41 -04002092}
2093
David Benjamin3c51d9b2016-11-01 17:50:42 -04002094static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
2095 SSL_CTX *server_ctx,
2096 SSL_SESSION *session) {
2097 g_last_session = nullptr;
2098 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2099
2100 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002101 ClientConfig config;
2102 config.session = session;
2103 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
2104 config)) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002105 fprintf(stderr, "Failed to connect client and server.\n");
2106 return nullptr;
2107 }
2108
2109 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2110 fprintf(stderr, "Client and server were inconsistent.\n");
2111 return nullptr;
2112 }
2113
2114 if (!SSL_session_reused(client.get())) {
2115 fprintf(stderr, "Session was not reused.\n");
2116 return nullptr;
2117 }
2118
2119 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2120 SSL_read(client.get(), nullptr, 0);
2121
2122 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2123
2124 if (!g_last_session) {
2125 fprintf(stderr, "Client did not receive a renewed session.\n");
2126 return nullptr;
2127 }
2128 return std::move(g_last_session);
2129}
2130
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002131static void ExpectTicketKeyChanged(SSL_CTX *ctx, uint8_t *inout_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002132 bool changed) {
2133 uint8_t new_key[kTicketKeyLen];
David Benjaminc11ea9422017-08-29 16:33:21 -04002134 // May return 0, 1 or 48.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002135 ASSERT_EQ(SSL_CTX_get_tlsext_ticket_keys(ctx, new_key, kTicketKeyLen), 1);
2136 if (changed) {
2137 ASSERT_NE(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
2138 } else {
2139 ASSERT_EQ(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002140 }
2141 OPENSSL_memcpy(inout_key, new_key, kTicketKeyLen);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002142}
2143
David Benjamina933c382016-10-28 00:10:03 -04002144static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
2145 static const uint8_t kContext[] = {3};
2146
2147 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
2148 return SSL_TLSEXT_ERR_ALERT_FATAL;
2149 }
2150
2151 return SSL_TLSEXT_ERR_OK;
2152}
2153
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002154TEST_P(SSLVersionTest, SessionIDContext) {
David Benjamina20e5352016-08-02 19:09:41 -04002155 static const uint8_t kContext1[] = {1};
2156 static const uint8_t kContext2[] = {2};
2157
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002158 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2159 sizeof(kContext1)));
David Benjamina20e5352016-08-02 19:09:41 -04002160
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002161 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2162 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002163
David Benjamin0fef3052016-11-18 15:11:10 +09002164 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002165 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2166 ASSERT_TRUE(session);
David Benjamina20e5352016-08-02 19:09:41 -04002167
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002168 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2169 session.get(),
2170 true /* expect session reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002171
David Benjamin0fef3052016-11-18 15:11:10 +09002172 // Change the session ID context.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002173 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext2,
2174 sizeof(kContext2)));
David Benjamina20e5352016-08-02 19:09:41 -04002175
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002176 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2177 session.get(),
2178 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002179
David Benjamin0fef3052016-11-18 15:11:10 +09002180 // Change the session ID context back and install an SNI callback to switch
2181 // it.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002182 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2183 sizeof(kContext1)));
David Benjamina933c382016-10-28 00:10:03 -04002184
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002185 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09002186 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04002187
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002188 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2189 session.get(),
2190 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002191
David Benjamin0fef3052016-11-18 15:11:10 +09002192 // Switch the session ID context with the early callback instead.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002193 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), nullptr);
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002194 SSL_CTX_set_select_certificate_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002195 server_ctx_.get(),
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002196 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
2197 static const uint8_t kContext[] = {3};
2198
2199 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
2200 sizeof(kContext))) {
2201 return ssl_select_cert_error;
2202 }
2203
2204 return ssl_select_cert_success;
2205 });
David Benjamina933c382016-10-28 00:10:03 -04002206
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002207 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2208 session.get(),
2209 false /* expect session not reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002210}
2211
David Benjamin721e8b72016-08-03 13:13:17 -04002212static timeval g_current_time;
2213
2214static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2215 *out_clock = g_current_time;
2216}
2217
David Benjamin17b30832017-01-28 14:00:32 -05002218static void FrozenTimeCallback(const SSL *ssl, timeval *out_clock) {
2219 out_clock->tv_sec = 1000;
2220 out_clock->tv_usec = 0;
2221}
2222
David Benjamin3c51d9b2016-11-01 17:50:42 -04002223static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
2224 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
2225 int encrypt) {
2226 static const uint8_t kZeros[16] = {0};
2227
2228 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -05002229 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamin3c51d9b2016-11-01 17:50:42 -04002230 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -05002231 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002232 return 0;
2233 }
2234
2235 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
2236 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
2237 return -1;
2238 }
2239
2240 // Returning two from the callback in decrypt mode renews the
2241 // session in TLS 1.2 and below.
2242 return encrypt ? 1 : 2;
2243}
2244
David Benjamin123db572016-11-03 16:59:25 -04002245static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjamin123db572016-11-03 16:59:25 -04002246 if (session->tlsext_ticklen < 16 + 16 + SHA256_DIGEST_LENGTH) {
2247 return false;
2248 }
2249
David Benjamin123db572016-11-03 16:59:25 -04002250 const uint8_t *ciphertext = session->tlsext_tick + 16 + 16;
2251 size_t len = session->tlsext_ticklen - 16 - 16 - SHA256_DIGEST_LENGTH;
2252 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
2253
David Benjamin9b63f292016-11-15 00:44:05 -05002254#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
2255 // Fuzzer-mode tickets are unencrypted.
David Benjamin17cf2cb2016-12-13 01:07:13 -05002256 OPENSSL_memcpy(plaintext.get(), ciphertext, len);
David Benjamin9b63f292016-11-15 00:44:05 -05002257#else
2258 static const uint8_t kZeros[16] = {0};
2259 const uint8_t *iv = session->tlsext_tick + 16;
David Benjamin123db572016-11-03 16:59:25 -04002260 bssl::ScopedEVP_CIPHER_CTX ctx;
2261 int len1, len2;
2262 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
2263 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
2264 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
2265 return false;
2266 }
2267
2268 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05002269#endif
David Benjamin123db572016-11-03 16:59:25 -04002270
Adam Langley46db7af2017-02-01 15:49:37 -08002271 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
2272 if (!ssl_ctx) {
2273 return false;
2274 }
David Benjamin123db572016-11-03 16:59:25 -04002275 bssl::UniquePtr<SSL_SESSION> server_session(
Adam Langley46db7af2017-02-01 15:49:37 -08002276 SSL_SESSION_from_bytes(plaintext.get(), len, ssl_ctx.get()));
David Benjamin123db572016-11-03 16:59:25 -04002277 if (!server_session) {
2278 return false;
2279 }
2280
2281 *out = server_session->time;
2282 return true;
2283}
2284
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002285TEST_P(SSLVersionTest, SessionTimeout) {
2286 for (bool server_test : {false, true}) {
2287 SCOPED_TRACE(server_test);
David Benjamin721e8b72016-08-03 13:13:17 -04002288
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002289 ResetContexts();
2290 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2291 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
2292
David Benjamin17b30832017-01-28 14:00:32 -05002293 static const time_t kStartTime = 1000;
David Benjamin0fef3052016-11-18 15:11:10 +09002294 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002295
David Benjamin17b30832017-01-28 14:00:32 -05002296 // We are willing to use a longer lifetime for TLS 1.3 sessions as
2297 // resumptions still perform ECDHE.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002298 const time_t timeout = version() == TLS1_3_VERSION
David Benjamin17b30832017-01-28 14:00:32 -05002299 ? SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT
2300 : SSL_DEFAULT_SESSION_TIMEOUT;
2301
David Benjamin17b30832017-01-28 14:00:32 -05002302 // Both client and server must enforce session timeouts. We configure the
2303 // other side with a frozen clock so it never expires tickets.
David Benjamin0fef3052016-11-18 15:11:10 +09002304 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002305 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2306 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002307 } else {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002308 SSL_CTX_set_current_time_cb(client_ctx_.get(), CurrentTimeCallback);
2309 SSL_CTX_set_current_time_cb(server_ctx_.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002310 }
2311
2312 // Configure a ticket callback which renews tickets.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002313 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002314
2315 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002316 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2317 ASSERT_TRUE(session);
David Benjamin0fef3052016-11-18 15:11:10 +09002318
2319 // Advance the clock just behind the timeout.
David Benjamin17b30832017-01-28 14:00:32 -05002320 g_current_time.tv_sec += timeout - 1;
David Benjamin0fef3052016-11-18 15:11:10 +09002321
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002322 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2323 session.get(),
2324 true /* expect session reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002325
2326 // Advance the clock one more second.
2327 g_current_time.tv_sec++;
2328
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002329 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2330 session.get(),
2331 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002332
2333 // Rewind the clock to before the session was minted.
2334 g_current_time.tv_sec = kStartTime - 1;
2335
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002336 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2337 session.get(),
2338 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002339
2340 // SSL 3.0 cannot renew sessions.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002341 if (version() == SSL3_VERSION) {
David Benjamin0fef3052016-11-18 15:11:10 +09002342 continue;
2343 }
2344
2345 // Renew the session 10 seconds before expiration.
David Benjamin17b30832017-01-28 14:00:32 -05002346 time_t new_start_time = kStartTime + timeout - 10;
2347 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002348 bssl::UniquePtr<SSL_SESSION> new_session = ExpectSessionRenewed(
2349 client_ctx_.get(), server_ctx_.get(), session.get());
2350 ASSERT_TRUE(new_session);
David Benjamin0fef3052016-11-18 15:11:10 +09002351
2352 // This new session is not the same object as before.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002353 EXPECT_NE(session.get(), new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002354
2355 // Check the sessions have timestamps measured from issuance.
2356 long session_time = 0;
2357 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002358 ASSERT_TRUE(GetServerTicketTime(&session_time, new_session.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09002359 } else {
2360 session_time = new_session->time;
2361 }
David Benjamin721e8b72016-08-03 13:13:17 -04002362
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002363 ASSERT_EQ(session_time, g_current_time.tv_sec);
David Benjamin721e8b72016-08-03 13:13:17 -04002364
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002365 if (version() == TLS1_3_VERSION) {
David Benjamin17b30832017-01-28 14:00:32 -05002366 // Renewal incorporates fresh key material in TLS 1.3, so we extend the
2367 // lifetime TLS 1.3.
2368 g_current_time.tv_sec = new_start_time + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002369 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2370 new_session.get(),
2371 true /* expect session reused */));
David Benjamin721e8b72016-08-03 13:13:17 -04002372
David Benjamin17b30832017-01-28 14:00:32 -05002373 // The new session expires after the new timeout.
2374 g_current_time.tv_sec = new_start_time + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002375 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2376 new_session.get(),
2377 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002378
2379 // Renew the session until it begins just past the auth timeout.
2380 time_t auth_end_time = kStartTime + SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
2381 while (new_start_time < auth_end_time - 1000) {
2382 // Get as close as possible to target start time.
2383 new_start_time =
2384 std::min(auth_end_time - 1000, new_start_time + timeout - 1);
2385 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002386 new_session = ExpectSessionRenewed(client_ctx_.get(), server_ctx_.get(),
David Benjamin17b30832017-01-28 14:00:32 -05002387 new_session.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002388 ASSERT_TRUE(new_session);
David Benjamin17b30832017-01-28 14:00:32 -05002389 }
2390
2391 // Now the session's lifetime is bound by the auth timeout.
2392 g_current_time.tv_sec = auth_end_time - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002393 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2394 new_session.get(),
2395 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002396
2397 g_current_time.tv_sec = auth_end_time + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002398 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2399 new_session.get(),
2400 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002401 } else {
2402 // The new session is usable just before the old expiration.
2403 g_current_time.tv_sec = kStartTime + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002404 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2405 new_session.get(),
2406 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002407
2408 // Renewal does not extend the lifetime, so it is not usable beyond the
2409 // old expiration.
2410 g_current_time.tv_sec = kStartTime + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002411 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2412 new_session.get(),
2413 false /* expect session not reused */));
David Benjamin1b22f852016-10-27 16:36:32 -04002414 }
David Benjamin721e8b72016-08-03 13:13:17 -04002415 }
David Benjamin721e8b72016-08-03 13:13:17 -04002416}
2417
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002418TEST_P(SSLVersionTest, DefaultTicketKeyInitialization) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002419 static const uint8_t kZeroKey[kTicketKeyLen] = {};
2420 uint8_t ticket_key[kTicketKeyLen];
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002421 ASSERT_EQ(1, SSL_CTX_get_tlsext_ticket_keys(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002422 kTicketKeyLen));
2423 ASSERT_NE(0, OPENSSL_memcmp(ticket_key, kZeroKey, kTicketKeyLen));
2424}
2425
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002426TEST_P(SSLVersionTest, DefaultTicketKeyRotation) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002427 if (GetParam().version == SSL3_VERSION) {
2428 return;
2429 }
2430
2431 static const time_t kStartTime = 1001;
2432 g_current_time.tv_sec = kStartTime;
2433 uint8_t ticket_key[kTicketKeyLen];
2434
David Benjaminc11ea9422017-08-29 16:33:21 -04002435 // We use session reuse as a proxy for ticket decryption success, hence
2436 // disable session timeouts.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002437 SSL_CTX_set_timeout(server_ctx_.get(), std::numeric_limits<uint32_t>::max());
2438 SSL_CTX_set_session_psk_dhe_timeout(server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002439 std::numeric_limits<uint32_t>::max());
2440
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002441 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2442 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002443
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002444 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2445 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_OFF);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002446
David Benjaminc11ea9422017-08-29 16:33:21 -04002447 // Initialize ticket_key with the current key.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002448 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2449 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002450
David Benjaminc11ea9422017-08-29 16:33:21 -04002451 // Verify ticket resumption actually works.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002452 bssl::UniquePtr<SSL> client, server;
2453 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002454 CreateClientSession(client_ctx_.get(), server_ctx_.get());
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002455 ASSERT_TRUE(session);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002456 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002457 session.get(), true /* reused */));
2458
David Benjaminc11ea9422017-08-29 16:33:21 -04002459 // Advance time to just before key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002460 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002461 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002462 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002463 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002464 false /* NOT changed */));
2465
David Benjaminc11ea9422017-08-29 16:33:21 -04002466 // Force key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002467 g_current_time.tv_sec += 1;
2468 bssl::UniquePtr<SSL_SESSION> new_session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002469 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2470 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2471 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002472
David Benjaminc11ea9422017-08-29 16:33:21 -04002473 // Resumption with both old and new ticket should work.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002474 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002475 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002476 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002477 new_session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002478 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002479 false /* NOT changed */));
2480
David Benjaminc11ea9422017-08-29 16:33:21 -04002481 // Force key rotation again. Resumption with the old ticket now fails.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002482 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002483 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002484 session.get(), false /* NOT reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002485 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2486 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002487
David Benjaminc11ea9422017-08-29 16:33:21 -04002488 // But resumption with the newer session still works.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002489 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002490 new_session.get(), true /* reused */));
2491}
2492
David Benjamin0fc37ef2016-08-17 15:29:46 -04002493static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002494 SSL_CTX *ctx = reinterpret_cast<SSL_CTX *>(arg);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002495 SSL_set_SSL_CTX(ssl, ctx);
2496 return SSL_TLSEXT_ERR_OK;
2497}
2498
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002499TEST_P(SSLVersionTest, SNICallback) {
David Benjamin0fef3052016-11-18 15:11:10 +09002500 // SSL 3.0 lacks extensions.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002501 if (version() == SSL3_VERSION) {
2502 return;
David Benjamin0fef3052016-11-18 15:11:10 +09002503 }
2504
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002505 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002506 ASSERT_TRUE(cert2);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002507 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002508 ASSERT_TRUE(key2);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002509
David Benjamin0fef3052016-11-18 15:11:10 +09002510 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
2511 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002512
David Benjamin83a32122017-02-14 18:34:54 -05002513 static const uint8_t kSCTList[] = {0, 6, 0, 4, 5, 6, 7, 8};
2514 static const uint8_t kOCSPResponse[] = {1, 2, 3, 4};
2515
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002516 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
2517 ASSERT_TRUE(server_ctx2);
2518 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()));
2519 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()));
2520 ASSERT_TRUE(SSL_CTX_set_signed_cert_timestamp_list(
2521 server_ctx2.get(), kSCTList, sizeof(kSCTList)));
2522 ASSERT_TRUE(SSL_CTX_set_ocsp_response(server_ctx2.get(), kOCSPResponse,
2523 sizeof(kOCSPResponse)));
2524 // Historically signing preferences would be lost in some cases with the
2525 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2526 // this doesn't happen when |version| is TLS 1.2, configure the private
2527 // key to only sign SHA-256.
2528 ASSERT_TRUE(SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
2529 &kECDSAWithSHA256, 1));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002530
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002531 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), SwitchContext);
2532 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002533
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002534 SSL_CTX_enable_signed_cert_timestamps(client_ctx_.get());
2535 SSL_CTX_enable_ocsp_stapling(client_ctx_.get());
David Benjamin83a32122017-02-14 18:34:54 -05002536
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002537 ASSERT_TRUE(Connect());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002538
David Benjamin0fef3052016-11-18 15:11:10 +09002539 // The client should have received |cert2|.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002540 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client_.get()));
2541 ASSERT_TRUE(peer);
2542 EXPECT_EQ(X509_cmp(peer.get(), cert2.get()), 0);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002543
David Benjamin83a32122017-02-14 18:34:54 -05002544 // The client should have received |server_ctx2|'s SCT list.
2545 const uint8_t *data;
2546 size_t len;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002547 SSL_get0_signed_cert_timestamp_list(client_.get(), &data, &len);
2548 EXPECT_EQ(Bytes(kSCTList), Bytes(data, len));
David Benjamin83a32122017-02-14 18:34:54 -05002549
2550 // The client should have received |server_ctx2|'s OCSP response.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002551 SSL_get0_ocsp_response(client_.get(), &data, &len);
2552 EXPECT_EQ(Bytes(kOCSPResponse), Bytes(data, len));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002553}
2554
David Benjaminf0d8e222017-02-04 10:58:26 -05002555// Test that the early callback can swap the maximum version.
2556TEST(SSLTest, EarlyCallbackVersionSwitch) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002557 bssl::UniquePtr<X509> cert = GetTestCertificate();
2558 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2559 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2560 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002561 ASSERT_TRUE(cert);
2562 ASSERT_TRUE(key);
2563 ASSERT_TRUE(server_ctx);
2564 ASSERT_TRUE(client_ctx);
2565 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
2566 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
2567 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
2568 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
David Benjamin99620572016-08-30 00:35:36 -04002569
David Benjaminf0d8e222017-02-04 10:58:26 -05002570 SSL_CTX_set_select_certificate_cb(
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002571 server_ctx.get(),
2572 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
David Benjaminf0d8e222017-02-04 10:58:26 -05002573 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002574 return ssl_select_cert_error;
David Benjaminf0d8e222017-02-04 10:58:26 -05002575 }
2576
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002577 return ssl_select_cert_success;
David Benjaminf0d8e222017-02-04 10:58:26 -05002578 });
David Benjamin99620572016-08-30 00:35:36 -04002579
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002580 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05002581 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04002582 server_ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002583 EXPECT_EQ(TLS1_2_VERSION, SSL_version(client.get()));
David Benjamin99620572016-08-30 00:35:36 -04002584}
2585
David Benjaminf0d8e222017-02-04 10:58:26 -05002586TEST(SSLTest, SetVersion) {
David Benjamin2dc02042016-09-19 19:57:37 -04002587 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002588 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002589
David Benjaminf0d8e222017-02-04 10:58:26 -05002590 // Set valid TLS versions.
2591 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2592 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
2593 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2594 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002595
David Benjaminf0d8e222017-02-04 10:58:26 -05002596 // Invalid TLS versions are rejected.
2597 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2598 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x0200));
2599 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2600 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2601 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x0200));
2602 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002603
David Benjaminf0d8e222017-02-04 10:58:26 -05002604 // Zero is the default version.
2605 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002606 EXPECT_EQ(TLS1_2_VERSION, ctx->conf_max_version);
David Benjaminf0d8e222017-02-04 10:58:26 -05002607 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002608 EXPECT_EQ(TLS1_VERSION, ctx->conf_min_version);
David Benjamin3cfeb952017-03-01 16:48:38 -05002609
2610 // SSL 3.0 and TLS 1.3 are available, but not by default.
2611 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002612 EXPECT_EQ(SSL3_VERSION, ctx->conf_min_version);
David Benjamin3cfeb952017-03-01 16:48:38 -05002613 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002614 EXPECT_EQ(TLS1_3_VERSION, ctx->conf_max_version);
David Benjamine34bcc92016-09-21 16:53:09 -04002615
David Benjamin353577c2017-06-29 15:54:58 -04002616 // TLS1_3_DRAFT_VERSION is not an API-level version.
2617 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_DRAFT_VERSION));
2618 ERR_clear_error();
2619
David Benjamin2dc02042016-09-19 19:57:37 -04002620 ctx.reset(SSL_CTX_new(DTLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002621 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002622
David Benjaminf0d8e222017-02-04 10:58:26 -05002623 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2624 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION));
2625 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2626 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002627
David Benjaminf0d8e222017-02-04 10:58:26 -05002628 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2629 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2630 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2631 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2632 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2633 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2634 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2635 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002636
David Benjaminf0d8e222017-02-04 10:58:26 -05002637 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002638 EXPECT_EQ(TLS1_2_VERSION, ctx->conf_max_version);
David Benjaminf0d8e222017-02-04 10:58:26 -05002639 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002640 EXPECT_EQ(TLS1_1_VERSION, ctx->conf_min_version);
David Benjamin2dc02042016-09-19 19:57:37 -04002641}
2642
David Benjamin458334a2016-12-15 13:53:25 -05002643static const char *GetVersionName(uint16_t version) {
2644 switch (version) {
2645 case SSL3_VERSION:
2646 return "SSLv3";
2647 case TLS1_VERSION:
2648 return "TLSv1";
2649 case TLS1_1_VERSION:
2650 return "TLSv1.1";
2651 case TLS1_2_VERSION:
2652 return "TLSv1.2";
2653 case TLS1_3_VERSION:
2654 return "TLSv1.3";
2655 case DTLS1_VERSION:
2656 return "DTLSv1";
2657 case DTLS1_2_VERSION:
2658 return "DTLSv1.2";
2659 default:
2660 return "???";
2661 }
2662}
2663
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002664TEST_P(SSLVersionTest, Version) {
2665 ASSERT_TRUE(Connect());
David Benjamincb18ac22016-09-27 14:09:15 -04002666
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002667 EXPECT_EQ(SSL_version(client_.get()), version());
2668 EXPECT_EQ(SSL_version(server_.get()), version());
David Benjamincb18ac22016-09-27 14:09:15 -04002669
David Benjamin458334a2016-12-15 13:53:25 -05002670 // Test the version name is reported as expected.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002671 const char *version_name = GetVersionName(version());
2672 EXPECT_EQ(strcmp(version_name, SSL_get_version(client_.get())), 0);
2673 EXPECT_EQ(strcmp(version_name, SSL_get_version(server_.get())), 0);
David Benjamin458334a2016-12-15 13:53:25 -05002674
2675 // Test SSL_SESSION reports the same name.
2676 const char *client_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002677 SSL_SESSION_get_version(SSL_get_session(client_.get()));
David Benjamin458334a2016-12-15 13:53:25 -05002678 const char *server_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002679 SSL_SESSION_get_version(SSL_get_session(server_.get()));
2680 EXPECT_EQ(strcmp(version_name, client_name), 0);
2681 EXPECT_EQ(strcmp(version_name, server_name), 0);
David Benjamincb18ac22016-09-27 14:09:15 -04002682}
2683
David Benjamin9ef31f02016-10-31 18:01:13 -04002684// Tests that that |SSL_get_pending_cipher| is available during the ALPN
2685// selection callback.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002686TEST_P(SSLVersionTest, ALPNCipherAvailable) {
David Benjamin0fef3052016-11-18 15:11:10 +09002687 // SSL 3.0 lacks extensions.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002688 if (version() == SSL3_VERSION) {
2689 return;
David Benjamin0fef3052016-11-18 15:11:10 +09002690 }
2691
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002692 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2693
David Benjamin9ef31f02016-10-31 18:01:13 -04002694 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002695 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
2696 sizeof(kALPNProtos)),
2697 0);
David Benjamin0fef3052016-11-18 15:11:10 +09002698
2699 // The ALPN callback does not fail the handshake on error, so have the
2700 // callback write a boolean.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002701 std::pair<uint16_t, bool> callback_state(version(), false);
David Benjamin0fef3052016-11-18 15:11:10 +09002702 SSL_CTX_set_alpn_select_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002703 server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09002704 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
2705 unsigned in_len, void *arg) -> int {
2706 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
2707 if (SSL_get_pending_cipher(ssl) != nullptr &&
2708 SSL_version(ssl) == state->first) {
2709 state->second = true;
2710 }
2711 return SSL_TLSEXT_ERR_NOACK;
2712 },
2713 &callback_state);
2714
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002715 ASSERT_TRUE(Connect());
David Benjamin0fef3052016-11-18 15:11:10 +09002716
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002717 ASSERT_TRUE(callback_state.second);
David Benjamin0fef3052016-11-18 15:11:10 +09002718}
2719
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002720TEST_P(SSLVersionTest, SSLClearSessionResumption) {
David Benjaminb79cc842016-12-07 15:57:14 -05002721 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
2722 // API pattern.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002723 if (version() == TLS1_3_VERSION) {
2724 return;
David Benjaminb79cc842016-12-07 15:57:14 -05002725 }
2726
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002727 ASSERT_TRUE(Connect());
David Benjaminb79cc842016-12-07 15:57:14 -05002728
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002729 EXPECT_FALSE(SSL_session_reused(client_.get()));
2730 EXPECT_FALSE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002731
2732 // Reset everything.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002733 ASSERT_TRUE(SSL_clear(client_.get()));
2734 ASSERT_TRUE(SSL_clear(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002735
2736 // Attempt to connect a second time.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002737 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002738
2739 // |SSL_clear| should implicitly offer the previous session to the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002740 EXPECT_TRUE(SSL_session_reused(client_.get()));
2741 EXPECT_TRUE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002742}
2743
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002744static bool ChainsEqual(STACK_OF(X509) * chain,
2745 const std::vector<X509 *> &expected) {
David Benjamin1444c3a2016-12-20 17:23:11 -05002746 if (sk_X509_num(chain) != expected.size()) {
2747 return false;
2748 }
2749
2750 for (size_t i = 0; i < expected.size(); i++) {
2751 if (X509_cmp(sk_X509_value(chain, i), expected[i]) != 0) {
2752 return false;
2753 }
2754 }
2755
2756 return true;
2757}
2758
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002759TEST_P(SSLVersionTest, AutoChain) {
2760 cert_ = GetChainTestCertificate();
2761 ASSERT_TRUE(cert_);
2762 key_ = GetChainTestKey();
2763 ASSERT_TRUE(key_);
David Benjamin1444c3a2016-12-20 17:23:11 -05002764 bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002765 ASSERT_TRUE(intermediate);
2766
2767 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2768 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin1444c3a2016-12-20 17:23:11 -05002769
2770 // Configure both client and server to accept any certificate. Add
2771 // |intermediate| to the cert store.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002772 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx_.get()),
2773 intermediate.get()));
2774 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(server_ctx_.get()),
2775 intermediate.get()));
2776 SSL_CTX_set_verify(client_ctx_.get(),
2777 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2778 nullptr);
2779 SSL_CTX_set_verify(server_ctx_.get(),
2780 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2781 nullptr);
2782 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
2783 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjamin1444c3a2016-12-20 17:23:11 -05002784
2785 // By default, the client and server should each only send the leaf.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002786 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002787
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002788 EXPECT_TRUE(
2789 ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()), {cert_.get()}));
2790 EXPECT_TRUE(
2791 ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()), {cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002792
2793 // If auto-chaining is enabled, then the intermediate is sent.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002794 SSL_CTX_clear_mode(client_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
2795 SSL_CTX_clear_mode(server_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
2796 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002797
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002798 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
2799 {cert_.get(), intermediate.get()}));
2800 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
2801 {cert_.get(), intermediate.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002802
2803 // Auto-chaining does not override explicitly-configured intermediates.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002804 ASSERT_TRUE(SSL_CTX_add1_chain_cert(client_ctx_.get(), cert_.get()));
2805 ASSERT_TRUE(SSL_CTX_add1_chain_cert(server_ctx_.get(), cert_.get()));
2806 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002807
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002808 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
2809 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002810
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002811 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
2812 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002813}
2814
David Benjamin48063c22017-01-01 23:56:36 -05002815static bool ExpectBadWriteRetry() {
2816 int err = ERR_get_error();
2817 if (ERR_GET_LIB(err) != ERR_LIB_SSL ||
2818 ERR_GET_REASON(err) != SSL_R_BAD_WRITE_RETRY) {
2819 char buf[ERR_ERROR_STRING_BUF_LEN];
2820 ERR_error_string_n(err, buf, sizeof(buf));
2821 fprintf(stderr, "Wanted SSL_R_BAD_WRITE_RETRY, got: %s.\n", buf);
2822 return false;
2823 }
2824
2825 if (ERR_peek_error() != 0) {
2826 fprintf(stderr, "Unexpected error following SSL_R_BAD_WRITE_RETRY.\n");
2827 return false;
2828 }
2829
2830 return true;
2831}
2832
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002833TEST_P(SSLVersionTest, SSLWriteRetry) {
2834 if (is_dtls()) {
2835 return;
David Benjamin48063c22017-01-01 23:56:36 -05002836 }
2837
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002838 for (bool enable_partial_write : {false, true}) {
2839 SCOPED_TRACE(enable_partial_write);
2840
David Benjamin48063c22017-01-01 23:56:36 -05002841 // Connect a client and server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002842 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2843
2844 ASSERT_TRUE(Connect());
David Benjamin48063c22017-01-01 23:56:36 -05002845
2846 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002847 SSL_set_mode(client_.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002848 }
2849
2850 // Write without reading until the buffer is full and we have an unfinished
2851 // write. Keep a count so we may reread it again later. "hello!" will be
2852 // written in two chunks, "hello" and "!".
2853 char data[] = "hello!";
2854 static const int kChunkLen = 5; // The length of "hello".
2855 unsigned count = 0;
2856 for (;;) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002857 int ret = SSL_write(client_.get(), data, kChunkLen);
David Benjamin48063c22017-01-01 23:56:36 -05002858 if (ret <= 0) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002859 ASSERT_EQ(SSL_get_error(client_.get(), ret), SSL_ERROR_WANT_WRITE);
2860 break;
David Benjamin48063c22017-01-01 23:56:36 -05002861 }
2862
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002863 ASSERT_EQ(ret, 5);
David Benjamin48063c22017-01-01 23:56:36 -05002864
2865 count++;
2866 }
2867
2868 // Retrying with the same parameters is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002869 ASSERT_EQ(
2870 SSL_get_error(client_.get(), SSL_write(client_.get(), data, kChunkLen)),
2871 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002872
2873 // Retrying with the same buffer but shorter length is not legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002874 ASSERT_EQ(SSL_get_error(client_.get(),
2875 SSL_write(client_.get(), data, kChunkLen - 1)),
2876 SSL_ERROR_SSL);
2877 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002878
2879 // Retrying with a different buffer pointer is not legal.
2880 char data2[] = "hello";
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002881 ASSERT_EQ(SSL_get_error(client_.get(),
2882 SSL_write(client_.get(), data2, kChunkLen)),
2883 SSL_ERROR_SSL);
2884 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002885
2886 // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002887 SSL_set_mode(client_.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
2888 ASSERT_EQ(SSL_get_error(client_.get(),
2889 SSL_write(client_.get(), data2, kChunkLen)),
2890 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002891
2892 // |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| does not disable length checks.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002893 ASSERT_EQ(SSL_get_error(client_.get(),
2894 SSL_write(client_.get(), data2, kChunkLen - 1)),
2895 SSL_ERROR_SSL);
2896 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002897
2898 // Retrying with a larger buffer is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002899 ASSERT_EQ(SSL_get_error(client_.get(),
2900 SSL_write(client_.get(), data, kChunkLen + 1)),
2901 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002902
2903 // Drain the buffer.
2904 char buf[20];
2905 for (unsigned i = 0; i < count; i++) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002906 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
2907 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
David Benjamin48063c22017-01-01 23:56:36 -05002908 }
2909
2910 // Now that there is space, a retry with a larger buffer should flush the
2911 // pending record, skip over that many bytes of input (on assumption they
2912 // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE
2913 // is set, this will complete in two steps.
2914 char data3[] = "_____!";
2915 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002916 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen);
2917 ASSERT_EQ(SSL_write(client_.get(), data3 + kChunkLen, 1), 1);
2918 } else {
2919 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen + 1);
David Benjamin48063c22017-01-01 23:56:36 -05002920 }
2921
2922 // Check the last write was correct. The data will be spread over two
2923 // records, so SSL_read returns twice.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002924 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
2925 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
2926 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), 1);
2927 ASSERT_EQ(buf[0], '!');
David Benjamin48063c22017-01-01 23:56:36 -05002928 }
David Benjamin48063c22017-01-01 23:56:36 -05002929}
2930
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002931TEST_P(SSLVersionTest, RecordCallback) {
2932 for (bool test_server : {true, false}) {
2933 SCOPED_TRACE(test_server);
2934 ResetContexts();
David Benjamin5df5be12017-06-22 19:43:11 -04002935
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002936 bool read_seen = false;
2937 bool write_seen = false;
2938 auto cb = [&](int is_write, int cb_version, int cb_type, const void *buf,
2939 size_t len, SSL *ssl) {
2940 if (cb_type != SSL3_RT_HEADER) {
2941 return;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002942 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002943
2944 // The callback does not report a version for records.
2945 EXPECT_EQ(0, cb_version);
2946
2947 if (is_write) {
2948 write_seen = true;
2949 } else {
2950 read_seen = true;
2951 }
2952
2953 // Sanity-check that the record header is plausible.
2954 CBS cbs;
2955 CBS_init(&cbs, reinterpret_cast<const uint8_t *>(buf), len);
2956 uint8_t type;
2957 uint16_t record_version, length;
2958 ASSERT_TRUE(CBS_get_u8(&cbs, &type));
2959 ASSERT_TRUE(CBS_get_u16(&cbs, &record_version));
2960 EXPECT_TRUE(record_version == version() ||
2961 record_version == (is_dtls() ? DTLS1_VERSION : TLS1_VERSION))
2962 << "Invalid record version: " << record_version;
2963 if (is_dtls()) {
2964 uint16_t epoch;
2965 ASSERT_TRUE(CBS_get_u16(&cbs, &epoch));
2966 EXPECT_TRUE(epoch == 0 || epoch == 1) << "Invalid epoch: " << epoch;
2967 ASSERT_TRUE(CBS_skip(&cbs, 6));
2968 }
2969 ASSERT_TRUE(CBS_get_u16(&cbs, &length));
2970 EXPECT_EQ(0u, CBS_len(&cbs));
2971 };
2972 using CallbackType = decltype(cb);
2973 SSL_CTX *ctx = test_server ? server_ctx_.get() : client_ctx_.get();
2974 SSL_CTX_set_msg_callback(
2975 ctx, [](int is_write, int cb_version, int cb_type, const void *buf,
2976 size_t len, SSL *ssl, void *arg) {
2977 CallbackType *cb_ptr = reinterpret_cast<CallbackType *>(arg);
2978 (*cb_ptr)(is_write, cb_version, cb_type, buf, len, ssl);
2979 });
2980 SSL_CTX_set_msg_callback_arg(ctx, &cb);
2981
2982 ASSERT_TRUE(Connect());
2983
2984 EXPECT_TRUE(read_seen);
2985 EXPECT_TRUE(write_seen);
David Benjamin0fef3052016-11-18 15:11:10 +09002986 }
David Benjamin9ef31f02016-10-31 18:01:13 -04002987}
2988
David Benjamina8614602017-09-06 15:40:19 -04002989TEST_P(SSLVersionTest, GetServerName) {
2990 // No extensions in SSL 3.0.
2991 if (version() == SSL3_VERSION) {
2992 return;
2993 }
2994
2995 ClientConfig config;
2996 config.servername = "host1";
2997
2998 SSL_CTX_set_tlsext_servername_callback(
2999 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
3000 // During the handshake, |SSL_get_servername| must match |config|.
3001 ClientConfig *config_p = reinterpret_cast<ClientConfig *>(arg);
3002 EXPECT_STREQ(config_p->servername.c_str(),
3003 SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name));
3004 return SSL_TLSEXT_ERR_OK;
3005 });
3006 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), &config);
3007
3008 ASSERT_TRUE(Connect(config));
3009 // After the handshake, it must also be available.
3010 EXPECT_STREQ(config.servername.c_str(),
3011 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3012
3013 // Establish a session under host1.
3014 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3015 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3016 bssl::UniquePtr<SSL_SESSION> session =
3017 CreateClientSession(client_ctx_.get(), server_ctx_.get(), config);
3018
3019 // If the client resumes a session with a different name, |SSL_get_servername|
3020 // must return the new name.
3021 ASSERT_TRUE(session);
3022 config.session = session.get();
3023 config.servername = "host2";
3024 ASSERT_TRUE(Connect(config));
3025 EXPECT_STREQ(config.servername.c_str(),
3026 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3027}
3028
David Benjamin3d8f0802017-09-06 16:12:52 -04003029// Test that session cache mode bits are honored in the client session callback.
3030TEST_P(SSLVersionTest, ClientSessionCacheMode) {
3031 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_OFF);
3032 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3033
3034 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_CLIENT);
3035 EXPECT_TRUE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3036
3037 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_SERVER);
3038 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3039}
3040
Adam Langleye1e78132017-01-31 15:24:31 -08003041TEST(SSLTest, AddChainCertHack) {
3042 // Ensure that we don't accidently break the hack that we have in place to
3043 // keep curl and serf happy when they use an |X509| even after transfering
3044 // ownership.
3045
3046 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3047 ASSERT_TRUE(ctx);
3048 X509 *cert = GetTestCertificate().release();
3049 ASSERT_TRUE(cert);
3050 SSL_CTX_add0_chain_cert(ctx.get(), cert);
3051
3052 // This should not trigger a use-after-free.
3053 X509_cmp(cert, cert);
3054}
3055
David Benjaminb2ff2622017-02-03 17:06:18 -05003056TEST(SSLTest, GetCertificate) {
3057 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3058 ASSERT_TRUE(ctx);
3059 bssl::UniquePtr<X509> cert = GetTestCertificate();
3060 ASSERT_TRUE(cert);
3061 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
3062 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3063 ASSERT_TRUE(ssl);
3064
3065 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
3066 ASSERT_TRUE(cert2);
3067 X509 *cert3 = SSL_get_certificate(ssl.get());
3068 ASSERT_TRUE(cert3);
3069
3070 // The old and new certificates must be identical.
3071 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
3072 EXPECT_EQ(0, X509_cmp(cert.get(), cert3));
3073
3074 uint8_t *der = nullptr;
3075 long der_len = i2d_X509(cert.get(), &der);
3076 ASSERT_LT(0, der_len);
3077 bssl::UniquePtr<uint8_t> free_der(der);
3078
3079 uint8_t *der2 = nullptr;
3080 long der2_len = i2d_X509(cert2, &der2);
3081 ASSERT_LT(0, der2_len);
3082 bssl::UniquePtr<uint8_t> free_der2(der2);
3083
3084 uint8_t *der3 = nullptr;
3085 long der3_len = i2d_X509(cert3, &der3);
3086 ASSERT_LT(0, der3_len);
3087 bssl::UniquePtr<uint8_t> free_der3(der3);
3088
3089 // They must also encode identically.
David Benjamin7d7554b2017-02-04 11:48:59 -05003090 EXPECT_EQ(Bytes(der, der_len), Bytes(der2, der2_len));
3091 EXPECT_EQ(Bytes(der, der_len), Bytes(der3, der3_len));
David Benjaminb2ff2622017-02-03 17:06:18 -05003092}
3093
Adam Langleyd04ca952017-02-28 11:26:51 -08003094TEST(SSLTest, SetChainAndKeyMismatch) {
3095 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_with_buffers_method()));
3096 ASSERT_TRUE(ctx);
3097
3098 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3099 ASSERT_TRUE(key);
3100 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3101 ASSERT_TRUE(leaf);
3102 std::vector<CRYPTO_BUFFER*> chain = {
3103 leaf.get(),
3104 };
3105
3106 // Should fail because |GetTestKey| doesn't match the chain-test certificate.
3107 ASSERT_FALSE(SSL_CTX_set_chain_and_key(ctx.get(), &chain[0], chain.size(),
3108 key.get(), nullptr));
3109 ERR_clear_error();
3110}
3111
3112TEST(SSLTest, SetChainAndKey) {
3113 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3114 ASSERT_TRUE(client_ctx);
3115 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3116 ASSERT_TRUE(server_ctx);
3117
3118 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3119 ASSERT_TRUE(key);
3120 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3121 ASSERT_TRUE(leaf);
3122 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3123 GetChainTestIntermediateBuffer();
3124 ASSERT_TRUE(intermediate);
3125 std::vector<CRYPTO_BUFFER*> chain = {
3126 leaf.get(), intermediate.get(),
3127 };
3128 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3129 chain.size(), key.get(), nullptr));
3130
David Benjamin3a1dd462017-07-11 16:13:10 -04003131 SSL_CTX_set_custom_verify(
3132 client_ctx.get(), SSL_VERIFY_PEER,
3133 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3134 return ssl_verify_ok;
3135 });
Adam Langleyd04ca952017-02-28 11:26:51 -08003136
3137 bssl::UniquePtr<SSL> client, server;
3138 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003139 server_ctx.get()));
Adam Langleyd04ca952017-02-28 11:26:51 -08003140}
3141
David Benjamin71dfad42017-07-16 17:27:39 -04003142TEST(SSLTest, ClientCABuffers) {
3143 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3144 ASSERT_TRUE(client_ctx);
3145 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3146 ASSERT_TRUE(server_ctx);
3147
3148 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3149 ASSERT_TRUE(key);
3150 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3151 ASSERT_TRUE(leaf);
3152 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3153 GetChainTestIntermediateBuffer();
3154 ASSERT_TRUE(intermediate);
3155 std::vector<CRYPTO_BUFFER *> chain = {
3156 leaf.get(),
3157 intermediate.get(),
3158 };
3159 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3160 chain.size(), key.get(), nullptr));
3161
3162 bssl::UniquePtr<CRYPTO_BUFFER> ca_name(
3163 CRYPTO_BUFFER_new(kTestName, sizeof(kTestName), nullptr));
3164 ASSERT_TRUE(ca_name);
3165 bssl::UniquePtr<STACK_OF(CRYPTO_BUFFER)> ca_names(
3166 sk_CRYPTO_BUFFER_new_null());
3167 ASSERT_TRUE(ca_names);
3168 ASSERT_TRUE(sk_CRYPTO_BUFFER_push(ca_names.get(), ca_name.get()));
3169 ca_name.release();
3170 SSL_CTX_set0_client_CAs(server_ctx.get(), ca_names.release());
3171
3172 // Configure client and server to accept all certificates.
3173 SSL_CTX_set_custom_verify(
3174 client_ctx.get(), SSL_VERIFY_PEER,
3175 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3176 return ssl_verify_ok;
3177 });
3178 SSL_CTX_set_custom_verify(
3179 server_ctx.get(), SSL_VERIFY_PEER,
3180 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3181 return ssl_verify_ok;
3182 });
3183
3184 bool cert_cb_called = false;
3185 SSL_CTX_set_cert_cb(
3186 client_ctx.get(),
3187 [](SSL *ssl, void *arg) -> int {
3188 STACK_OF(CRYPTO_BUFFER) *peer_names =
3189 SSL_get0_server_requested_CAs(ssl);
3190 EXPECT_EQ(1u, sk_CRYPTO_BUFFER_num(peer_names));
3191 CRYPTO_BUFFER *peer_name = sk_CRYPTO_BUFFER_value(peer_names, 0);
3192 EXPECT_EQ(Bytes(kTestName), Bytes(CRYPTO_BUFFER_data(peer_name),
3193 CRYPTO_BUFFER_len(peer_name)));
3194 *reinterpret_cast<bool *>(arg) = true;
3195 return 1;
3196 },
3197 &cert_cb_called);
3198
3199 bssl::UniquePtr<SSL> client, server;
3200 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003201 server_ctx.get()));
David Benjamin71dfad42017-07-16 17:27:39 -04003202 EXPECT_TRUE(cert_cb_called);
3203}
3204
David Benjamin91222b82017-03-09 20:10:56 -05003205// Configuring the empty cipher list, though an error, should still modify the
3206// configuration.
3207TEST(SSLTest, EmptyCipherList) {
3208 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3209 ASSERT_TRUE(ctx);
3210
3211 // Initially, the cipher list is not empty.
3212 EXPECT_NE(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3213
3214 // Configuring the empty cipher list fails.
3215 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), ""));
3216 ERR_clear_error();
3217
3218 // But the cipher list is still updated to empty.
3219 EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3220}
3221
Adam Langley4c341d02017-03-08 19:33:21 -08003222// ssl_test_ticket_aead_failure_mode enumerates the possible ways in which the
3223// test |SSL_TICKET_AEAD_METHOD| can fail.
3224enum ssl_test_ticket_aead_failure_mode {
3225 ssl_test_ticket_aead_ok = 0,
3226 ssl_test_ticket_aead_seal_fail,
3227 ssl_test_ticket_aead_open_soft_fail,
3228 ssl_test_ticket_aead_open_hard_fail,
3229};
3230
3231struct ssl_test_ticket_aead_state {
3232 unsigned retry_count;
3233 ssl_test_ticket_aead_failure_mode failure_mode;
3234};
3235
3236static int ssl_test_ticket_aead_ex_index_dup(CRYPTO_EX_DATA *to,
3237 const CRYPTO_EX_DATA *from,
3238 void **from_d, int index,
3239 long argl, void *argp) {
3240 abort();
3241}
3242
3243static void ssl_test_ticket_aead_ex_index_free(void *parent, void *ptr,
3244 CRYPTO_EX_DATA *ad, int index,
3245 long argl, void *argp) {
3246 auto state = reinterpret_cast<ssl_test_ticket_aead_state*>(ptr);
3247 if (state == nullptr) {
3248 return;
3249 }
3250
3251 OPENSSL_free(state);
3252}
3253
3254static CRYPTO_once_t g_ssl_test_ticket_aead_ex_index_once = CRYPTO_ONCE_INIT;
3255static int g_ssl_test_ticket_aead_ex_index;
3256
3257static int ssl_test_ticket_aead_get_ex_index() {
3258 CRYPTO_once(&g_ssl_test_ticket_aead_ex_index_once, [] {
3259 g_ssl_test_ticket_aead_ex_index = SSL_get_ex_new_index(
3260 0, nullptr, nullptr, ssl_test_ticket_aead_ex_index_dup,
3261 ssl_test_ticket_aead_ex_index_free);
3262 });
3263 return g_ssl_test_ticket_aead_ex_index;
3264}
3265
3266static size_t ssl_test_ticket_aead_max_overhead(SSL *ssl) {
3267 return 1;
3268}
3269
3270static int ssl_test_ticket_aead_seal(SSL *ssl, uint8_t *out, size_t *out_len,
3271 size_t max_out_len, const uint8_t *in,
3272 size_t in_len) {
3273 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3274 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3275
3276 if (state->failure_mode == ssl_test_ticket_aead_seal_fail ||
3277 max_out_len < in_len + 1) {
3278 return 0;
3279 }
3280
3281 OPENSSL_memmove(out, in, in_len);
3282 out[in_len] = 0xff;
3283 *out_len = in_len + 1;
3284
3285 return 1;
3286}
3287
3288static ssl_ticket_aead_result_t ssl_test_ticket_aead_open(
3289 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len,
3290 const uint8_t *in, size_t in_len) {
3291 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3292 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3293
3294 if (state->retry_count > 0) {
3295 state->retry_count--;
3296 return ssl_ticket_aead_retry;
3297 }
3298
3299 switch (state->failure_mode) {
3300 case ssl_test_ticket_aead_ok:
3301 break;
3302 case ssl_test_ticket_aead_seal_fail:
3303 // If |seal| failed then there shouldn't be any ticket to try and
3304 // decrypt.
3305 abort();
3306 break;
3307 case ssl_test_ticket_aead_open_soft_fail:
3308 return ssl_ticket_aead_ignore_ticket;
3309 case ssl_test_ticket_aead_open_hard_fail:
3310 return ssl_ticket_aead_error;
3311 }
3312
3313 if (in_len == 0 || in[in_len - 1] != 0xff) {
3314 return ssl_ticket_aead_ignore_ticket;
3315 }
3316
3317 if (max_out_len < in_len - 1) {
3318 return ssl_ticket_aead_error;
3319 }
3320
3321 OPENSSL_memmove(out, in, in_len - 1);
3322 *out_len = in_len - 1;
3323 return ssl_ticket_aead_success;
3324}
3325
3326static const SSL_TICKET_AEAD_METHOD kSSLTestTicketMethod = {
3327 ssl_test_ticket_aead_max_overhead,
3328 ssl_test_ticket_aead_seal,
3329 ssl_test_ticket_aead_open,
3330};
3331
3332static void ConnectClientAndServerWithTicketMethod(
3333 bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
3334 SSL_CTX *client_ctx, SSL_CTX *server_ctx, unsigned retry_count,
3335 ssl_test_ticket_aead_failure_mode failure_mode, SSL_SESSION *session) {
3336 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
3337 ASSERT_TRUE(client);
3338 ASSERT_TRUE(server);
3339 SSL_set_connect_state(client.get());
3340 SSL_set_accept_state(server.get());
3341
3342 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3343 OPENSSL_malloc(sizeof(ssl_test_ticket_aead_state)));
3344 ASSERT_TRUE(state);
3345 OPENSSL_memset(state, 0, sizeof(ssl_test_ticket_aead_state));
3346 state->retry_count = retry_count;
3347 state->failure_mode = failure_mode;
3348
3349 ASSERT_TRUE(SSL_set_ex_data(server.get(), ssl_test_ticket_aead_get_ex_index(),
3350 state));
3351
3352 SSL_set_session(client.get(), session);
3353
3354 BIO *bio1, *bio2;
3355 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
3356
3357 // SSL_set_bio takes ownership.
3358 SSL_set_bio(client.get(), bio1, bio1);
3359 SSL_set_bio(server.get(), bio2, bio2);
3360
3361 if (CompleteHandshakes(client.get(), server.get())) {
3362 *out_client = std::move(client);
3363 *out_server = std::move(server);
3364 } else {
3365 out_client->reset();
3366 out_server->reset();
3367 }
3368}
3369
3370class TicketAEADMethodTest
3371 : public ::testing::TestWithParam<testing::tuple<
3372 uint16_t, unsigned, ssl_test_ticket_aead_failure_mode>> {};
3373
3374TEST_P(TicketAEADMethodTest, Resume) {
3375 bssl::UniquePtr<X509> cert = GetTestCertificate();
3376 ASSERT_TRUE(cert);
3377 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3378 ASSERT_TRUE(key);
3379
3380 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
3381 ASSERT_TRUE(server_ctx);
3382 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
3383 ASSERT_TRUE(client_ctx);
3384
3385 const uint16_t version = testing::get<0>(GetParam());
3386 const unsigned retry_count = testing::get<1>(GetParam());
3387 const ssl_test_ticket_aead_failure_mode failure_mode =
3388 testing::get<2>(GetParam());
3389
3390 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3391 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3392 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), version));
3393 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), version));
3394 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), version));
3395 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), version));
3396
3397 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
3398 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
3399 SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
3400 SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
David Benjamin707af292017-03-10 17:47:18 -05003401 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langley4c341d02017-03-08 19:33:21 -08003402
3403 SSL_CTX_set_ticket_aead_method(server_ctx.get(), &kSSLTestTicketMethod);
3404
3405 bssl::UniquePtr<SSL> client, server;
3406 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3407 server_ctx.get(), retry_count,
3408 failure_mode, nullptr);
3409 switch (failure_mode) {
3410 case ssl_test_ticket_aead_ok:
3411 case ssl_test_ticket_aead_open_hard_fail:
3412 case ssl_test_ticket_aead_open_soft_fail:
3413 ASSERT_TRUE(client);
3414 break;
3415 case ssl_test_ticket_aead_seal_fail:
3416 EXPECT_FALSE(client);
3417 return;
3418 }
3419 EXPECT_FALSE(SSL_session_reused(client.get()));
3420 EXPECT_FALSE(SSL_session_reused(server.get()));
3421
David Benjamin707af292017-03-10 17:47:18 -05003422 // Run the read loop to account for post-handshake tickets in TLS 1.3.
3423 SSL_read(client.get(), nullptr, 0);
3424
3425 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
Adam Langley4c341d02017-03-08 19:33:21 -08003426 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3427 server_ctx.get(), retry_count,
David Benjamin707af292017-03-10 17:47:18 -05003428 failure_mode, session.get());
Adam Langley4c341d02017-03-08 19:33:21 -08003429 switch (failure_mode) {
3430 case ssl_test_ticket_aead_ok:
3431 ASSERT_TRUE(client);
3432 EXPECT_TRUE(SSL_session_reused(client.get()));
3433 EXPECT_TRUE(SSL_session_reused(server.get()));
3434 break;
3435 case ssl_test_ticket_aead_seal_fail:
3436 abort();
3437 break;
3438 case ssl_test_ticket_aead_open_hard_fail:
3439 EXPECT_FALSE(client);
3440 break;
3441 case ssl_test_ticket_aead_open_soft_fail:
3442 ASSERT_TRUE(client);
3443 EXPECT_FALSE(SSL_session_reused(client.get()));
3444 EXPECT_FALSE(SSL_session_reused(server.get()));
3445 }
3446}
3447
3448INSTANTIATE_TEST_CASE_P(
3449 TicketAEADMethodTests, TicketAEADMethodTest,
3450 testing::Combine(
David Benjamin707af292017-03-10 17:47:18 -05003451 testing::Values(TLS1_2_VERSION, TLS1_3_VERSION),
Adam Langley4c341d02017-03-08 19:33:21 -08003452 testing::Values(0, 1, 2),
3453 testing::Values(ssl_test_ticket_aead_ok,
3454 ssl_test_ticket_aead_seal_fail,
3455 ssl_test_ticket_aead_open_soft_fail,
3456 ssl_test_ticket_aead_open_hard_fail)));
3457
David Benjamin3cfeb952017-03-01 16:48:38 -05003458TEST(SSLTest, SSL3Method) {
3459 bssl::UniquePtr<X509> cert = GetTestCertificate();
3460 ASSERT_TRUE(cert);
3461
3462 // For compatibility, SSLv3_method should work up to SSL_CTX_new and SSL_new.
3463 bssl::UniquePtr<SSL_CTX> ssl3_ctx(SSL_CTX_new(SSLv3_method()));
3464 ASSERT_TRUE(ssl3_ctx);
3465 ASSERT_TRUE(SSL_CTX_use_certificate(ssl3_ctx.get(), cert.get()));
3466 bssl::UniquePtr<SSL> ssl(SSL_new(ssl3_ctx.get()));
3467 EXPECT_TRUE(ssl);
3468
3469 // Create a normal TLS context to test against.
3470 bssl::UniquePtr<SSL_CTX> tls_ctx(SSL_CTX_new(TLS_method()));
3471 ASSERT_TRUE(tls_ctx);
3472 ASSERT_TRUE(SSL_CTX_use_certificate(tls_ctx.get(), cert.get()));
3473
3474 // However, handshaking an SSLv3_method server should fail to resolve the
3475 // version range. Explicit calls to SSL_CTX_set_min_proto_version are the only
3476 // way to enable SSL 3.0.
3477 bssl::UniquePtr<SSL> client, server;
3478 EXPECT_FALSE(ConnectClientAndServer(&client, &server, tls_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003479 ssl3_ctx.get()));
David Benjamin3cfeb952017-03-01 16:48:38 -05003480 uint32_t err = ERR_get_error();
3481 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
3482 EXPECT_EQ(SSL_R_NO_SUPPORTED_VERSIONS_ENABLED, ERR_GET_REASON(err));
3483
3484 // Likewise for SSLv3_method clients.
3485 EXPECT_FALSE(ConnectClientAndServer(&client, &server, ssl3_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003486 tls_ctx.get()));
David Benjamin3cfeb952017-03-01 16:48:38 -05003487 err = ERR_get_error();
3488 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
3489 EXPECT_EQ(SSL_R_NO_SUPPORTED_VERSIONS_ENABLED, ERR_GET_REASON(err));
3490}
3491
David Benjaminca743582017-06-15 17:51:35 -04003492TEST(SSLTest, SelectNextProto) {
3493 uint8_t *result;
3494 uint8_t result_len;
3495
3496 // If there is an overlap, it should be returned.
3497 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3498 SSL_select_next_proto(&result, &result_len,
3499 (const uint8_t *)"\1a\2bb\3ccc", 9,
3500 (const uint8_t *)"\1x\1y\1a\1z", 8));
3501 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
3502
3503 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3504 SSL_select_next_proto(&result, &result_len,
3505 (const uint8_t *)"\1a\2bb\3ccc", 9,
3506 (const uint8_t *)"\1x\1y\2bb\1z", 9));
3507 EXPECT_EQ(Bytes("bb"), Bytes(result, result_len));
3508
3509 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3510 SSL_select_next_proto(&result, &result_len,
3511 (const uint8_t *)"\1a\2bb\3ccc", 9,
3512 (const uint8_t *)"\1x\1y\3ccc\1z", 10));
3513 EXPECT_EQ(Bytes("ccc"), Bytes(result, result_len));
3514
3515 // Peer preference order takes precedence over local.
3516 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3517 SSL_select_next_proto(&result, &result_len,
3518 (const uint8_t *)"\1a\2bb\3ccc", 9,
3519 (const uint8_t *)"\3ccc\2bb\1a", 9));
3520 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
3521
3522 // If there is no overlap, return the first local protocol.
3523 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
3524 SSL_select_next_proto(&result, &result_len,
3525 (const uint8_t *)"\1a\2bb\3ccc", 9,
3526 (const uint8_t *)"\1x\2yy\3zzz", 9));
3527 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
3528
3529 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
3530 SSL_select_next_proto(&result, &result_len, nullptr, 0,
3531 (const uint8_t *)"\1x\2yy\3zzz", 9));
3532 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
3533}
3534
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003535TEST(SSLTest, SealRecord) {
3536 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3537 server_ctx(SSL_CTX_new(TLS_method()));
3538 ASSERT_TRUE(client_ctx);
3539 ASSERT_TRUE(server_ctx);
3540
3541 bssl::UniquePtr<X509> cert = GetTestCertificate();
3542 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3543 ASSERT_TRUE(cert);
3544 ASSERT_TRUE(key);
3545 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3546 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3547
3548 bssl::UniquePtr<SSL> client, server;
3549 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003550 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003551
3552 const std::vector<uint8_t> record = {1, 2, 3, 4, 5};
3553 std::vector<uint8_t> prefix(
3554 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003555 body(record.size()),
3556 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003557 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3558 bssl::MakeSpan(body), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003559 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003560
3561 std::vector<uint8_t> sealed;
3562 sealed.insert(sealed.end(), prefix.begin(), prefix.end());
3563 sealed.insert(sealed.end(), body.begin(), body.end());
3564 sealed.insert(sealed.end(), suffix.begin(), suffix.end());
3565 std::vector<uint8_t> sealed_copy = sealed;
3566
3567 bssl::Span<uint8_t> plaintext;
3568 size_t record_len;
3569 uint8_t alert = 255;
3570 EXPECT_EQ(bssl::OpenRecord(server.get(), &plaintext, &record_len, &alert,
3571 bssl::MakeSpan(sealed)),
3572 bssl::OpenRecordResult::kOK);
3573 EXPECT_EQ(record_len, sealed.size());
3574 EXPECT_EQ(plaintext, record);
3575 EXPECT_EQ(255, alert);
3576}
3577
3578TEST(SSLTest, SealRecordInPlace) {
3579 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3580 server_ctx(SSL_CTX_new(TLS_method()));
3581 ASSERT_TRUE(client_ctx);
3582 ASSERT_TRUE(server_ctx);
3583
3584 bssl::UniquePtr<X509> cert = GetTestCertificate();
3585 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3586 ASSERT_TRUE(cert);
3587 ASSERT_TRUE(key);
3588 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3589 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3590
3591 bssl::UniquePtr<SSL> client, server;
3592 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003593 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003594
3595 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
3596 std::vector<uint8_t> record = plaintext;
3597 std::vector<uint8_t> prefix(
3598 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003599 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003600 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3601 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003602 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003603 record.insert(record.begin(), prefix.begin(), prefix.end());
3604 record.insert(record.end(), suffix.begin(), suffix.end());
3605
3606 bssl::Span<uint8_t> result;
3607 size_t record_len;
3608 uint8_t alert;
3609 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
3610 bssl::MakeSpan(record)),
3611 bssl::OpenRecordResult::kOK);
3612 EXPECT_EQ(record_len, record.size());
3613 EXPECT_EQ(plaintext, result);
3614}
3615
3616TEST(SSLTest, SealRecordTrailingData) {
3617 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3618 server_ctx(SSL_CTX_new(TLS_method()));
3619 ASSERT_TRUE(client_ctx);
3620 ASSERT_TRUE(server_ctx);
3621
3622 bssl::UniquePtr<X509> cert = GetTestCertificate();
3623 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3624 ASSERT_TRUE(cert);
3625 ASSERT_TRUE(key);
3626 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3627 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3628
3629 bssl::UniquePtr<SSL> client, server;
3630 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003631 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003632
3633 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
3634 std::vector<uint8_t> record = plaintext;
3635 std::vector<uint8_t> prefix(
3636 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003637 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003638 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3639 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003640 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003641 record.insert(record.begin(), prefix.begin(), prefix.end());
3642 record.insert(record.end(), suffix.begin(), suffix.end());
3643 record.insert(record.end(), {5, 4, 3, 2, 1});
3644
3645 bssl::Span<uint8_t> result;
3646 size_t record_len;
3647 uint8_t alert;
3648 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
3649 bssl::MakeSpan(record)),
3650 bssl::OpenRecordResult::kOK);
3651 EXPECT_EQ(record_len, record.size() - 5);
3652 EXPECT_EQ(plaintext, result);
3653}
3654
3655TEST(SSLTest, SealRecordInvalidSpanSize) {
3656 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3657 server_ctx(SSL_CTX_new(TLS_method()));
3658 ASSERT_TRUE(client_ctx);
3659 ASSERT_TRUE(server_ctx);
3660
3661 bssl::UniquePtr<X509> cert = GetTestCertificate();
3662 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3663 ASSERT_TRUE(cert);
3664 ASSERT_TRUE(key);
3665 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3666 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3667
3668 bssl::UniquePtr<SSL> client, server;
3669 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003670 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003671
3672 std::vector<uint8_t> record = {1, 2, 3, 4, 5};
3673 std::vector<uint8_t> prefix(
3674 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003675 body(record.size()),
3676 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003677
3678 auto expect_err = []() {
3679 int err = ERR_get_error();
3680 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
3681 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_BUFFER_TOO_SMALL);
3682 ERR_clear_error();
3683 };
3684 EXPECT_FALSE(bssl::SealRecord(
3685 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003686 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003687 expect_err();
3688 EXPECT_FALSE(bssl::SealRecord(
3689 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003690 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003691 expect_err();
3692
3693 EXPECT_FALSE(
3694 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3695 bssl::MakeSpan(record.data(), record.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003696 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003697 expect_err();
3698 EXPECT_FALSE(
3699 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3700 bssl::MakeSpan(record.data(), record.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003701 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003702 expect_err();
3703
3704 EXPECT_FALSE(bssl::SealRecord(
3705 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003706 bssl::MakeSpan(suffix.data(), suffix.size() - 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003707 expect_err();
3708 EXPECT_FALSE(bssl::SealRecord(
3709 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003710 bssl::MakeSpan(suffix.data(), suffix.size() + 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003711 expect_err();
3712}
3713
David Benjamin617b8182017-08-29 15:33:10 -04003714// The client should gracefully handle no suitable ciphers being enabled.
3715TEST(SSLTest, NoCiphersAvailable) {
3716 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3717 ASSERT_TRUE(ctx);
3718
3719 // Configure |client_ctx| with a cipher list that does not intersect with its
3720 // version configuration.
3721 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
3722 ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
3723 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
3724
3725 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3726 ASSERT_TRUE(ssl);
3727 SSL_set_connect_state(ssl.get());
3728
3729 UniquePtr<BIO> rbio(BIO_new(BIO_s_mem())), wbio(BIO_new(BIO_s_mem()));
3730 ASSERT_TRUE(rbio);
3731 ASSERT_TRUE(wbio);
3732 SSL_set0_rbio(ssl.get(), rbio.release());
3733 SSL_set0_wbio(ssl.get(), wbio.release());
3734
3735 int ret = SSL_do_handshake(ssl.get());
3736 EXPECT_EQ(-1, ret);
3737 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), ret));
3738 uint32_t err = ERR_get_error();
3739 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
3740 EXPECT_EQ(SSL_R_NO_CIPHERS_AVAILABLE, ERR_GET_REASON(err));
3741}
3742
David Benjamin96628432017-01-19 19:05:47 -05003743// TODO(davidben): Convert this file to GTest properly.
3744TEST(SSLTest, AllTests) {
David Benjamine11726a2017-04-23 12:14:28 -04003745 if (!TestSSL_SESSIONEncoding(kOpenSSLSession) ||
Adam Langley10f97f32016-07-12 08:09:33 -07003746 !TestSSL_SESSIONEncoding(kCustomSession) ||
3747 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
3748 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
3749 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
3750 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
Steven Valdeza833c352016-11-01 13:39:36 -04003751 // Test the padding extension at TLS 1.2.
3752 !TestPaddingExtension(TLS1_2_VERSION, TLS1_2_VERSION) ||
3753 // Test the padding extension at TLS 1.3 with a TLS 1.2 session, so there
3754 // will be no PSK binder after the padding extension.
3755 !TestPaddingExtension(TLS1_3_VERSION, TLS1_2_VERSION) ||
3756 // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
3757 // will be a PSK binder after the padding extension.
David Benjamin737d2df2017-09-25 15:05:19 -04003758 !TestPaddingExtension(TLS1_3_VERSION, TLS1_3_DRAFT_VERSION)) {
David Benjamin96628432017-01-19 19:05:47 -05003759 ADD_FAILURE() << "Tests failed";
David Benjaminbb0a17c2014-09-20 15:35:39 -04003760 }
David Benjamin2e521212014-07-16 14:37:51 -04003761}
Martin Kreichgauer72912d22017-08-04 12:06:43 -07003762
3763} // namespace
3764} // namespace bssl