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