blob: 61a47d3dc59771b2fe888b8f0aeb95b545087b6a [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 Benjamin5b33eff2018-09-22 16:52:48 -070051#if defined(OPENSSL_THREADS)
David Benjamin6c04bd12018-07-19 18:13:09 -040052#include <thread>
53#endif
54
David Benjamin1d77e562015-03-22 17:22:08 -040055
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -070056BSSL_NAMESPACE_BEGIN
Martin Kreichgauer72912d22017-08-04 12:06:43 -070057
58namespace {
59
Martin Kreichgauer1a663262017-08-16 14:54:04 -070060#define TRACED_CALL(code) \
61 do { \
62 SCOPED_TRACE("<- called from here"); \
63 code; \
64 if (::testing::Test::HasFatalFailure()) { \
65 return; \
66 } \
67 } while (false)
68
Martin Kreichgauer72912d22017-08-04 12:06:43 -070069struct VersionParam {
70 uint16_t version;
71 enum { is_tls, is_dtls } ssl_method;
72 const char name[8];
73};
74
75static const size_t kTicketKeyLen = 48;
76
77static const VersionParam kAllVersions[] = {
Martin Kreichgauer72912d22017-08-04 12:06:43 -070078 {TLS1_VERSION, VersionParam::is_tls, "TLS1"},
79 {TLS1_1_VERSION, VersionParam::is_tls, "TLS1_1"},
80 {TLS1_2_VERSION, VersionParam::is_tls, "TLS1_2"},
Martin Kreichgauer72912d22017-08-04 12:06:43 -070081 {TLS1_3_VERSION, VersionParam::is_tls, "TLS1_3"},
Martin Kreichgauer72912d22017-08-04 12:06:43 -070082 {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.
David Benjamin6e678ee2018-04-16 19:54:42 -0400233 "!AESGCM:!3DES:"
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 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400292 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!SSLv3",
David Benjaminfb974e62015-12-16 19:34:22 -0500293 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400294 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500295 },
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 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400300 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!TLSv1.2",
David Benjaminfb974e62015-12-16 19:34:22 -0500301 {
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 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400309 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!TLSv1.2+SSLv3",
David Benjaminfb974e62015-12-16 19:34:22 -0500310 {
311 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400312 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500313 },
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 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400318 "AES128-SHA: ECDHE-RSA-AES128-GCM-SHA256 AES256-SHA ,ECDHE-ECDSA-AES128-GCM-SHA256 ; AES128-GCM-SHA256",
Adam Langley22df6912017-07-25 12:27:37 -0700319 {
320 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400321 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley22df6912017-07-25 12:27:37 -0700322 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400323 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley22df6912017-07-25 12:27:37 -0700324 {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 },
David Benjamin6dda1662017-11-02 20:44:26 -0400385 {
386 "prime256v1:secp384r1:secp521r1:x25519",
387 {
388 SSL_CURVE_SECP256R1,
389 SSL_CURVE_SECP384R1,
390 SSL_CURVE_SECP521R1,
391 SSL_CURVE_X25519,
392 },
393 },
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100394};
395
396static const char *kBadCurvesLists[] = {
397 "",
398 ":",
399 "::",
400 "P-256::X25519",
401 "RSA:P-256",
402 "P-256:RSA",
403 "X25519:P-256:",
404 ":X25519:P-256",
405};
406
David Benjamin70dbf042017-08-08 18:51:37 -0400407static std::string CipherListToString(SSL_CTX *ctx) {
David Benjamin1d77e562015-03-22 17:22:08 -0400408 bool in_group = false;
David Benjamine11726a2017-04-23 12:14:28 -0400409 std::string ret;
David Benjamin70dbf042017-08-08 18:51:37 -0400410 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
411 for (size_t i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
412 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
413 if (!in_group && SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400414 ret += "\t[\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400415 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400416 }
David Benjamine11726a2017-04-23 12:14:28 -0400417 ret += "\t";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400418 if (in_group) {
David Benjamine11726a2017-04-23 12:14:28 -0400419 ret += " ";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400420 }
David Benjamine11726a2017-04-23 12:14:28 -0400421 ret += SSL_CIPHER_get_name(cipher);
422 ret += "\n";
David Benjamin70dbf042017-08-08 18:51:37 -0400423 if (in_group && !SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400424 ret += "\t]\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400425 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400426 }
427 }
David Benjamine11726a2017-04-23 12:14:28 -0400428 return ret;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400429}
430
David Benjamin70dbf042017-08-08 18:51:37 -0400431static bool CipherListsEqual(SSL_CTX *ctx,
David Benjamine11726a2017-04-23 12:14:28 -0400432 const std::vector<ExpectedCipher> &expected) {
David Benjamin70dbf042017-08-08 18:51:37 -0400433 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
434 if (sk_SSL_CIPHER_num(ciphers) != expected.size()) {
David Benjamin1d77e562015-03-22 17:22:08 -0400435 return false;
David Benjamin65226252015-02-05 16:49:47 -0500436 }
437
David Benjamine11726a2017-04-23 12:14:28 -0400438 for (size_t i = 0; i < expected.size(); i++) {
David Benjamin70dbf042017-08-08 18:51:37 -0400439 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
David Benjamine11726a2017-04-23 12:14:28 -0400440 if (expected[i].id != SSL_CIPHER_get_id(cipher) ||
David Benjamin70dbf042017-08-08 18:51:37 -0400441 expected[i].in_group_flag != !!SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400442 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400443 }
444 }
445
David Benjamin1d77e562015-03-22 17:22:08 -0400446 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400447}
448
David Benjamine11726a2017-04-23 12:14:28 -0400449TEST(SSLTest, CipherRules) {
450 for (const CipherTest &t : kCipherTests) {
451 SCOPED_TRACE(t.rule);
452 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
453 ASSERT_TRUE(ctx);
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700454
David Benjamine11726a2017-04-23 12:14:28 -0400455 // Test lax mode.
456 ASSERT_TRUE(SSL_CTX_set_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 Benjamine11726a2017-04-23 12:14:28 -0400460
461 // Test strict mode.
462 if (t.strict_fail) {
463 EXPECT_FALSE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
464 } else {
465 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400466 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400467 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400468 << CipherListToString(ctx.get());
David Benjaminbb0a17c2014-09-20 15:35:39 -0400469 }
470 }
471
David Benjaminfb974e62015-12-16 19:34:22 -0500472 for (const char *rule : kBadRules) {
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 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), rule));
David Benjaminbb0a17c2014-09-20 15:35:39 -0400478 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400479 }
480
David Benjaminfb974e62015-12-16 19:34:22 -0500481 for (const char *rule : kMustNotIncludeNull) {
David Benjamine11726a2017-04-23 12:14:28 -0400482 SCOPED_TRACE(rule);
483 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
484 ASSERT_TRUE(ctx);
485
486 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400487 for (const SSL_CIPHER *cipher : SSL_CTX_get_ciphers(ctx.get())) {
David Benjamine3bb51c2017-08-22 23:16:02 -0700488 EXPECT_NE(NID_undef, SSL_CIPHER_get_cipher_nid(cipher));
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700489 }
490 }
David Benjaminbb0a17c2014-09-20 15:35:39 -0400491}
David Benjamin2e521212014-07-16 14:37:51 -0400492
David Benjamine11726a2017-04-23 12:14:28 -0400493TEST(SSLTest, CurveRules) {
494 for (const CurveTest &t : kCurveTests) {
495 SCOPED_TRACE(t.rule);
496 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
497 ASSERT_TRUE(ctx);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100498
David Benjamine11726a2017-04-23 12:14:28 -0400499 ASSERT_TRUE(SSL_CTX_set1_curves_list(ctx.get(), t.rule));
David Benjamin0ce090a2018-07-02 20:24:40 -0400500 ASSERT_EQ(t.expected.size(), ctx->supported_group_list.size());
David Benjamine11726a2017-04-23 12:14:28 -0400501 for (size_t i = 0; i < t.expected.size(); i++) {
502 EXPECT_EQ(t.expected[i], ctx->supported_group_list[i]);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100503 }
504 }
505
506 for (const char *rule : kBadCurvesLists) {
David Benjamine11726a2017-04-23 12:14:28 -0400507 SCOPED_TRACE(rule);
508 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
509 ASSERT_TRUE(ctx);
510
511 EXPECT_FALSE(SSL_CTX_set1_curves_list(ctx.get(), rule));
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100512 ERR_clear_error();
513 }
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100514}
515
Adam Langley364f7a62016-12-12 10:51:00 -0800516// kOpenSSLSession is a serialized SSL_SESSION.
Adam Langley10f97f32016-07-12 08:09:33 -0700517static const char kOpenSSLSession[] =
Adam Langley364f7a62016-12-12 10:51:00 -0800518 "MIIFqgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700519 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
520 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
521 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
522 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
523 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
524 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
525 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
526 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
527 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
528 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
529 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
530 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
531 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
532 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
533 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
534 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
535 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
536 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
537 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
538 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
539 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
540 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
541 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
542 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
543 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
544 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
545 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
546 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
547 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
Adam Langley364f7a62016-12-12 10:51:00 -0800548 "i4gv7Y5oliyntgMBAQA=";
Adam Langley10f97f32016-07-12 08:09:33 -0700549
550// kCustomSession is a custom serialized SSL_SESSION generated by
551// filling in missing fields from |kOpenSSLSession|. This includes
552// providing |peer_sha256|, so |peer| is not serialized.
553static const char kCustomSession[] =
David Benjamina8614602017-09-06 15:40:19 -0400554 "MIIBZAIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700555 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
David Benjamina8614602017-09-06 15:40:19 -0400556 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUqAcEBXdvcmxkqQUCAwGJwKqBpwSB"
557 "pBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38"
558 "VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd"
559 "3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hg"
560 "b+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYGBgYGBgYGBgYGBgYGBgYGBgYG"
561 "BgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
Adam Langley10f97f32016-07-12 08:09:33 -0700562
563// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
564static const char kBoringSSLSession[] =
565 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
566 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
567 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
568 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
569 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
570 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
571 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
572 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
573 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
574 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
575 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
576 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
577 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
578 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
579 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
580 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
581 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
582 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
583 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
584 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
585 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
586 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
587 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
588 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
589 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
590 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
591 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
592 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
593 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
594 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
595 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
596 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
597 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
598 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
599 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
600 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
601 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
602 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
603 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
604 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
605 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
606 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
607 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
608 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
609 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
610 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
611 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
612 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
613 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
614 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
615 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
616 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
617 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
618 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
619 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
620 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
621 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
622 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
623 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
624 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
625 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
626 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
627 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
628 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
629 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
630 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
631 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
632 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
633 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
634 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
635 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
636 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
637 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
638 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
639 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
640 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
641 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
642 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
643 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
644 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
645 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
646 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
647 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
648 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
649 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
650 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
651 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
652 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
653 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
654 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
655 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
656 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
657 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
658 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
659 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
660
661// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
662// the final (optional) element of |kCustomSession| with tag number 30.
663static const char kBadSessionExtraField[] =
664 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
665 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
666 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
667 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
668 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
669 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
670 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
671 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
672
673// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
674// the version of |kCustomSession| with 2.
675static const char kBadSessionVersion[] =
676 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
677 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
678 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
679 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
680 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
681 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
682 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
683 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
684
685// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
686// appended.
687static const char kBadSessionTrailingData[] =
688 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
689 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
690 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
691 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
692 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
693 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
694 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
695 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
696
David Benjamin1d77e562015-03-22 17:22:08 -0400697static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400698 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400699 if (!EVP_DecodedLength(&len, strlen(in))) {
700 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400701 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400702 }
703
David Benjamin1d77e562015-03-22 17:22:08 -0400704 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800705 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400706 strlen(in))) {
707 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400708 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400709 }
David Benjamin1d77e562015-03-22 17:22:08 -0400710 out->resize(len);
711 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400712}
713
David Benjamin1d77e562015-03-22 17:22:08 -0400714static bool TestSSL_SESSIONEncoding(const char *input_b64) {
David Benjamin751e8892014-10-19 00:59:36 -0400715 const uint8_t *cptr;
716 uint8_t *ptr;
David Benjamin751e8892014-10-19 00:59:36 -0400717
David Benjamin1d77e562015-03-22 17:22:08 -0400718 // Decode the input.
719 std::vector<uint8_t> input;
720 if (!DecodeBase64(&input, input_b64)) {
721 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400722 }
723
David Benjamin1d77e562015-03-22 17:22:08 -0400724 // Verify the SSL_SESSION decodes.
Adam Langley46db7af2017-02-01 15:49:37 -0800725 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
726 if (!ssl_ctx) {
727 return false;
728 }
729 bssl::UniquePtr<SSL_SESSION> session(
730 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
David Benjaminfd67aa82015-06-15 19:41:48 -0400731 if (!session) {
732 fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400733 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400734 }
735
David Benjamin1d77e562015-03-22 17:22:08 -0400736 // Verify the SSL_SESSION encoding round-trips.
737 size_t encoded_len;
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700738 bssl::UniquePtr<uint8_t> encoded;
David Benjamin1d77e562015-03-22 17:22:08 -0400739 uint8_t *encoded_raw;
740 if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
David Benjamin3cac4502014-10-21 01:46:30 -0400741 fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400742 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400743 }
David Benjamin1d77e562015-03-22 17:22:08 -0400744 encoded.reset(encoded_raw);
745 if (encoded_len != input.size() ||
David Benjamin17cf2cb2016-12-13 01:07:13 -0500746 OPENSSL_memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin3cac4502014-10-21 01:46:30 -0400747 fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
Sigbjorn Vik2b23d242015-06-29 15:07:26 +0200748 hexdump(stderr, "Before: ", input.data(), input.size());
749 hexdump(stderr, "After: ", encoded_raw, encoded_len);
David Benjamin1d77e562015-03-22 17:22:08 -0400750 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400751 }
David Benjamin3cac4502014-10-21 01:46:30 -0400752
David Benjaminfd67aa82015-06-15 19:41:48 -0400753 // Verify the SSL_SESSION also decodes with the legacy API.
David Benjaminef14b2d2015-11-11 14:01:27 -0800754 cptr = input.data();
David Benjaminfd67aa82015-06-15 19:41:48 -0400755 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
David Benjaminef14b2d2015-11-11 14:01:27 -0800756 if (!session || cptr != input.data() + input.size()) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400757 fprintf(stderr, "d2i_SSL_SESSION failed\n");
758 return false;
759 }
760
David Benjamin1d77e562015-03-22 17:22:08 -0400761 // Verify the SSL_SESSION encoding round-trips via the legacy API.
762 int len = i2d_SSL_SESSION(session.get(), NULL);
763 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400764 fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400765 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400766 }
767
David Benjamin1d77e562015-03-22 17:22:08 -0400768 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
769 if (!encoded) {
David Benjamin751e8892014-10-19 00:59:36 -0400770 fprintf(stderr, "malloc failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400771 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400772 }
David Benjamin1d77e562015-03-22 17:22:08 -0400773
774 ptr = encoded.get();
775 len = i2d_SSL_SESSION(session.get(), &ptr);
776 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400777 fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400778 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400779 }
David Benjamin1d77e562015-03-22 17:22:08 -0400780 if (ptr != encoded.get() + input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400781 fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400782 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400783 }
David Benjamin17cf2cb2016-12-13 01:07:13 -0500784 if (OPENSSL_memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin751e8892014-10-19 00:59:36 -0400785 fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400786 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400787 }
788
David Benjamin1d77e562015-03-22 17:22:08 -0400789 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400790}
791
David Benjaminf297e022015-05-28 19:55:29 -0400792static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
793 std::vector<uint8_t> input;
794 if (!DecodeBase64(&input, input_b64)) {
795 return false;
796 }
797
798 // Verify that the SSL_SESSION fails to decode.
Adam Langley46db7af2017-02-01 15:49:37 -0800799 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
800 if (!ssl_ctx) {
801 return false;
802 }
803 bssl::UniquePtr<SSL_SESSION> session(
804 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
David Benjaminf297e022015-05-28 19:55:29 -0400805 if (session) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400806 fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
David Benjaminf297e022015-05-28 19:55:29 -0400807 return false;
808 }
809 ERR_clear_error();
810 return true;
811}
812
David Benjamin321fcdc2017-04-24 11:42:42 -0400813static void ExpectDefaultVersion(uint16_t min_version, uint16_t max_version,
814 const SSL_METHOD *(*method)(void)) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700815 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
David Benjamin321fcdc2017-04-24 11:42:42 -0400816 ASSERT_TRUE(ctx);
David Benjaminfc08dfc2017-06-20 14:39:32 -0400817 EXPECT_EQ(min_version, ctx->conf_min_version);
818 EXPECT_EQ(max_version, ctx->conf_max_version);
David Benjamin321fcdc2017-04-24 11:42:42 -0400819}
820
821TEST(SSLTest, DefaultVersion) {
822 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
823 ExpectDefaultVersion(TLS1_VERSION, TLS1_2_VERSION, &TLS_method);
824 ExpectDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method);
825 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method);
826 ExpectDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method);
827 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method);
828 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method);
829 ExpectDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method);
David Benjamin82c9e902014-12-12 15:55:27 -0500830}
831
David Benjamin348f0d82017-08-10 16:06:27 -0400832TEST(SSLTest, CipherProperties) {
David Benjamin6fff3862017-06-21 21:07:04 -0400833 static const struct {
834 int id;
835 const char *standard_name;
David Benjamin348f0d82017-08-10 16:06:27 -0400836 int cipher_nid;
837 int digest_nid;
838 int kx_nid;
839 int auth_nid;
David Benjaminb1b76ae2017-09-21 17:03:34 -0400840 int prf_nid;
David Benjamin6fff3862017-06-21 21:07:04 -0400841 } kTests[] = {
David Benjamin348f0d82017-08-10 16:06:27 -0400842 {
843 SSL3_CK_RSA_DES_192_CBC3_SHA,
844 "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
845 NID_des_ede3_cbc,
846 NID_sha1,
847 NID_kx_rsa,
848 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400849 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400850 },
851 {
852 TLS1_CK_RSA_WITH_AES_128_SHA,
853 "TLS_RSA_WITH_AES_128_CBC_SHA",
854 NID_aes_128_cbc,
855 NID_sha1,
856 NID_kx_rsa,
857 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400858 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400859 },
860 {
861 TLS1_CK_PSK_WITH_AES_256_CBC_SHA,
862 "TLS_PSK_WITH_AES_256_CBC_SHA",
863 NID_aes_256_cbc,
864 NID_sha1,
865 NID_kx_psk,
866 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400867 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400868 },
869 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400870 TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA,
871 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
David Benjamin348f0d82017-08-10 16:06:27 -0400872 NID_aes_128_cbc,
David Benjamin6e678ee2018-04-16 19:54:42 -0400873 NID_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400874 NID_kx_ecdhe,
875 NID_auth_rsa,
David Benjamin6e678ee2018-04-16 19:54:42 -0400876 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400877 },
878 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400879 TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA,
880 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
David Benjamin348f0d82017-08-10 16:06:27 -0400881 NID_aes_256_cbc,
David Benjamin6e678ee2018-04-16 19:54:42 -0400882 NID_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400883 NID_kx_ecdhe,
884 NID_auth_rsa,
David Benjamin6e678ee2018-04-16 19:54:42 -0400885 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400886 },
887 {
888 TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
889 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
890 NID_aes_128_gcm,
891 NID_undef,
892 NID_kx_ecdhe,
893 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400894 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400895 },
896 {
897 TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
898 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
899 NID_aes_128_gcm,
900 NID_undef,
901 NID_kx_ecdhe,
902 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400903 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400904 },
905 {
906 TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
907 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
908 NID_aes_256_gcm,
909 NID_undef,
910 NID_kx_ecdhe,
911 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400912 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -0400913 },
914 {
915 TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
916 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
917 NID_aes_128_cbc,
918 NID_sha1,
919 NID_kx_ecdhe,
920 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400921 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400922 },
923 {
924 TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
925 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
926 NID_chacha20_poly1305,
927 NID_undef,
928 NID_kx_ecdhe,
929 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400930 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400931 },
932 {
933 TLS1_CK_AES_256_GCM_SHA384,
934 "TLS_AES_256_GCM_SHA384",
935 NID_aes_256_gcm,
936 NID_undef,
937 NID_kx_any,
938 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400939 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -0400940 },
941 {
942 TLS1_CK_AES_128_GCM_SHA256,
943 "TLS_AES_128_GCM_SHA256",
944 NID_aes_128_gcm,
945 NID_undef,
946 NID_kx_any,
947 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400948 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400949 },
950 {
951 TLS1_CK_CHACHA20_POLY1305_SHA256,
952 "TLS_CHACHA20_POLY1305_SHA256",
953 NID_chacha20_poly1305,
954 NID_undef,
955 NID_kx_any,
956 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400957 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400958 },
David Benjamin6fff3862017-06-21 21:07:04 -0400959 };
David Benjamin65226252015-02-05 16:49:47 -0500960
David Benjamin6fff3862017-06-21 21:07:04 -0400961 for (const auto &t : kTests) {
962 SCOPED_TRACE(t.standard_name);
David Benjamine11726a2017-04-23 12:14:28 -0400963
964 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(t.id & 0xffff);
965 ASSERT_TRUE(cipher);
David Benjamin6fff3862017-06-21 21:07:04 -0400966 EXPECT_STREQ(t.standard_name, SSL_CIPHER_standard_name(cipher));
967
David Benjamine11726a2017-04-23 12:14:28 -0400968 bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
969 ASSERT_TRUE(rfc_name);
David Benjamin6fff3862017-06-21 21:07:04 -0400970 EXPECT_STREQ(t.standard_name, rfc_name.get());
David Benjamin348f0d82017-08-10 16:06:27 -0400971
972 EXPECT_EQ(t.cipher_nid, SSL_CIPHER_get_cipher_nid(cipher));
973 EXPECT_EQ(t.digest_nid, SSL_CIPHER_get_digest_nid(cipher));
974 EXPECT_EQ(t.kx_nid, SSL_CIPHER_get_kx_nid(cipher));
975 EXPECT_EQ(t.auth_nid, SSL_CIPHER_get_auth_nid(cipher));
David Benjaminb1b76ae2017-09-21 17:03:34 -0400976 EXPECT_EQ(t.prf_nid, SSL_CIPHER_get_prf_nid(cipher));
David Benjamin65226252015-02-05 16:49:47 -0500977 }
David Benjamin65226252015-02-05 16:49:47 -0500978}
979
Steven Valdeza833c352016-11-01 13:39:36 -0400980// CreateSessionWithTicket returns a sample |SSL_SESSION| with the specified
981// version and ticket length or nullptr on failure.
982static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(uint16_t version,
983 size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -0400984 std::vector<uint8_t> der;
985 if (!DecodeBase64(&der, kOpenSSLSession)) {
986 return nullptr;
987 }
Adam Langley46db7af2017-02-01 15:49:37 -0800988
989 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
990 if (!ssl_ctx) {
991 return nullptr;
992 }
David Benjaminaaef8332018-06-29 16:45:49 -0400993 // Use a garbage ticket.
994 std::vector<uint8_t> ticket(ticket_len, 'a');
Steven Valdeza833c352016-11-01 13:39:36 -0400995 bssl::UniquePtr<SSL_SESSION> session(
Adam Langley46db7af2017-02-01 15:49:37 -0800996 SSL_SESSION_from_bytes(der.data(), der.size(), ssl_ctx.get()));
David Benjaminaaef8332018-06-29 16:45:49 -0400997 if (!session ||
998 !SSL_SESSION_set_protocol_version(session.get(), version) ||
999 !SSL_SESSION_set_ticket(session.get(), ticket.data(), ticket.size())) {
David Benjamin422fe082015-07-21 22:03:43 -04001000 return nullptr;
1001 }
David Benjamin1269ddd2015-10-18 15:18:55 -04001002 // Fix up the timeout.
David Benjamin9b63f292016-11-15 00:44:05 -05001003#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
David Benjaminaaef8332018-06-29 16:45:49 -04001004 SSL_SESSION_set_time(session.get(), 1234);
David Benjamin9b63f292016-11-15 00:44:05 -05001005#else
David Benjaminaaef8332018-06-29 16:45:49 -04001006 SSL_SESSION_set_time(session.get(), time(nullptr));
David Benjamin9b63f292016-11-15 00:44:05 -05001007#endif
David Benjamin422fe082015-07-21 22:03:43 -04001008 return session;
1009}
1010
David Benjaminafc64de2016-07-19 17:12:41 +02001011static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001012 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +02001013 if (!bio) {
1014 return false;
1015 }
1016 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -04001017 BIO_up_ref(bio.get());
1018 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +02001019 int ret = SSL_connect(ssl);
1020 if (ret > 0) {
1021 // SSL_connect should fail without a BIO to write to.
1022 return false;
1023 }
1024 ERR_clear_error();
1025
1026 const uint8_t *client_hello;
1027 size_t client_hello_len;
1028 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
1029 return false;
1030 }
1031 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
1032 return true;
1033}
1034
Steven Valdeza833c352016-11-01 13:39:36 -04001035// GetClientHelloLen creates a client SSL connection with the specified version
1036// and ticket length. It returns the length of the ClientHello, not including
1037// the record header, on success and zero on error.
1038static size_t GetClientHelloLen(uint16_t max_version, uint16_t session_version,
1039 size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001040 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Steven Valdeza833c352016-11-01 13:39:36 -04001041 bssl::UniquePtr<SSL_SESSION> session =
1042 CreateSessionWithTicket(session_version, ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -04001043 if (!ctx || !session) {
1044 return 0;
1045 }
Steven Valdeza833c352016-11-01 13:39:36 -04001046
1047 // Set a one-element cipher list so the baseline ClientHello is unpadded.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001048 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
Steven Valdez2c62fe92016-10-14 12:08:12 -04001049 if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -08001050 !SSL_set_strict_cipher_list(ssl.get(), "ECDHE-RSA-AES128-GCM-SHA256") ||
Steven Valdeza833c352016-11-01 13:39:36 -04001051 !SSL_set_max_proto_version(ssl.get(), max_version)) {
David Benjamin422fe082015-07-21 22:03:43 -04001052 return 0;
1053 }
Steven Valdeza833c352016-11-01 13:39:36 -04001054
David Benjaminafc64de2016-07-19 17:12:41 +02001055 std::vector<uint8_t> client_hello;
1056 if (!GetClientHello(ssl.get(), &client_hello) ||
1057 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -04001058 return 0;
1059 }
Steven Valdeza833c352016-11-01 13:39:36 -04001060
David Benjaminafc64de2016-07-19 17:12:41 +02001061 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -04001062}
1063
1064struct PaddingTest {
1065 size_t input_len, padded_len;
1066};
1067
1068static const PaddingTest kPaddingTests[] = {
1069 // ClientHellos of length below 0x100 do not require padding.
1070 {0xfe, 0xfe},
1071 {0xff, 0xff},
1072 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
1073 {0x100, 0x200},
1074 {0x123, 0x200},
1075 {0x1fb, 0x200},
1076 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
1077 // padding extension takes a minimum of four bytes plus one required content
1078 // byte. (To work around yet more server bugs, we avoid empty final
1079 // extensions.)
1080 {0x1fc, 0x201},
1081 {0x1fd, 0x202},
1082 {0x1fe, 0x203},
1083 {0x1ff, 0x204},
1084 // Finally, larger ClientHellos need no padding.
1085 {0x200, 0x200},
1086 {0x201, 0x201},
1087};
1088
Steven Valdeza833c352016-11-01 13:39:36 -04001089static bool TestPaddingExtension(uint16_t max_version,
1090 uint16_t session_version) {
David Benjamin422fe082015-07-21 22:03:43 -04001091 // Sample a baseline length.
Steven Valdeza833c352016-11-01 13:39:36 -04001092 size_t base_len = GetClientHelloLen(max_version, session_version, 1);
David Benjamin422fe082015-07-21 22:03:43 -04001093 if (base_len == 0) {
1094 return false;
1095 }
1096
1097 for (const PaddingTest &test : kPaddingTests) {
1098 if (base_len > test.input_len) {
Steven Valdeza833c352016-11-01 13:39:36 -04001099 fprintf(stderr,
1100 "Baseline ClientHello too long (max_version = %04x, "
1101 "session_version = %04x).\n",
1102 max_version, session_version);
David Benjamin422fe082015-07-21 22:03:43 -04001103 return false;
1104 }
1105
Steven Valdeza833c352016-11-01 13:39:36 -04001106 size_t padded_len = GetClientHelloLen(max_version, session_version,
1107 1 + test.input_len - base_len);
David Benjamin422fe082015-07-21 22:03:43 -04001108 if (padded_len != test.padded_len) {
Steven Valdeza833c352016-11-01 13:39:36 -04001109 fprintf(stderr,
1110 "%u-byte ClientHello padded to %u bytes, not %u (max_version = "
1111 "%04x, session_version = %04x).\n",
David Benjamin422fe082015-07-21 22:03:43 -04001112 static_cast<unsigned>(test.input_len),
1113 static_cast<unsigned>(padded_len),
Steven Valdeza833c352016-11-01 13:39:36 -04001114 static_cast<unsigned>(test.padded_len), max_version,
1115 session_version);
David Benjamin422fe082015-07-21 22:03:43 -04001116 return false;
1117 }
1118 }
Steven Valdeza833c352016-11-01 13:39:36 -04001119
David Benjamin422fe082015-07-21 22:03:43 -04001120 return true;
1121}
1122
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001123static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001124 static const char kCertPEM[] =
1125 "-----BEGIN CERTIFICATE-----\n"
1126 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1127 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1128 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1129 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1130 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1131 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1132 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1133 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1134 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1135 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1136 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1137 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1138 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1139 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001140 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
David Benjamin1444c3a2016-12-20 17:23:11 -05001141 return bssl::UniquePtr<X509>(
1142 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjaminde942382016-02-11 12:02:01 -05001143}
1144
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001145static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001146 static const char kKeyPEM[] =
1147 "-----BEGIN RSA PRIVATE KEY-----\n"
1148 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1149 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1150 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1151 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1152 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1153 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1154 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1155 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1156 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1157 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1158 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1159 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1160 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1161 "-----END RSA PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001162 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1163 return bssl::UniquePtr<EVP_PKEY>(
David Benjaminde942382016-02-11 12:02:01 -05001164 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1165}
1166
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001167static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001168 static const char kCertPEM[] =
1169 "-----BEGIN CERTIFICATE-----\n"
1170 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1171 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1172 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1173 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1174 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1175 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1176 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1177 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1178 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1179 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1180 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001181 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1182 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjamin0fc37ef2016-08-17 15:29:46 -04001183}
1184
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001185static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001186 static const char kKeyPEM[] =
1187 "-----BEGIN PRIVATE KEY-----\n"
1188 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1189 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1190 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1191 "-----END PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001192 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1193 return bssl::UniquePtr<EVP_PKEY>(
David Benjamin0fc37ef2016-08-17 15:29:46 -04001194 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1195}
1196
Adam Langleyd04ca952017-02-28 11:26:51 -08001197static bssl::UniquePtr<CRYPTO_BUFFER> BufferFromPEM(const char *pem) {
1198 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1199 char *name, *header;
1200 uint8_t *data;
1201 long data_len;
1202 if (!PEM_read_bio(bio.get(), &name, &header, &data,
1203 &data_len)) {
1204 return nullptr;
1205 }
1206 OPENSSL_free(name);
1207 OPENSSL_free(header);
1208
1209 auto ret = bssl::UniquePtr<CRYPTO_BUFFER>(
1210 CRYPTO_BUFFER_new(data, data_len, nullptr));
1211 OPENSSL_free(data);
1212 return ret;
1213}
1214
1215static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestCertificateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001216 static const char kCertPEM[] =
1217 "-----BEGIN CERTIFICATE-----\n"
1218 "MIIC0jCCAbqgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQiBD\n"
1219 "QTAeFw0xNjAyMjgyMDI3MDNaFw0yNjAyMjUyMDI3MDNaMBgxFjAUBgNVBAMMDUNs\n"
1220 "aWVudCBDZXJ0IEEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRvaz8\n"
1221 "CC/cshpCafJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/\n"
1222 "kLRcH89M/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3\n"
1223 "tHb+xs2PSs8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+c\n"
1224 "IDs2rQ+lP7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1\n"
1225 "z7C8jU50Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9V\n"
1226 "iLeXANgZi+Xx9KgfAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI\n"
1227 "KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBFEVbmYl+2RtNw\n"
1228 "rDftRDF1v2QUbcN2ouSnQDHxeDQdSgasLzT3ui8iYu0Rw2WWcZ0DV5e0ztGPhWq7\n"
1229 "AO0B120aFRMOY+4+bzu9Q2FFkQqc7/fKTvTDzIJI5wrMnFvUfzzvxh3OHWMYSs/w\n"
1230 "giq33hTKeHEq6Jyk3btCny0Ycecyc3yGXH10sizUfiHlhviCkDuESk8mFDwDDzqW\n"
1231 "ZF0IipzFbEDHoIxLlm3GQxpiLoEV4k8KYJp3R5KBLFyxM6UGPz8h72mIPCJp2RuK\n"
1232 "MYgF91UDvVzvnYm6TfseM2+ewKirC00GOrZ7rEcFvtxnKSqYf4ckqfNdSU1Y+RRC\n"
1233 "1ngWZ7Ih\n"
1234 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001235 return BufferFromPEM(kCertPEM);
David Benjamin1444c3a2016-12-20 17:23:11 -05001236}
1237
Adam Langleyd04ca952017-02-28 11:26:51 -08001238static bssl::UniquePtr<X509> X509FromBuffer(
1239 bssl::UniquePtr<CRYPTO_BUFFER> buffer) {
1240 if (!buffer) {
1241 return nullptr;
1242 }
1243 const uint8_t *derp = CRYPTO_BUFFER_data(buffer.get());
1244 return bssl::UniquePtr<X509>(
1245 d2i_X509(NULL, &derp, CRYPTO_BUFFER_len(buffer.get())));
1246}
1247
1248static bssl::UniquePtr<X509> GetChainTestCertificate() {
1249 return X509FromBuffer(GetChainTestCertificateBuffer());
1250}
1251
1252static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestIntermediateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001253 static const char kCertPEM[] =
1254 "-----BEGIN CERTIFICATE-----\n"
1255 "MIICwjCCAaqgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS\n"
1256 "b290IENBMB4XDTE2MDIyODIwMjcwM1oXDTI2MDIyNTIwMjcwM1owDzENMAsGA1UE\n"
1257 "AwwEQiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALsSCYmDip2D\n"
1258 "GkjFxw7ykz26JSjELkl6ArlYjFJ3aT/SCh8qbS4gln7RH8CPBd78oFdfhIKQrwtZ\n"
1259 "3/q21ykD9BAS3qHe2YdcJfm8/kWAy5DvXk6NXU4qX334KofBAEpgdA/igEFq1P1l\n"
1260 "HAuIfZCpMRfT+i5WohVsGi8f/NgpRvVaMONLNfgw57mz1lbtFeBEISmX0kbsuJxF\n"
1261 "Qj/Bwhi5/0HAEXG8e7zN4cEx0yPRvmOATRdVb/8dW2pwOHRJq9R5M0NUkIsTSnL7\n"
1262 "6N/z8hRAHMsV3IudC5Yd7GXW1AGu9a+iKU+Q4xcZCoj0DC99tL4VKujrV1kAeqsM\n"
1263 "cz5/dKzi6+cCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
1264 "AQYwDQYJKoZIhvcNAQELBQADggEBAIIeZiEeNhWWQ8Y4D+AGDwqUUeG8NjCbKrXQ\n"
1265 "BlHg5wZ8xftFaiP1Dp/UAezmx2LNazdmuwrYB8lm3FVTyaPDTKEGIPS4wJKHgqH1\n"
1266 "QPDhqNm85ey7TEtI9oYjsNim/Rb+iGkIAMXaxt58SzxbjvP0kMr1JfJIZbic9vye\n"
1267 "NwIspMFIpP3FB8ywyu0T0hWtCQgL4J47nigCHpOu58deP88fS/Nyz/fyGVWOZ76b\n"
1268 "WhWwgM3P3X95fQ3d7oFPR/bVh0YV+Cf861INwplokXgXQ3/TCQ+HNXeAMWn3JLWv\n"
1269 "XFwk8owk9dq/kQGdndGgy3KTEW4ctPX5GNhf3LJ9Q7dLji4ReQ4=\n"
1270 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001271 return BufferFromPEM(kCertPEM);
1272}
1273
1274static bssl::UniquePtr<X509> GetChainTestIntermediate() {
1275 return X509FromBuffer(GetChainTestIntermediateBuffer());
David Benjamin1444c3a2016-12-20 17:23:11 -05001276}
1277
1278static bssl::UniquePtr<EVP_PKEY> GetChainTestKey() {
1279 static const char kKeyPEM[] =
1280 "-----BEGIN PRIVATE KEY-----\n"
1281 "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRvaz8CC/cshpC\n"
1282 "afJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/kLRcH89M\n"
1283 "/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3tHb+xs2P\n"
1284 "Ss8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+cIDs2rQ+l\n"
1285 "P7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1z7C8jU50\n"
1286 "Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9ViLeXANgZ\n"
1287 "i+Xx9KgfAgMBAAECggEBAK0VjSJzkyPaamcyTVSWjo7GdaBGcK60lk657RjR+lK0\n"
1288 "YJ7pkej4oM2hdsVZFsP8Cs4E33nXLa/0pDsRov/qrp0WQm2skwqGMC1I/bZ0WRPk\n"
1289 "wHaDrBBfESWnJDX/AGpVtlyOjPmgmK6J2usMPihQUDkKdAYrVWJePrMIxt1q6BMe\n"
1290 "iczs3qriMmtY3bUc4UyUwJ5fhDLjshHvfuIpYQyI6EXZM6dZksn9LylXJnigY6QJ\n"
1291 "HxOYO0BDwOsZ8yQ8J8afLk88i0GizEkgE1z3REtQUwgWfxr1WV/ud+T6/ZhSAgH9\n"
1292 "042mQvSFZnIUSEsmCvjhWuAunfxHKCTcAoYISWfzWpkCgYEA7gpf3HHU5Tn+CgUn\n"
1293 "1X5uGpG3DmcMgfeGgs2r2f/IIg/5Ac1dfYILiybL1tN9zbyLCJfcbFpWBc9hJL6f\n"
1294 "CPc5hUiwWFJqBJewxQkC1Ae/HakHbip+IZ+Jr0842O4BAArvixk4Lb7/N2Ct9sTE\n"
1295 "NJO6RtK9lbEZ5uK61DglHy8CS2UCgYEA4ZC1o36kPAMQBggajgnucb2yuUEelk0f\n"
1296 "AEr+GI32MGE+93xMr7rAhBoqLg4AITyIfEnOSQ5HwagnIHonBbv1LV/Gf9ursx8Z\n"
1297 "YOGbvT8zzzC+SU1bkDzdjAYnFQVGIjMtKOBJ3K07++ypwX1fr4QsQ8uKL8WSOWwt\n"
1298 "Z3Bym6XiZzMCgYADnhy+2OwHX85AkLt+PyGlPbmuelpyTzS4IDAQbBa6jcuW/2wA\n"
1299 "UE2km75VUXmD+u2R/9zVuLm99NzhFhSMqlUxdV1YukfqMfP5yp1EY6m/5aW7QuIP\n"
1300 "2MDa7TVL9rIFMiVZ09RKvbBbQxjhuzPQKL6X/PPspnhiTefQ+dl2k9xREQKBgHDS\n"
1301 "fMfGNEeAEKezrfSVqxphE9/tXms3L+ZpnCaT+yu/uEr5dTIAawKoQ6i9f/sf1/Sy\n"
1302 "xedsqR+IB+oKrzIDDWMgoJybN4pkZ8E5lzhVQIjFjKgFdWLzzqyW9z1gYfABQPlN\n"
1303 "FiS20WX0vgP1vcKAjdNrHzc9zyHBpgQzDmAj3NZZAoGBAI8vKCKdH7w3aL5CNkZQ\n"
1304 "2buIeWNA2HZazVwAGG5F2TU/LmXfRKnG6dX5bkU+AkBZh56jNZy//hfFSewJB4Kk\n"
1305 "buB7ERSdaNbO21zXt9FEA3+z0RfMd/Zv2vlIWOSB5nzl/7UKti3sribK6s9ZVLfi\n"
1306 "SxpiPQ8d/hmSGwn4ksrWUsJD\n"
1307 "-----END PRIVATE KEY-----\n";
1308 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1309 return bssl::UniquePtr<EVP_PKEY>(
1310 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1311}
1312
David Benjaminc79ae7a2017-08-29 16:09:44 -04001313// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
1314// before configuring as a server.
1315TEST(SSLTest, ClientCAList) {
1316 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1317 ASSERT_TRUE(ctx);
1318 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1319 ASSERT_TRUE(ssl);
1320
1321 bssl::UniquePtr<X509_NAME> name(X509_NAME_new());
1322 ASSERT_TRUE(name);
1323
1324 bssl::UniquePtr<X509_NAME> name_dup(X509_NAME_dup(name.get()));
1325 ASSERT_TRUE(name_dup);
1326
1327 bssl::UniquePtr<STACK_OF(X509_NAME)> stack(sk_X509_NAME_new_null());
1328 ASSERT_TRUE(stack);
David Benjamin2908dd12018-06-29 17:46:42 -04001329 ASSERT_TRUE(PushToStack(stack.get(), std::move(name_dup)));
David Benjaminc79ae7a2017-08-29 16:09:44 -04001330
1331 // |SSL_set_client_CA_list| takes ownership.
1332 SSL_set_client_CA_list(ssl.get(), stack.release());
1333
1334 STACK_OF(X509_NAME) *result = SSL_get_client_CA_list(ssl.get());
1335 ASSERT_TRUE(result);
1336 ASSERT_EQ(1u, sk_X509_NAME_num(result));
1337 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(result, 0), name.get()));
1338}
1339
1340TEST(SSLTest, AddClientCA) {
1341 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1342 ASSERT_TRUE(ctx);
1343 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1344 ASSERT_TRUE(ssl);
1345
1346 bssl::UniquePtr<X509> cert1 = GetTestCertificate();
1347 bssl::UniquePtr<X509> cert2 = GetChainTestCertificate();
1348 ASSERT_TRUE(cert1 && cert2);
1349 X509_NAME *name1 = X509_get_subject_name(cert1.get());
1350 X509_NAME *name2 = X509_get_subject_name(cert2.get());
1351
1352 EXPECT_EQ(0u, sk_X509_NAME_num(SSL_get_client_CA_list(ssl.get())));
1353
1354 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1355 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert2.get()));
1356
1357 STACK_OF(X509_NAME) *list = SSL_get_client_CA_list(ssl.get());
1358 ASSERT_EQ(2u, sk_X509_NAME_num(list));
1359 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1360 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1361
1362 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1363
1364 list = SSL_get_client_CA_list(ssl.get());
1365 ASSERT_EQ(3u, sk_X509_NAME_num(list));
1366 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1367 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1368 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 2), name1));
1369}
1370
1371static void AppendSession(SSL_SESSION *session, void *arg) {
1372 std::vector<SSL_SESSION*> *out =
1373 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
1374 out->push_back(session);
1375}
1376
1377// CacheEquals returns true if |ctx|'s session cache consists of |expected|, in
1378// order.
1379static bool CacheEquals(SSL_CTX *ctx,
1380 const std::vector<SSL_SESSION*> &expected) {
1381 // Check the linked list.
1382 SSL_SESSION *ptr = ctx->session_cache_head;
1383 for (SSL_SESSION *session : expected) {
1384 if (ptr != session) {
1385 return false;
1386 }
1387 // TODO(davidben): This is an absurd way to denote the end of the list.
1388 if (ptr->next ==
1389 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
1390 ptr = nullptr;
1391 } else {
1392 ptr = ptr->next;
1393 }
1394 }
1395 if (ptr != nullptr) {
1396 return false;
1397 }
1398
1399 // Check the hash table.
1400 std::vector<SSL_SESSION*> actual, expected_copy;
David Benjamin9eaa3bd2017-09-27 17:03:54 -04001401 lh_SSL_SESSION_doall_arg(ctx->sessions, AppendSession, &actual);
David Benjaminc79ae7a2017-08-29 16:09:44 -04001402 expected_copy = expected;
1403
1404 std::sort(actual.begin(), actual.end());
1405 std::sort(expected_copy.begin(), expected_copy.end());
1406
1407 return actual == expected_copy;
1408}
1409
1410static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
1411 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
1412 if (!ssl_ctx) {
1413 return nullptr;
1414 }
1415 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new(ssl_ctx.get()));
1416 if (!ret) {
1417 return nullptr;
1418 }
1419
David Benjaminaaef8332018-06-29 16:45:49 -04001420 uint8_t id[SSL3_SSL_SESSION_ID_LENGTH] = {0};
1421 OPENSSL_memcpy(id, &number, sizeof(number));
1422 if (!SSL_SESSION_set1_id(ret.get(), id, sizeof(id))) {
1423 return nullptr;
1424 }
David Benjaminc79ae7a2017-08-29 16:09:44 -04001425 return ret;
1426}
1427
1428// Test that the internal session cache behaves as expected.
1429TEST(SSLTest, InternalSessionCache) {
1430 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1431 ASSERT_TRUE(ctx);
1432
1433 // Prepare 10 test sessions.
1434 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
1435 for (int i = 0; i < 10; i++) {
1436 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
1437 ASSERT_TRUE(session);
1438 sessions.push_back(std::move(session));
1439 }
1440
1441 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1442
1443 // Insert all the test sessions.
1444 for (const auto &session : sessions) {
1445 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), session.get()));
1446 }
1447
1448 // Only the last five should be in the list.
1449 ASSERT_TRUE(CacheEquals(
1450 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
1451 sessions[6].get(), sessions[5].get()}));
1452
1453 // Inserting an element already in the cache should fail and leave the cache
1454 // unchanged.
1455 ASSERT_FALSE(SSL_CTX_add_session(ctx.get(), sessions[7].get()));
1456 ASSERT_TRUE(CacheEquals(
1457 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
1458 sessions[6].get(), sessions[5].get()}));
1459
1460 // Although collisions should be impossible (256-bit session IDs), the cache
1461 // must handle them gracefully.
1462 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
1463 ASSERT_TRUE(collision);
1464 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), collision.get()));
1465 ASSERT_TRUE(CacheEquals(
1466 ctx.get(), {collision.get(), sessions[9].get(), sessions[8].get(),
1467 sessions[6].get(), sessions[5].get()}));
1468
1469 // Removing sessions behaves correctly.
1470 ASSERT_TRUE(SSL_CTX_remove_session(ctx.get(), sessions[6].get()));
1471 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
1472 sessions[8].get(), sessions[5].get()}));
1473
1474 // Removing sessions requires an exact match.
1475 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[0].get()));
1476 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[7].get()));
1477
1478 // The cache remains unchanged.
1479 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
1480 sessions[8].get(), sessions[5].get()}));
1481}
1482
1483static uint16_t EpochFromSequence(uint64_t seq) {
1484 return static_cast<uint16_t>(seq >> 48);
1485}
1486
David Benjamin71dfad42017-07-16 17:27:39 -04001487static const uint8_t kTestName[] = {
1488 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
1489 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
1490 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
1491 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
1492 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
1493 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64,
1494};
1495
David Benjaminb79cc842016-12-07 15:57:14 -05001496static bool CompleteHandshakes(SSL *client, SSL *server) {
1497 // Drive both their handshakes to completion.
1498 for (;;) {
1499 int client_ret = SSL_do_handshake(client);
1500 int client_err = SSL_get_error(client, client_ret);
1501 if (client_err != SSL_ERROR_NONE &&
1502 client_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001503 client_err != SSL_ERROR_WANT_WRITE &&
1504 client_err != SSL_ERROR_PENDING_TICKET) {
David Benjaminb79cc842016-12-07 15:57:14 -05001505 fprintf(stderr, "Client error: %d\n", client_err);
1506 return false;
1507 }
1508
1509 int server_ret = SSL_do_handshake(server);
1510 int server_err = SSL_get_error(server, server_ret);
1511 if (server_err != SSL_ERROR_NONE &&
1512 server_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001513 server_err != SSL_ERROR_WANT_WRITE &&
1514 server_err != SSL_ERROR_PENDING_TICKET) {
David Benjaminb79cc842016-12-07 15:57:14 -05001515 fprintf(stderr, "Server error: %d\n", server_err);
1516 return false;
1517 }
1518
1519 if (client_ret == 1 && server_ret == 1) {
1520 break;
1521 }
1522 }
1523
1524 return true;
1525}
1526
David Benjamina8614602017-09-06 15:40:19 -04001527struct ClientConfig {
1528 SSL_SESSION *session = nullptr;
1529 std::string servername;
1530};
1531
David Benjaminb79cc842016-12-07 15:57:14 -05001532static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client,
1533 bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001534 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
Adam Langleyddb57cf2018-01-26 09:17:53 -08001535 const ClientConfig &config = ClientConfig(),
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001536 bool do_handshake = true,
1537 bool shed_handshake_config = true) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001538 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001539 if (!client || !server) {
1540 return false;
1541 }
1542 SSL_set_connect_state(client.get());
1543 SSL_set_accept_state(server.get());
1544
David Benjamina8614602017-09-06 15:40:19 -04001545 if (config.session) {
1546 SSL_set_session(client.get(), config.session);
1547 }
1548 if (!config.servername.empty() &&
1549 !SSL_set_tlsext_host_name(client.get(), config.servername.c_str())) {
1550 return false;
1551 }
David Benjamina20e5352016-08-02 19:09:41 -04001552
David Benjaminde942382016-02-11 12:02:01 -05001553 BIO *bio1, *bio2;
1554 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1555 return false;
1556 }
1557 // SSL_set_bio takes ownership.
1558 SSL_set_bio(client.get(), bio1, bio1);
1559 SSL_set_bio(server.get(), bio2, bio2);
1560
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001561 SSL_set_shed_handshake_config(client.get(), shed_handshake_config);
1562 SSL_set_shed_handshake_config(server.get(), shed_handshake_config);
1563
Adam Langleyddb57cf2018-01-26 09:17:53 -08001564 if (do_handshake && !CompleteHandshakes(client.get(), server.get())) {
David Benjaminb79cc842016-12-07 15:57:14 -05001565 return false;
David Benjaminde942382016-02-11 12:02:01 -05001566 }
1567
David Benjamin686bb192016-05-10 15:15:41 -04001568 *out_client = std::move(client);
1569 *out_server = std::move(server);
1570 return true;
1571}
1572
David Benjaminc11ea9422017-08-29 16:33:21 -04001573// SSLVersionTest executes its test cases under all available protocol versions.
1574// Test cases call |Connect| to create a connection using context objects with
1575// the protocol version fixed to the current version under test.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001576class SSLVersionTest : public ::testing::TestWithParam<VersionParam> {
1577 protected:
1578 SSLVersionTest() : cert_(GetTestCertificate()), key_(GetTestKey()) {}
1579
1580 void SetUp() { ResetContexts(); }
1581
1582 bssl::UniquePtr<SSL_CTX> CreateContext() const {
1583 const SSL_METHOD *method = is_dtls() ? DTLS_method() : TLS_method();
1584 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
1585 if (!ctx || !SSL_CTX_set_min_proto_version(ctx.get(), version()) ||
1586 !SSL_CTX_set_max_proto_version(ctx.get(), version())) {
1587 return nullptr;
1588 }
1589 return ctx;
David Benjamin0fef3052016-11-18 15:11:10 +09001590 }
David Benjamin686bb192016-05-10 15:15:41 -04001591
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001592 void ResetContexts() {
1593 ASSERT_TRUE(cert_);
1594 ASSERT_TRUE(key_);
1595 client_ctx_ = CreateContext();
1596 ASSERT_TRUE(client_ctx_);
1597 server_ctx_ = CreateContext();
1598 ASSERT_TRUE(server_ctx_);
1599 // Set up a server cert. Client certs can be set up explicitly.
1600 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09001601 }
David Benjamin686bb192016-05-10 15:15:41 -04001602
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001603 bool UseCertAndKey(SSL_CTX *ctx) const {
1604 return SSL_CTX_use_certificate(ctx, cert_.get()) &&
1605 SSL_CTX_use_PrivateKey(ctx, key_.get());
David Benjamin0fef3052016-11-18 15:11:10 +09001606 }
David Benjamin686bb192016-05-10 15:15:41 -04001607
David Benjamina8614602017-09-06 15:40:19 -04001608 bool Connect(const ClientConfig &config = ClientConfig()) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001609 return ConnectClientAndServer(&client_, &server_, client_ctx_.get(),
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001610 server_ctx_.get(), config, true,
1611 shed_handshake_config_);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001612 }
1613
1614 uint16_t version() const { return GetParam().version; }
1615
1616 bool is_dtls() const {
1617 return GetParam().ssl_method == VersionParam::is_dtls;
1618 }
1619
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001620 bool shed_handshake_config_ = true;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001621 bssl::UniquePtr<SSL> client_, server_;
1622 bssl::UniquePtr<SSL_CTX> server_ctx_, client_ctx_;
1623 bssl::UniquePtr<X509> cert_;
1624 bssl::UniquePtr<EVP_PKEY> key_;
1625};
1626
1627INSTANTIATE_TEST_CASE_P(WithVersion, SSLVersionTest,
1628 testing::ValuesIn(kAllVersions),
1629 [](const testing::TestParamInfo<VersionParam> &i) {
1630 return i.param.name;
1631 });
1632
1633TEST_P(SSLVersionTest, SequenceNumber) {
1634 ASSERT_TRUE(Connect());
1635
David Benjamin0fef3052016-11-18 15:11:10 +09001636 // Drain any post-handshake messages to ensure there are no unread records
1637 // on either end.
1638 uint8_t byte = 0;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001639 ASSERT_LE(SSL_read(client_.get(), &byte, 1), 0);
1640 ASSERT_LE(SSL_read(server_.get(), &byte, 1), 0);
David Benjaminde942382016-02-11 12:02:01 -05001641
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001642 uint64_t client_read_seq = SSL_get_read_sequence(client_.get());
1643 uint64_t client_write_seq = SSL_get_write_sequence(client_.get());
1644 uint64_t server_read_seq = SSL_get_read_sequence(server_.get());
1645 uint64_t server_write_seq = SSL_get_write_sequence(server_.get());
Steven Valdez2c62fe92016-10-14 12:08:12 -04001646
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001647 if (is_dtls()) {
David Benjamin0fef3052016-11-18 15:11:10 +09001648 // Both client and server must be at epoch 1.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001649 EXPECT_EQ(EpochFromSequence(client_read_seq), 1);
1650 EXPECT_EQ(EpochFromSequence(client_write_seq), 1);
1651 EXPECT_EQ(EpochFromSequence(server_read_seq), 1);
1652 EXPECT_EQ(EpochFromSequence(server_write_seq), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09001653
1654 // The next record to be written should exceed the largest received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001655 EXPECT_GT(client_write_seq, server_read_seq);
1656 EXPECT_GT(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09001657 } else {
1658 // The next record to be written should equal the next to be received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001659 EXPECT_EQ(client_write_seq, server_read_seq);
1660 EXPECT_EQ(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09001661 }
1662
1663 // Send a record from client to server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001664 EXPECT_EQ(SSL_write(client_.get(), &byte, 1), 1);
1665 EXPECT_EQ(SSL_read(server_.get(), &byte, 1), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09001666
1667 // The client write and server read sequence numbers should have
1668 // incremented.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001669 EXPECT_EQ(client_write_seq + 1, SSL_get_write_sequence(client_.get()));
1670 EXPECT_EQ(server_read_seq + 1, SSL_get_read_sequence(server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05001671}
1672
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001673TEST_P(SSLVersionTest, OneSidedShutdown) {
David Benjamin68f37b72016-11-18 15:14:42 +09001674 // SSL_shutdown is a no-op in DTLS.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001675 if (is_dtls()) {
1676 return;
David Benjamin686bb192016-05-10 15:15:41 -04001677 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001678 ASSERT_TRUE(Connect());
David Benjamin686bb192016-05-10 15:15:41 -04001679
1680 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1681 // one side has shut down.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001682 ASSERT_EQ(SSL_shutdown(client_.get()), 0);
David Benjamin686bb192016-05-10 15:15:41 -04001683
1684 // Reading from the server should consume the EOF.
1685 uint8_t byte;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001686 ASSERT_EQ(SSL_read(server_.get(), &byte, 1), 0);
1687 ASSERT_EQ(SSL_get_error(server_.get(), 0), SSL_ERROR_ZERO_RETURN);
David Benjamin686bb192016-05-10 15:15:41 -04001688
1689 // However, the server may continue to write data and then shut down the
1690 // connection.
1691 byte = 42;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001692 ASSERT_EQ(SSL_write(server_.get(), &byte, 1), 1);
1693 ASSERT_EQ(SSL_read(client_.get(), &byte, 1), 1);
1694 ASSERT_EQ(byte, 42);
David Benjamin686bb192016-05-10 15:15:41 -04001695
1696 // The server may then shutdown the connection.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001697 EXPECT_EQ(SSL_shutdown(server_.get()), 1);
1698 EXPECT_EQ(SSL_shutdown(client_.get()), 1);
David Benjamin686bb192016-05-10 15:15:41 -04001699}
David Benjamin68f37b72016-11-18 15:14:42 +09001700
David Benjaminf0d8e222017-02-04 10:58:26 -05001701TEST(SSLTest, SessionDuplication) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001702 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1703 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001704 ASSERT_TRUE(client_ctx);
1705 ASSERT_TRUE(server_ctx);
Steven Valdez87eab492016-06-27 16:34:59 -04001706
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001707 bssl::UniquePtr<X509> cert = GetTestCertificate();
1708 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminf0d8e222017-02-04 10:58:26 -05001709 ASSERT_TRUE(cert);
1710 ASSERT_TRUE(key);
1711 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
1712 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04001713
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001714 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05001715 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04001716 server_ctx.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04001717
1718 SSL_SESSION *session0 = SSL_get_session(client.get());
David Benjamin31b0c9b2017-07-20 14:49:15 -04001719 bssl::UniquePtr<SSL_SESSION> session1 =
1720 bssl::SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL);
David Benjaminf0d8e222017-02-04 10:58:26 -05001721 ASSERT_TRUE(session1);
David Benjamin4501bd52016-08-01 13:39:41 -04001722
David Benjamina3a71e92018-06-29 13:24:45 -04001723 session1->not_resumable = false;
Steven Valdez84b5c002016-08-25 16:30:58 -04001724
Steven Valdez87eab492016-06-27 16:34:59 -04001725 uint8_t *s0_bytes, *s1_bytes;
1726 size_t s0_len, s1_len;
1727
David Benjaminf0d8e222017-02-04 10:58:26 -05001728 ASSERT_TRUE(SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001729 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001730
David Benjaminf0d8e222017-02-04 10:58:26 -05001731 ASSERT_TRUE(SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001732 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001733
David Benjamin7d7554b2017-02-04 11:48:59 -05001734 EXPECT_EQ(Bytes(s0_bytes, s0_len), Bytes(s1_bytes, s1_len));
Steven Valdez87eab492016-06-27 16:34:59 -04001735}
David Benjamin686bb192016-05-10 15:15:41 -04001736
David Benjaminf0d8e222017-02-04 10:58:26 -05001737static void ExpectFDs(const SSL *ssl, int rfd, int wfd) {
David Benjaminca743582017-06-15 17:51:35 -04001738 EXPECT_EQ(rfd, SSL_get_fd(ssl));
David Benjaminf0d8e222017-02-04 10:58:26 -05001739 EXPECT_EQ(rfd, SSL_get_rfd(ssl));
1740 EXPECT_EQ(wfd, SSL_get_wfd(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04001741
1742 // The wrapper BIOs are always equal when fds are equal, even if set
1743 // individually.
David Benjaminf0d8e222017-02-04 10:58:26 -05001744 if (rfd == wfd) {
1745 EXPECT_EQ(SSL_get_rbio(ssl), SSL_get_wbio(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04001746 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001747}
1748
David Benjaminf0d8e222017-02-04 10:58:26 -05001749TEST(SSLTest, SetFD) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001750 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001751 ASSERT_TRUE(ctx);
David Benjamin5c0fb882016-06-14 14:03:51 -04001752
1753 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001754 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001755 ASSERT_TRUE(ssl);
1756 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1757 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
1758 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04001759
1760 // Test setting the same FD.
1761 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001762 ASSERT_TRUE(ssl);
1763 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1764 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001765
1766 // Test setting the same FD one side at a time.
1767 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001768 ASSERT_TRUE(ssl);
1769 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1770 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1771 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001772
1773 // Test setting the same FD in the other order.
1774 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001775 ASSERT_TRUE(ssl);
1776 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1777 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1778 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001779
David Benjamin5c0fb882016-06-14 14:03:51 -04001780 // Test changing the read FD partway through.
1781 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001782 ASSERT_TRUE(ssl);
1783 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1784 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 2));
1785 ExpectFDs(ssl.get(), 2, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001786
1787 // Test changing the write FD partway through.
1788 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001789 ASSERT_TRUE(ssl);
1790 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1791 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
1792 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04001793
1794 // Test a no-op change to the read FD partway through.
1795 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001796 ASSERT_TRUE(ssl);
1797 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1798 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1799 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001800
1801 // Test a no-op change to the write FD partway through.
1802 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001803 ASSERT_TRUE(ssl);
1804 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1805 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1806 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001807
1808 // ASan builds will implicitly test that the internal |BIO| reference-counting
1809 // is correct.
David Benjamin5c0fb882016-06-14 14:03:51 -04001810}
1811
David Benjaminf0d8e222017-02-04 10:58:26 -05001812TEST(SSLTest, SetBIO) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001813 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001814 ASSERT_TRUE(ctx);
David Benjamin4501bd52016-08-01 13:39:41 -04001815
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001816 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1817 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04001818 bio3(BIO_new(BIO_s_mem()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001819 ASSERT_TRUE(ssl);
1820 ASSERT_TRUE(bio1);
1821 ASSERT_TRUE(bio2);
1822 ASSERT_TRUE(bio3);
David Benjamin4501bd52016-08-01 13:39:41 -04001823
1824 // SSL_set_bio takes one reference when the parameters are the same.
1825 BIO_up_ref(bio1.get());
1826 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1827
1828 // Repeating the call does nothing.
1829 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1830
1831 // It takes one reference each when the parameters are different.
1832 BIO_up_ref(bio2.get());
1833 BIO_up_ref(bio3.get());
1834 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1835
1836 // Repeating the call does nothing.
1837 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1838
1839 // It takes one reference when changing only wbio.
1840 BIO_up_ref(bio1.get());
1841 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1842
1843 // It takes one reference when changing only rbio and the two are different.
1844 BIO_up_ref(bio3.get());
1845 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1846
1847 // If setting wbio to rbio, it takes no additional references.
1848 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1849
1850 // From there, wbio may be switched to something else.
1851 BIO_up_ref(bio1.get());
1852 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1853
1854 // If setting rbio to wbio, it takes no additional references.
1855 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1856
1857 // From there, rbio may be switched to something else, but, for historical
1858 // reasons, it takes a reference to both parameters.
1859 BIO_up_ref(bio1.get());
1860 BIO_up_ref(bio2.get());
1861 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1862
1863 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1864 // is correct.
David Benjamin4501bd52016-08-01 13:39:41 -04001865}
1866
David Benjamin25490f22016-07-14 00:22:54 -04001867static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1868
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001869TEST_P(SSLVersionTest, GetPeerCertificate) {
1870 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04001871
David Benjamin0fef3052016-11-18 15:11:10 +09001872 // Configure both client and server to accept any certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001873 SSL_CTX_set_verify(client_ctx_.get(),
1874 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1875 nullptr);
1876 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
1877 SSL_CTX_set_verify(server_ctx_.get(),
1878 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1879 nullptr);
1880 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjaminadd5e522016-07-14 00:33:24 -04001881
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001882 ASSERT_TRUE(Connect());
David Benjaminadd5e522016-07-14 00:33:24 -04001883
David Benjamin0fef3052016-11-18 15:11:10 +09001884 // Client and server should both see the leaf certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001885 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1886 ASSERT_TRUE(peer);
1887 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04001888
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001889 peer.reset(SSL_get_peer_certificate(client_.get()));
1890 ASSERT_TRUE(peer);
1891 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04001892
David Benjamine664a532017-07-20 20:19:36 -04001893 // However, for historical reasons, the X509 chain includes the leaf on the
David Benjamin0fef3052016-11-18 15:11:10 +09001894 // client, but does not on the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001895 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(client_.get())), 1u);
1896 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(client_.get())),
1897 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04001898
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001899 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(server_.get())), 0u);
1900 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(server_.get())),
1901 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04001902}
1903
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001904TEST_P(SSLVersionTest, NoPeerCertificate) {
1905 SSL_CTX_set_verify(server_ctx_.get(), SSL_VERIFY_PEER, nullptr);
1906 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
1907 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
David Benjamine664a532017-07-20 20:19:36 -04001908
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001909 ASSERT_TRUE(Connect());
David Benjamine664a532017-07-20 20:19:36 -04001910
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001911 // Server should not see a peer certificate.
1912 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1913 ASSERT_FALSE(peer);
1914 ASSERT_FALSE(SSL_get0_peer_certificates(server_.get()));
David Benjamine664a532017-07-20 20:19:36 -04001915}
1916
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001917TEST_P(SSLVersionTest, RetainOnlySHA256OfCerts) {
David Benjamin25490f22016-07-14 00:22:54 -04001918 uint8_t *cert_der = NULL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001919 int cert_der_len = i2d_X509(cert_.get(), &cert_der);
1920 ASSERT_GE(cert_der_len, 0);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001921 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04001922
1923 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1924 SHA256(cert_der, cert_der_len, cert_sha256);
1925
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001926 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
1927
David Benjamin0fef3052016-11-18 15:11:10 +09001928 // Configure both client and server to accept any certificate, but the
1929 // server must retain only the SHA-256 of the peer.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001930 SSL_CTX_set_verify(client_ctx_.get(),
1931 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1932 nullptr);
1933 SSL_CTX_set_verify(server_ctx_.get(),
1934 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1935 nullptr);
1936 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
1937 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
1938 SSL_CTX_set_retain_only_sha256_of_client_certs(server_ctx_.get(), 1);
David Benjamin25490f22016-07-14 00:22:54 -04001939
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001940 ASSERT_TRUE(Connect());
David Benjamin25490f22016-07-14 00:22:54 -04001941
David Benjamin0fef3052016-11-18 15:11:10 +09001942 // The peer certificate has been dropped.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001943 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1944 EXPECT_FALSE(peer);
David Benjamin25490f22016-07-14 00:22:54 -04001945
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001946 SSL_SESSION *session = SSL_get_session(server_.get());
David Benjamin02de7bd2018-05-08 18:13:54 -04001947 EXPECT_TRUE(SSL_SESSION_has_peer_sha256(session));
David Benjamin25490f22016-07-14 00:22:54 -04001948
David Benjamin02de7bd2018-05-08 18:13:54 -04001949 const uint8_t *peer_sha256;
1950 size_t peer_sha256_len;
1951 SSL_SESSION_get0_peer_sha256(session, &peer_sha256, &peer_sha256_len);
1952 EXPECT_EQ(Bytes(cert_sha256), Bytes(peer_sha256, peer_sha256_len));
David Benjamin25490f22016-07-14 00:22:54 -04001953}
1954
David Benjamin737d2df2017-09-25 15:05:19 -04001955// Tests that our ClientHellos do not change unexpectedly. These are purely
1956// change detection tests. If they fail as part of an intentional ClientHello
1957// change, update the test vector.
1958TEST(SSLTest, ClientHello) {
1959 struct {
1960 uint16_t max_version;
1961 std::vector<uint8_t> expected;
1962 } kTests[] = {
David Benjamin737d2df2017-09-25 15:05:19 -04001963 {TLS1_VERSION,
1964 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x01, 0x00,
1965 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1966 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1967 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
1968 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
Adam Langleyd6680952018-08-23 08:01:23 -07001969 0x01, 0x00, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01,
1970 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
1971 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
David Benjamin737d2df2017-09-25 15:05:19 -04001972 {TLS1_1_VERSION,
1973 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x02, 0x00,
1974 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1975 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1976 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
1977 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
Adam Langleyd6680952018-08-23 08:01:23 -07001978 0x01, 0x00, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01,
1979 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
1980 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
David Benjamin737d2df2017-09-25 15:05:19 -04001981 {TLS1_2_VERSION,
David Benjamin6e678ee2018-04-16 19:54:42 -04001982 {0x16, 0x03, 0x01, 0x00, 0x82, 0x01, 0x00, 0x00, 0x7e, 0x03, 0x03, 0x00,
David Benjamin737d2df2017-09-25 15:05:19 -04001983 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1984 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
David Benjamin6e678ee2018-04-16 19:54:42 -04001985 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xcc, 0xa9,
David Benjamin737d2df2017-09-25 15:05:19 -04001986 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xc0, 0x09,
David Benjamin6e678ee2018-04-16 19:54:42 -04001987 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
Adam Langleyd6680952018-08-23 08:01:23 -07001988 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37, 0x00, 0x17, 0x00, 0x00,
1989 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00,
1990 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1991 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04, 0x03, 0x08,
1992 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06,
1993 0x01, 0x02, 0x01}},
David Benjamin737d2df2017-09-25 15:05:19 -04001994 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
1995 // implementation has settled enough that it won't change.
David Benjaminafc64de2016-07-19 17:12:41 +02001996 };
David Benjamin737d2df2017-09-25 15:05:19 -04001997
1998 for (const auto &t : kTests) {
1999 SCOPED_TRACE(t.max_version);
2000
2001 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2002 ASSERT_TRUE(ctx);
2003 // Our default cipher list varies by CPU capabilities, so manually place the
2004 // ChaCha20 ciphers in front.
2005 const char *cipher_list = "CHACHA20:ALL";
David Benjamin737d2df2017-09-25 15:05:19 -04002006 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), t.max_version));
2007 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list));
2008
2009 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
2010 ASSERT_TRUE(ssl);
2011 std::vector<uint8_t> client_hello;
2012 ASSERT_TRUE(GetClientHello(ssl.get(), &client_hello));
2013
2014 // Zero the client_random.
2015 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
2016 1 + 3 + // handshake message header
2017 2; // client_version
2018 ASSERT_GE(client_hello.size(), kRandomOffset + SSL3_RANDOM_SIZE);
2019 OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
2020
2021 if (client_hello != t.expected) {
2022 ADD_FAILURE() << "ClientHellos did not match.";
2023 // Print the value manually so it is easier to update the test vector.
2024 for (size_t i = 0; i < client_hello.size(); i += 12) {
2025 printf(" %c", i == 0 ? '{' : ' ');
2026 for (size_t j = i; j < client_hello.size() && j < i + 12; j++) {
2027 if (j > i) {
2028 printf(" ");
2029 }
2030 printf("0x%02x", client_hello[j]);
2031 if (j < client_hello.size() - 1) {
2032 printf(",");
2033 }
2034 }
2035 if (i + 12 >= client_hello.size()) {
Adam Langleyd6680952018-08-23 08:01:23 -07002036 printf("}},");
David Benjamin737d2df2017-09-25 15:05:19 -04002037 }
2038 printf("\n");
2039 }
2040 }
David Benjaminafc64de2016-07-19 17:12:41 +02002041 }
David Benjaminafc64de2016-07-19 17:12:41 +02002042}
2043
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002044static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04002045
2046static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
2047 // Save the most recent session.
2048 g_last_session.reset(session);
2049 return 1;
2050}
2051
David Benjamina8614602017-09-06 15:40:19 -04002052static bssl::UniquePtr<SSL_SESSION> CreateClientSession(
2053 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2054 const ClientConfig &config = ClientConfig()) {
David Benjamina20e5352016-08-02 19:09:41 -04002055 g_last_session = nullptr;
2056 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2057
2058 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002059 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04002060 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
David Benjamina8614602017-09-06 15:40:19 -04002061 config)) {
David Benjamina20e5352016-08-02 19:09:41 -04002062 fprintf(stderr, "Failed to connect client and server.\n");
2063 return nullptr;
2064 }
2065
2066 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2067 SSL_read(client.get(), nullptr, 0);
2068
2069 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2070
2071 if (!g_last_session) {
2072 fprintf(stderr, "Client did not receive a session.\n");
2073 return nullptr;
2074 }
2075 return std::move(g_last_session);
2076}
2077
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002078static void ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2079 SSL_SESSION *session, bool want_reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002080 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002081 ClientConfig config;
2082 config.session = session;
2083 EXPECT_TRUE(
2084 ConnectClientAndServer(&client, &server, client_ctx, server_ctx, config));
David Benjamina20e5352016-08-02 19:09:41 -04002085
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002086 EXPECT_EQ(SSL_session_reused(client.get()), SSL_session_reused(server.get()));
David Benjamina20e5352016-08-02 19:09:41 -04002087
2088 bool was_reused = !!SSL_session_reused(client.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002089 EXPECT_EQ(was_reused, want_reused);
David Benjamina20e5352016-08-02 19:09:41 -04002090}
2091
David Benjamin3c51d9b2016-11-01 17:50:42 -04002092static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
2093 SSL_CTX *server_ctx,
2094 SSL_SESSION *session) {
2095 g_last_session = nullptr;
2096 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2097
2098 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002099 ClientConfig config;
2100 config.session = session;
2101 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
2102 config)) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002103 fprintf(stderr, "Failed to connect client and server.\n");
2104 return nullptr;
2105 }
2106
2107 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2108 fprintf(stderr, "Client and server were inconsistent.\n");
2109 return nullptr;
2110 }
2111
2112 if (!SSL_session_reused(client.get())) {
2113 fprintf(stderr, "Session was not reused.\n");
2114 return nullptr;
2115 }
2116
2117 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2118 SSL_read(client.get(), nullptr, 0);
2119
2120 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2121
2122 if (!g_last_session) {
2123 fprintf(stderr, "Client did not receive a renewed session.\n");
2124 return nullptr;
2125 }
2126 return std::move(g_last_session);
2127}
2128
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002129static void ExpectTicketKeyChanged(SSL_CTX *ctx, uint8_t *inout_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002130 bool changed) {
2131 uint8_t new_key[kTicketKeyLen];
David Benjaminc11ea9422017-08-29 16:33:21 -04002132 // May return 0, 1 or 48.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002133 ASSERT_EQ(SSL_CTX_get_tlsext_ticket_keys(ctx, new_key, kTicketKeyLen), 1);
2134 if (changed) {
2135 ASSERT_NE(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
2136 } else {
2137 ASSERT_EQ(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002138 }
2139 OPENSSL_memcpy(inout_key, new_key, kTicketKeyLen);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002140}
2141
David Benjamina933c382016-10-28 00:10:03 -04002142static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
2143 static const uint8_t kContext[] = {3};
2144
2145 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
2146 return SSL_TLSEXT_ERR_ALERT_FATAL;
2147 }
2148
2149 return SSL_TLSEXT_ERR_OK;
2150}
2151
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002152TEST_P(SSLVersionTest, SessionIDContext) {
David Benjamina20e5352016-08-02 19:09:41 -04002153 static const uint8_t kContext1[] = {1};
2154 static const uint8_t kContext2[] = {2};
2155
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002156 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2157 sizeof(kContext1)));
David Benjamina20e5352016-08-02 19:09:41 -04002158
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002159 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2160 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002161
David Benjamin0fef3052016-11-18 15:11:10 +09002162 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002163 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2164 ASSERT_TRUE(session);
David Benjamina20e5352016-08-02 19:09:41 -04002165
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002166 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2167 session.get(),
2168 true /* expect session reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002169
David Benjamin0fef3052016-11-18 15:11:10 +09002170 // Change the session ID context.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002171 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext2,
2172 sizeof(kContext2)));
David Benjamina20e5352016-08-02 19:09:41 -04002173
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002174 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2175 session.get(),
2176 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002177
David Benjamin0fef3052016-11-18 15:11:10 +09002178 // Change the session ID context back and install an SNI callback to switch
2179 // it.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002180 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2181 sizeof(kContext1)));
David Benjamina933c382016-10-28 00:10:03 -04002182
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002183 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09002184 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04002185
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002186 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2187 session.get(),
2188 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002189
David Benjamin0fef3052016-11-18 15:11:10 +09002190 // Switch the session ID context with the early callback instead.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002191 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), nullptr);
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002192 SSL_CTX_set_select_certificate_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002193 server_ctx_.get(),
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002194 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
2195 static const uint8_t kContext[] = {3};
2196
2197 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
2198 sizeof(kContext))) {
2199 return ssl_select_cert_error;
2200 }
2201
2202 return ssl_select_cert_success;
2203 });
David Benjamina933c382016-10-28 00:10:03 -04002204
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002205 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2206 session.get(),
2207 false /* expect session not reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002208}
2209
David Benjamin721e8b72016-08-03 13:13:17 -04002210static timeval g_current_time;
2211
2212static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2213 *out_clock = g_current_time;
2214}
2215
David Benjamin17b30832017-01-28 14:00:32 -05002216static void FrozenTimeCallback(const SSL *ssl, timeval *out_clock) {
2217 out_clock->tv_sec = 1000;
2218 out_clock->tv_usec = 0;
2219}
2220
David Benjamin3c51d9b2016-11-01 17:50:42 -04002221static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
2222 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
2223 int encrypt) {
2224 static const uint8_t kZeros[16] = {0};
2225
2226 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -05002227 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamin3c51d9b2016-11-01 17:50:42 -04002228 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -05002229 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002230 return 0;
2231 }
2232
2233 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
2234 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
2235 return -1;
2236 }
2237
2238 // Returning two from the callback in decrypt mode renews the
2239 // session in TLS 1.2 and below.
2240 return encrypt ? 1 : 2;
2241}
2242
David Benjamin123db572016-11-03 16:59:25 -04002243static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjaminaaef8332018-06-29 16:45:49 -04002244 const uint8_t *ticket;
2245 size_t ticket_len;
2246 SSL_SESSION_get0_ticket(session, &ticket, &ticket_len);
2247 if (ticket_len < 16 + 16 + SHA256_DIGEST_LENGTH) {
David Benjamin123db572016-11-03 16:59:25 -04002248 return false;
2249 }
2250
David Benjaminaaef8332018-06-29 16:45:49 -04002251 const uint8_t *ciphertext = ticket + 16 + 16;
2252 size_t len = ticket_len - 16 - 16 - SHA256_DIGEST_LENGTH;
David Benjamin123db572016-11-03 16:59:25 -04002253 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
2254
David Benjamin9b63f292016-11-15 00:44:05 -05002255#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
2256 // Fuzzer-mode tickets are unencrypted.
David Benjamin17cf2cb2016-12-13 01:07:13 -05002257 OPENSSL_memcpy(plaintext.get(), ciphertext, len);
David Benjamin9b63f292016-11-15 00:44:05 -05002258#else
2259 static const uint8_t kZeros[16] = {0};
David Benjaminaaef8332018-06-29 16:45:49 -04002260 const uint8_t *iv = ticket + 16;
David Benjamin123db572016-11-03 16:59:25 -04002261 bssl::ScopedEVP_CIPHER_CTX ctx;
2262 int len1, len2;
2263 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
2264 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
2265 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
2266 return false;
2267 }
2268
2269 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05002270#endif
David Benjamin123db572016-11-03 16:59:25 -04002271
Adam Langley46db7af2017-02-01 15:49:37 -08002272 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
2273 if (!ssl_ctx) {
2274 return false;
2275 }
David Benjamin123db572016-11-03 16:59:25 -04002276 bssl::UniquePtr<SSL_SESSION> server_session(
Adam Langley46db7af2017-02-01 15:49:37 -08002277 SSL_SESSION_from_bytes(plaintext.get(), len, ssl_ctx.get()));
David Benjamin123db572016-11-03 16:59:25 -04002278 if (!server_session) {
2279 return false;
2280 }
2281
David Benjaminaaef8332018-06-29 16:45:49 -04002282 *out = SSL_SESSION_get_time(server_session.get());
David Benjamin123db572016-11-03 16:59:25 -04002283 return true;
2284}
2285
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002286TEST_P(SSLVersionTest, SessionTimeout) {
2287 for (bool server_test : {false, true}) {
2288 SCOPED_TRACE(server_test);
David Benjamin721e8b72016-08-03 13:13:17 -04002289
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002290 ResetContexts();
2291 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2292 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
2293
David Benjamin17b30832017-01-28 14:00:32 -05002294 static const time_t kStartTime = 1000;
David Benjamin0fef3052016-11-18 15:11:10 +09002295 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002296
David Benjamin17b30832017-01-28 14:00:32 -05002297 // We are willing to use a longer lifetime for TLS 1.3 sessions as
2298 // resumptions still perform ECDHE.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002299 const time_t timeout = version() == TLS1_3_VERSION
David Benjamin17b30832017-01-28 14:00:32 -05002300 ? SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT
2301 : SSL_DEFAULT_SESSION_TIMEOUT;
2302
David Benjamin17b30832017-01-28 14:00:32 -05002303 // Both client and server must enforce session timeouts. We configure the
2304 // other side with a frozen clock so it never expires tickets.
David Benjamin0fef3052016-11-18 15:11:10 +09002305 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002306 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2307 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002308 } else {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002309 SSL_CTX_set_current_time_cb(client_ctx_.get(), CurrentTimeCallback);
2310 SSL_CTX_set_current_time_cb(server_ctx_.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002311 }
2312
2313 // Configure a ticket callback which renews tickets.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002314 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002315
2316 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002317 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2318 ASSERT_TRUE(session);
David Benjamin0fef3052016-11-18 15:11:10 +09002319
2320 // Advance the clock just behind the timeout.
David Benjamin17b30832017-01-28 14:00:32 -05002321 g_current_time.tv_sec += timeout - 1;
David Benjamin0fef3052016-11-18 15:11:10 +09002322
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002323 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2324 session.get(),
2325 true /* expect session reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002326
2327 // Advance the clock one more second.
2328 g_current_time.tv_sec++;
2329
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002330 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2331 session.get(),
2332 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002333
2334 // Rewind the clock to before the session was minted.
2335 g_current_time.tv_sec = kStartTime - 1;
2336
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002337 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2338 session.get(),
2339 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002340
David Benjamin0fef3052016-11-18 15:11:10 +09002341 // Renew the session 10 seconds before expiration.
David Benjamin17b30832017-01-28 14:00:32 -05002342 time_t new_start_time = kStartTime + timeout - 10;
2343 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002344 bssl::UniquePtr<SSL_SESSION> new_session = ExpectSessionRenewed(
2345 client_ctx_.get(), server_ctx_.get(), session.get());
2346 ASSERT_TRUE(new_session);
David Benjamin0fef3052016-11-18 15:11:10 +09002347
2348 // This new session is not the same object as before.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002349 EXPECT_NE(session.get(), new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002350
2351 // Check the sessions have timestamps measured from issuance.
2352 long session_time = 0;
2353 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002354 ASSERT_TRUE(GetServerTicketTime(&session_time, new_session.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09002355 } else {
David Benjaminaaef8332018-06-29 16:45:49 -04002356 session_time = SSL_SESSION_get_time(new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002357 }
David Benjamin721e8b72016-08-03 13:13:17 -04002358
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002359 ASSERT_EQ(session_time, g_current_time.tv_sec);
David Benjamin721e8b72016-08-03 13:13:17 -04002360
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002361 if (version() == TLS1_3_VERSION) {
David Benjamin17b30832017-01-28 14:00:32 -05002362 // Renewal incorporates fresh key material in TLS 1.3, so we extend the
2363 // lifetime TLS 1.3.
2364 g_current_time.tv_sec = new_start_time + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002365 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2366 new_session.get(),
2367 true /* expect session reused */));
David Benjamin721e8b72016-08-03 13:13:17 -04002368
David Benjamin17b30832017-01-28 14:00:32 -05002369 // The new session expires after the new timeout.
2370 g_current_time.tv_sec = new_start_time + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002371 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2372 new_session.get(),
2373 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002374
2375 // Renew the session until it begins just past the auth timeout.
2376 time_t auth_end_time = kStartTime + SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
2377 while (new_start_time < auth_end_time - 1000) {
2378 // Get as close as possible to target start time.
2379 new_start_time =
2380 std::min(auth_end_time - 1000, new_start_time + timeout - 1);
2381 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002382 new_session = ExpectSessionRenewed(client_ctx_.get(), server_ctx_.get(),
David Benjamin17b30832017-01-28 14:00:32 -05002383 new_session.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002384 ASSERT_TRUE(new_session);
David Benjamin17b30832017-01-28 14:00:32 -05002385 }
2386
2387 // Now the session's lifetime is bound by the auth timeout.
2388 g_current_time.tv_sec = auth_end_time - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002389 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2390 new_session.get(),
2391 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002392
2393 g_current_time.tv_sec = auth_end_time + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002394 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2395 new_session.get(),
2396 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002397 } else {
2398 // The new session is usable just before the old expiration.
2399 g_current_time.tv_sec = kStartTime + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002400 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2401 new_session.get(),
2402 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002403
2404 // Renewal does not extend the lifetime, so it is not usable beyond the
2405 // old expiration.
2406 g_current_time.tv_sec = kStartTime + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002407 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2408 new_session.get(),
2409 false /* expect session not reused */));
David Benjamin1b22f852016-10-27 16:36:32 -04002410 }
David Benjamin721e8b72016-08-03 13:13:17 -04002411 }
David Benjamin721e8b72016-08-03 13:13:17 -04002412}
2413
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002414TEST_P(SSLVersionTest, DefaultTicketKeyInitialization) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002415 static const uint8_t kZeroKey[kTicketKeyLen] = {};
2416 uint8_t ticket_key[kTicketKeyLen];
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002417 ASSERT_EQ(1, SSL_CTX_get_tlsext_ticket_keys(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002418 kTicketKeyLen));
2419 ASSERT_NE(0, OPENSSL_memcmp(ticket_key, kZeroKey, kTicketKeyLen));
2420}
2421
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002422TEST_P(SSLVersionTest, DefaultTicketKeyRotation) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002423 static const time_t kStartTime = 1001;
2424 g_current_time.tv_sec = kStartTime;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002425
David Benjaminc11ea9422017-08-29 16:33:21 -04002426 // We use session reuse as a proxy for ticket decryption success, hence
2427 // disable session timeouts.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002428 SSL_CTX_set_timeout(server_ctx_.get(), std::numeric_limits<uint32_t>::max());
2429 SSL_CTX_set_session_psk_dhe_timeout(server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002430 std::numeric_limits<uint32_t>::max());
2431
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002432 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2433 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002434
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002435 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2436 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_OFF);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002437
David Benjamin1f0d54b2018-08-09 16:19:13 -05002438 // Initialize ticket_key with the current key and check that it was
2439 // initialized to something, not all zeros.
2440 uint8_t ticket_key[kTicketKeyLen] = {0};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002441 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2442 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002443
David Benjaminc11ea9422017-08-29 16:33:21 -04002444 // Verify ticket resumption actually works.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002445 bssl::UniquePtr<SSL> client, server;
2446 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002447 CreateClientSession(client_ctx_.get(), server_ctx_.get());
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002448 ASSERT_TRUE(session);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002449 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002450 session.get(), true /* reused */));
2451
David Benjaminc11ea9422017-08-29 16:33:21 -04002452 // Advance time to just before key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002453 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002454 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002455 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002456 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002457 false /* NOT changed */));
2458
David Benjaminc11ea9422017-08-29 16:33:21 -04002459 // Force key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002460 g_current_time.tv_sec += 1;
2461 bssl::UniquePtr<SSL_SESSION> new_session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002462 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2463 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2464 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002465
David Benjaminc11ea9422017-08-29 16:33:21 -04002466 // Resumption with both old and new ticket should work.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002467 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002468 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002469 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002470 new_session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002471 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002472 false /* NOT changed */));
2473
David Benjaminc11ea9422017-08-29 16:33:21 -04002474 // Force key rotation again. Resumption with the old ticket now fails.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002475 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002476 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002477 session.get(), false /* NOT reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002478 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2479 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002480
David Benjaminc11ea9422017-08-29 16:33:21 -04002481 // But resumption with the newer session still works.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002482 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002483 new_session.get(), true /* reused */));
2484}
2485
David Benjamin0fc37ef2016-08-17 15:29:46 -04002486static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002487 SSL_CTX *ctx = reinterpret_cast<SSL_CTX *>(arg);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002488 SSL_set_SSL_CTX(ssl, ctx);
2489 return SSL_TLSEXT_ERR_OK;
2490}
2491
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002492TEST_P(SSLVersionTest, SNICallback) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002493 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002494 ASSERT_TRUE(cert2);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002495 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002496 ASSERT_TRUE(key2);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002497
David Benjamin0fef3052016-11-18 15:11:10 +09002498 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
2499 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002500
David Benjamin83a32122017-02-14 18:34:54 -05002501 static const uint8_t kSCTList[] = {0, 6, 0, 4, 5, 6, 7, 8};
2502 static const uint8_t kOCSPResponse[] = {1, 2, 3, 4};
2503
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002504 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
2505 ASSERT_TRUE(server_ctx2);
2506 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()));
2507 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()));
2508 ASSERT_TRUE(SSL_CTX_set_signed_cert_timestamp_list(
2509 server_ctx2.get(), kSCTList, sizeof(kSCTList)));
2510 ASSERT_TRUE(SSL_CTX_set_ocsp_response(server_ctx2.get(), kOCSPResponse,
2511 sizeof(kOCSPResponse)));
2512 // Historically signing preferences would be lost in some cases with the
2513 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2514 // this doesn't happen when |version| is TLS 1.2, configure the private
2515 // key to only sign SHA-256.
2516 ASSERT_TRUE(SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
2517 &kECDSAWithSHA256, 1));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002518
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002519 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), SwitchContext);
2520 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002521
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002522 SSL_CTX_enable_signed_cert_timestamps(client_ctx_.get());
2523 SSL_CTX_enable_ocsp_stapling(client_ctx_.get());
David Benjamin83a32122017-02-14 18:34:54 -05002524
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002525 ASSERT_TRUE(Connect());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002526
David Benjamin0fef3052016-11-18 15:11:10 +09002527 // The client should have received |cert2|.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002528 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client_.get()));
2529 ASSERT_TRUE(peer);
2530 EXPECT_EQ(X509_cmp(peer.get(), cert2.get()), 0);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002531
David Benjamin83a32122017-02-14 18:34:54 -05002532 // The client should have received |server_ctx2|'s SCT list.
2533 const uint8_t *data;
2534 size_t len;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002535 SSL_get0_signed_cert_timestamp_list(client_.get(), &data, &len);
2536 EXPECT_EQ(Bytes(kSCTList), Bytes(data, len));
David Benjamin83a32122017-02-14 18:34:54 -05002537
2538 // The client should have received |server_ctx2|'s OCSP response.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002539 SSL_get0_ocsp_response(client_.get(), &data, &len);
2540 EXPECT_EQ(Bytes(kOCSPResponse), Bytes(data, len));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002541}
2542
David Benjaminf0d8e222017-02-04 10:58:26 -05002543// Test that the early callback can swap the maximum version.
2544TEST(SSLTest, EarlyCallbackVersionSwitch) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002545 bssl::UniquePtr<X509> cert = GetTestCertificate();
2546 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2547 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2548 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002549 ASSERT_TRUE(cert);
2550 ASSERT_TRUE(key);
2551 ASSERT_TRUE(server_ctx);
2552 ASSERT_TRUE(client_ctx);
2553 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
2554 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
2555 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
2556 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
David Benjamin99620572016-08-30 00:35:36 -04002557
David Benjaminf0d8e222017-02-04 10:58:26 -05002558 SSL_CTX_set_select_certificate_cb(
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002559 server_ctx.get(),
2560 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
David Benjaminf0d8e222017-02-04 10:58:26 -05002561 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002562 return ssl_select_cert_error;
David Benjaminf0d8e222017-02-04 10:58:26 -05002563 }
2564
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002565 return ssl_select_cert_success;
David Benjaminf0d8e222017-02-04 10:58:26 -05002566 });
David Benjamin99620572016-08-30 00:35:36 -04002567
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002568 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05002569 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04002570 server_ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002571 EXPECT_EQ(TLS1_2_VERSION, SSL_version(client.get()));
David Benjamin99620572016-08-30 00:35:36 -04002572}
2573
David Benjaminf0d8e222017-02-04 10:58:26 -05002574TEST(SSLTest, SetVersion) {
David Benjamin2dc02042016-09-19 19:57:37 -04002575 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002576 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002577
David Benjaminf0d8e222017-02-04 10:58:26 -05002578 // Set valid TLS versions.
2579 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2580 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
2581 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2582 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002583
David Benjaminf0d8e222017-02-04 10:58:26 -05002584 // Invalid TLS versions are rejected.
2585 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2586 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x0200));
2587 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2588 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2589 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x0200));
2590 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002591
David Benjaminf0d8e222017-02-04 10:58:26 -05002592 // Zero is the default version.
2593 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002594 EXPECT_EQ(TLS1_2_VERSION, ctx->conf_max_version);
David Benjaminf0d8e222017-02-04 10:58:26 -05002595 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002596 EXPECT_EQ(TLS1_VERSION, ctx->conf_min_version);
David Benjamin3cfeb952017-03-01 16:48:38 -05002597
David Benjamin9bb15f52018-06-26 00:07:40 -04002598 // TLS 1.3 is available, but not by default.
David Benjamin3cfeb952017-03-01 16:48:38 -05002599 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002600 EXPECT_EQ(TLS1_3_VERSION, ctx->conf_max_version);
David Benjamine34bcc92016-09-21 16:53:09 -04002601
David Benjamin9bb15f52018-06-26 00:07:40 -04002602 // SSL 3.0 is not available.
2603 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION));
2604
David Benjamin353577c2017-06-29 15:54:58 -04002605 // TLS1_3_DRAFT_VERSION is not an API-level version.
Steven Valdez64cc1212017-12-04 11:15:37 -05002606 EXPECT_FALSE(
Steven Valdez7e5dd252018-01-22 15:20:31 -05002607 SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_DRAFT23_VERSION));
David Benjamin353577c2017-06-29 15:54:58 -04002608 ERR_clear_error();
2609
David Benjamin2dc02042016-09-19 19:57:37 -04002610 ctx.reset(SSL_CTX_new(DTLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002611 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002612
David Benjaminf0d8e222017-02-04 10:58:26 -05002613 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2614 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION));
2615 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2616 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002617
David Benjaminf0d8e222017-02-04 10:58:26 -05002618 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2619 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2620 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2621 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2622 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2623 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2624 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2625 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002626
David Benjaminf0d8e222017-02-04 10:58:26 -05002627 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002628 EXPECT_EQ(TLS1_2_VERSION, ctx->conf_max_version);
David Benjaminf0d8e222017-02-04 10:58:26 -05002629 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002630 EXPECT_EQ(TLS1_1_VERSION, ctx->conf_min_version);
David Benjamin2dc02042016-09-19 19:57:37 -04002631}
2632
David Benjamin458334a2016-12-15 13:53:25 -05002633static const char *GetVersionName(uint16_t version) {
2634 switch (version) {
David Benjamin458334a2016-12-15 13:53:25 -05002635 case TLS1_VERSION:
2636 return "TLSv1";
2637 case TLS1_1_VERSION:
2638 return "TLSv1.1";
2639 case TLS1_2_VERSION:
2640 return "TLSv1.2";
2641 case TLS1_3_VERSION:
2642 return "TLSv1.3";
2643 case DTLS1_VERSION:
2644 return "DTLSv1";
2645 case DTLS1_2_VERSION:
2646 return "DTLSv1.2";
2647 default:
2648 return "???";
2649 }
2650}
2651
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002652TEST_P(SSLVersionTest, Version) {
2653 ASSERT_TRUE(Connect());
David Benjamincb18ac22016-09-27 14:09:15 -04002654
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002655 EXPECT_EQ(SSL_version(client_.get()), version());
2656 EXPECT_EQ(SSL_version(server_.get()), version());
David Benjamincb18ac22016-09-27 14:09:15 -04002657
David Benjamin458334a2016-12-15 13:53:25 -05002658 // Test the version name is reported as expected.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002659 const char *version_name = GetVersionName(version());
2660 EXPECT_EQ(strcmp(version_name, SSL_get_version(client_.get())), 0);
2661 EXPECT_EQ(strcmp(version_name, SSL_get_version(server_.get())), 0);
David Benjamin458334a2016-12-15 13:53:25 -05002662
2663 // Test SSL_SESSION reports the same name.
2664 const char *client_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002665 SSL_SESSION_get_version(SSL_get_session(client_.get()));
David Benjamin458334a2016-12-15 13:53:25 -05002666 const char *server_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002667 SSL_SESSION_get_version(SSL_get_session(server_.get()));
2668 EXPECT_EQ(strcmp(version_name, client_name), 0);
2669 EXPECT_EQ(strcmp(version_name, server_name), 0);
David Benjamincb18ac22016-09-27 14:09:15 -04002670}
2671
David Benjamin9ef31f02016-10-31 18:01:13 -04002672// Tests that that |SSL_get_pending_cipher| is available during the ALPN
2673// selection callback.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002674TEST_P(SSLVersionTest, ALPNCipherAvailable) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002675 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2676
David Benjamin9ef31f02016-10-31 18:01:13 -04002677 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002678 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
2679 sizeof(kALPNProtos)),
2680 0);
David Benjamin0fef3052016-11-18 15:11:10 +09002681
2682 // The ALPN callback does not fail the handshake on error, so have the
2683 // callback write a boolean.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002684 std::pair<uint16_t, bool> callback_state(version(), false);
David Benjamin0fef3052016-11-18 15:11:10 +09002685 SSL_CTX_set_alpn_select_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002686 server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09002687 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
2688 unsigned in_len, void *arg) -> int {
2689 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
2690 if (SSL_get_pending_cipher(ssl) != nullptr &&
2691 SSL_version(ssl) == state->first) {
2692 state->second = true;
2693 }
2694 return SSL_TLSEXT_ERR_NOACK;
2695 },
2696 &callback_state);
2697
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002698 ASSERT_TRUE(Connect());
David Benjamin0fef3052016-11-18 15:11:10 +09002699
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002700 ASSERT_TRUE(callback_state.second);
David Benjamin0fef3052016-11-18 15:11:10 +09002701}
2702
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002703TEST_P(SSLVersionTest, SSLClearSessionResumption) {
David Benjaminb79cc842016-12-07 15:57:14 -05002704 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
2705 // API pattern.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002706 if (version() == TLS1_3_VERSION) {
2707 return;
David Benjaminb79cc842016-12-07 15:57:14 -05002708 }
2709
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07002710 shed_handshake_config_ = false;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002711 ASSERT_TRUE(Connect());
David Benjaminb79cc842016-12-07 15:57:14 -05002712
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002713 EXPECT_FALSE(SSL_session_reused(client_.get()));
2714 EXPECT_FALSE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002715
2716 // Reset everything.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002717 ASSERT_TRUE(SSL_clear(client_.get()));
2718 ASSERT_TRUE(SSL_clear(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002719
2720 // Attempt to connect a second time.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002721 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002722
2723 // |SSL_clear| should implicitly offer the previous session to the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002724 EXPECT_TRUE(SSL_session_reused(client_.get()));
2725 EXPECT_TRUE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002726}
2727
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07002728TEST_P(SSLVersionTest, SSLClearFailsWithShedding) {
2729 shed_handshake_config_ = false;
2730 ASSERT_TRUE(Connect());
2731 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
2732
2733 // Reset everything.
2734 ASSERT_TRUE(SSL_clear(client_.get()));
2735 ASSERT_TRUE(SSL_clear(server_.get()));
2736
2737 // Now enable shedding, and connect a second time.
2738 shed_handshake_config_ = true;
2739 ASSERT_TRUE(Connect());
2740 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
2741
2742 // |SSL_clear| should now fail.
2743 ASSERT_FALSE(SSL_clear(client_.get()));
2744 ASSERT_FALSE(SSL_clear(server_.get()));
2745}
2746
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002747static bool ChainsEqual(STACK_OF(X509) * chain,
2748 const std::vector<X509 *> &expected) {
David Benjamin1444c3a2016-12-20 17:23:11 -05002749 if (sk_X509_num(chain) != expected.size()) {
2750 return false;
2751 }
2752
2753 for (size_t i = 0; i < expected.size(); i++) {
2754 if (X509_cmp(sk_X509_value(chain, i), expected[i]) != 0) {
2755 return false;
2756 }
2757 }
2758
2759 return true;
2760}
2761
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002762TEST_P(SSLVersionTest, AutoChain) {
2763 cert_ = GetChainTestCertificate();
2764 ASSERT_TRUE(cert_);
2765 key_ = GetChainTestKey();
2766 ASSERT_TRUE(key_);
David Benjamin1444c3a2016-12-20 17:23:11 -05002767 bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002768 ASSERT_TRUE(intermediate);
2769
2770 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2771 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin1444c3a2016-12-20 17:23:11 -05002772
2773 // Configure both client and server to accept any certificate. Add
2774 // |intermediate| to the cert store.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002775 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx_.get()),
2776 intermediate.get()));
2777 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(server_ctx_.get()),
2778 intermediate.get()));
2779 SSL_CTX_set_verify(client_ctx_.get(),
2780 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2781 nullptr);
2782 SSL_CTX_set_verify(server_ctx_.get(),
2783 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2784 nullptr);
2785 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
2786 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjamin1444c3a2016-12-20 17:23:11 -05002787
2788 // By default, the client and server should each only send the leaf.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002789 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002790
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002791 EXPECT_TRUE(
2792 ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()), {cert_.get()}));
2793 EXPECT_TRUE(
2794 ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()), {cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002795
2796 // If auto-chaining is enabled, then the intermediate is sent.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002797 SSL_CTX_clear_mode(client_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
2798 SSL_CTX_clear_mode(server_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
2799 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002800
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002801 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
2802 {cert_.get(), intermediate.get()}));
2803 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
2804 {cert_.get(), intermediate.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002805
2806 // Auto-chaining does not override explicitly-configured intermediates.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002807 ASSERT_TRUE(SSL_CTX_add1_chain_cert(client_ctx_.get(), cert_.get()));
2808 ASSERT_TRUE(SSL_CTX_add1_chain_cert(server_ctx_.get(), cert_.get()));
2809 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002810
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002811 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
2812 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002813
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002814 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
2815 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002816}
2817
David Benjamin48063c22017-01-01 23:56:36 -05002818static bool ExpectBadWriteRetry() {
2819 int err = ERR_get_error();
2820 if (ERR_GET_LIB(err) != ERR_LIB_SSL ||
2821 ERR_GET_REASON(err) != SSL_R_BAD_WRITE_RETRY) {
2822 char buf[ERR_ERROR_STRING_BUF_LEN];
2823 ERR_error_string_n(err, buf, sizeof(buf));
2824 fprintf(stderr, "Wanted SSL_R_BAD_WRITE_RETRY, got: %s.\n", buf);
2825 return false;
2826 }
2827
2828 if (ERR_peek_error() != 0) {
2829 fprintf(stderr, "Unexpected error following SSL_R_BAD_WRITE_RETRY.\n");
2830 return false;
2831 }
2832
2833 return true;
2834}
2835
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002836TEST_P(SSLVersionTest, SSLWriteRetry) {
2837 if (is_dtls()) {
2838 return;
David Benjamin48063c22017-01-01 23:56:36 -05002839 }
2840
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002841 for (bool enable_partial_write : {false, true}) {
2842 SCOPED_TRACE(enable_partial_write);
2843
David Benjamin48063c22017-01-01 23:56:36 -05002844 // Connect a client and server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002845 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2846
2847 ASSERT_TRUE(Connect());
David Benjamin48063c22017-01-01 23:56:36 -05002848
2849 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002850 SSL_set_mode(client_.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002851 }
2852
2853 // Write without reading until the buffer is full and we have an unfinished
2854 // write. Keep a count so we may reread it again later. "hello!" will be
2855 // written in two chunks, "hello" and "!".
2856 char data[] = "hello!";
2857 static const int kChunkLen = 5; // The length of "hello".
2858 unsigned count = 0;
2859 for (;;) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002860 int ret = SSL_write(client_.get(), data, kChunkLen);
David Benjamin48063c22017-01-01 23:56:36 -05002861 if (ret <= 0) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002862 ASSERT_EQ(SSL_get_error(client_.get(), ret), SSL_ERROR_WANT_WRITE);
2863 break;
David Benjamin48063c22017-01-01 23:56:36 -05002864 }
2865
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002866 ASSERT_EQ(ret, 5);
David Benjamin48063c22017-01-01 23:56:36 -05002867
2868 count++;
2869 }
2870
2871 // Retrying with the same parameters is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002872 ASSERT_EQ(
2873 SSL_get_error(client_.get(), SSL_write(client_.get(), data, kChunkLen)),
2874 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002875
2876 // Retrying with the same buffer but shorter length is not legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002877 ASSERT_EQ(SSL_get_error(client_.get(),
2878 SSL_write(client_.get(), data, kChunkLen - 1)),
2879 SSL_ERROR_SSL);
2880 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002881
2882 // Retrying with a different buffer pointer is not legal.
2883 char data2[] = "hello";
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002884 ASSERT_EQ(SSL_get_error(client_.get(),
2885 SSL_write(client_.get(), data2, kChunkLen)),
2886 SSL_ERROR_SSL);
2887 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002888
2889 // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002890 SSL_set_mode(client_.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
2891 ASSERT_EQ(SSL_get_error(client_.get(),
2892 SSL_write(client_.get(), data2, kChunkLen)),
2893 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002894
2895 // |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| does not disable length checks.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002896 ASSERT_EQ(SSL_get_error(client_.get(),
2897 SSL_write(client_.get(), data2, kChunkLen - 1)),
2898 SSL_ERROR_SSL);
2899 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002900
2901 // Retrying with a larger buffer is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002902 ASSERT_EQ(SSL_get_error(client_.get(),
2903 SSL_write(client_.get(), data, kChunkLen + 1)),
2904 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002905
2906 // Drain the buffer.
2907 char buf[20];
2908 for (unsigned i = 0; i < count; i++) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002909 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
2910 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
David Benjamin48063c22017-01-01 23:56:36 -05002911 }
2912
2913 // Now that there is space, a retry with a larger buffer should flush the
2914 // pending record, skip over that many bytes of input (on assumption they
2915 // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE
2916 // is set, this will complete in two steps.
2917 char data3[] = "_____!";
2918 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002919 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen);
2920 ASSERT_EQ(SSL_write(client_.get(), data3 + kChunkLen, 1), 1);
2921 } else {
2922 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen + 1);
David Benjamin48063c22017-01-01 23:56:36 -05002923 }
2924
2925 // Check the last write was correct. The data will be spread over two
2926 // records, so SSL_read returns twice.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002927 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
2928 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
2929 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), 1);
2930 ASSERT_EQ(buf[0], '!');
David Benjamin48063c22017-01-01 23:56:36 -05002931 }
David Benjamin48063c22017-01-01 23:56:36 -05002932}
2933
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002934TEST_P(SSLVersionTest, RecordCallback) {
2935 for (bool test_server : {true, false}) {
2936 SCOPED_TRACE(test_server);
2937 ResetContexts();
David Benjamin5df5be12017-06-22 19:43:11 -04002938
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002939 bool read_seen = false;
2940 bool write_seen = false;
2941 auto cb = [&](int is_write, int cb_version, int cb_type, const void *buf,
2942 size_t len, SSL *ssl) {
2943 if (cb_type != SSL3_RT_HEADER) {
2944 return;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002945 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002946
2947 // The callback does not report a version for records.
2948 EXPECT_EQ(0, cb_version);
2949
2950 if (is_write) {
2951 write_seen = true;
2952 } else {
2953 read_seen = true;
2954 }
2955
2956 // Sanity-check that the record header is plausible.
2957 CBS cbs;
2958 CBS_init(&cbs, reinterpret_cast<const uint8_t *>(buf), len);
2959 uint8_t type;
2960 uint16_t record_version, length;
2961 ASSERT_TRUE(CBS_get_u8(&cbs, &type));
2962 ASSERT_TRUE(CBS_get_u16(&cbs, &record_version));
Steven Valdez64cc1212017-12-04 11:15:37 -05002963 EXPECT_EQ(record_version & 0xff00, version() & 0xff00);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002964 if (is_dtls()) {
2965 uint16_t epoch;
2966 ASSERT_TRUE(CBS_get_u16(&cbs, &epoch));
2967 EXPECT_TRUE(epoch == 0 || epoch == 1) << "Invalid epoch: " << epoch;
2968 ASSERT_TRUE(CBS_skip(&cbs, 6));
2969 }
2970 ASSERT_TRUE(CBS_get_u16(&cbs, &length));
2971 EXPECT_EQ(0u, CBS_len(&cbs));
2972 };
2973 using CallbackType = decltype(cb);
2974 SSL_CTX *ctx = test_server ? server_ctx_.get() : client_ctx_.get();
2975 SSL_CTX_set_msg_callback(
2976 ctx, [](int is_write, int cb_version, int cb_type, const void *buf,
2977 size_t len, SSL *ssl, void *arg) {
2978 CallbackType *cb_ptr = reinterpret_cast<CallbackType *>(arg);
2979 (*cb_ptr)(is_write, cb_version, cb_type, buf, len, ssl);
2980 });
2981 SSL_CTX_set_msg_callback_arg(ctx, &cb);
2982
2983 ASSERT_TRUE(Connect());
2984
2985 EXPECT_TRUE(read_seen);
2986 EXPECT_TRUE(write_seen);
David Benjamin0fef3052016-11-18 15:11:10 +09002987 }
David Benjamin9ef31f02016-10-31 18:01:13 -04002988}
2989
David Benjamina8614602017-09-06 15:40:19 -04002990TEST_P(SSLVersionTest, GetServerName) {
David Benjamina8614602017-09-06 15:40:19 -04002991 ClientConfig config;
2992 config.servername = "host1";
2993
2994 SSL_CTX_set_tlsext_servername_callback(
2995 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
2996 // During the handshake, |SSL_get_servername| must match |config|.
2997 ClientConfig *config_p = reinterpret_cast<ClientConfig *>(arg);
2998 EXPECT_STREQ(config_p->servername.c_str(),
2999 SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name));
3000 return SSL_TLSEXT_ERR_OK;
3001 });
3002 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), &config);
3003
3004 ASSERT_TRUE(Connect(config));
3005 // After the handshake, it must also be available.
3006 EXPECT_STREQ(config.servername.c_str(),
3007 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3008
3009 // Establish a session under host1.
3010 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3011 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3012 bssl::UniquePtr<SSL_SESSION> session =
3013 CreateClientSession(client_ctx_.get(), server_ctx_.get(), config);
3014
3015 // If the client resumes a session with a different name, |SSL_get_servername|
3016 // must return the new name.
3017 ASSERT_TRUE(session);
3018 config.session = session.get();
3019 config.servername = "host2";
3020 ASSERT_TRUE(Connect(config));
3021 EXPECT_STREQ(config.servername.c_str(),
3022 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3023}
3024
David Benjamin3d8f0802017-09-06 16:12:52 -04003025// Test that session cache mode bits are honored in the client session callback.
3026TEST_P(SSLVersionTest, ClientSessionCacheMode) {
3027 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_OFF);
3028 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3029
3030 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_CLIENT);
3031 EXPECT_TRUE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3032
3033 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_SERVER);
3034 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3035}
3036
Adam Langleye1e78132017-01-31 15:24:31 -08003037TEST(SSLTest, AddChainCertHack) {
3038 // Ensure that we don't accidently break the hack that we have in place to
3039 // keep curl and serf happy when they use an |X509| even after transfering
3040 // ownership.
3041
3042 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3043 ASSERT_TRUE(ctx);
3044 X509 *cert = GetTestCertificate().release();
3045 ASSERT_TRUE(cert);
3046 SSL_CTX_add0_chain_cert(ctx.get(), cert);
3047
3048 // This should not trigger a use-after-free.
3049 X509_cmp(cert, cert);
3050}
3051
David Benjaminb2ff2622017-02-03 17:06:18 -05003052TEST(SSLTest, GetCertificate) {
3053 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3054 ASSERT_TRUE(ctx);
3055 bssl::UniquePtr<X509> cert = GetTestCertificate();
3056 ASSERT_TRUE(cert);
3057 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
3058 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3059 ASSERT_TRUE(ssl);
3060
3061 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
3062 ASSERT_TRUE(cert2);
3063 X509 *cert3 = SSL_get_certificate(ssl.get());
3064 ASSERT_TRUE(cert3);
3065
3066 // The old and new certificates must be identical.
3067 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
3068 EXPECT_EQ(0, X509_cmp(cert.get(), cert3));
3069
3070 uint8_t *der = nullptr;
3071 long der_len = i2d_X509(cert.get(), &der);
3072 ASSERT_LT(0, der_len);
3073 bssl::UniquePtr<uint8_t> free_der(der);
3074
3075 uint8_t *der2 = nullptr;
3076 long der2_len = i2d_X509(cert2, &der2);
3077 ASSERT_LT(0, der2_len);
3078 bssl::UniquePtr<uint8_t> free_der2(der2);
3079
3080 uint8_t *der3 = nullptr;
3081 long der3_len = i2d_X509(cert3, &der3);
3082 ASSERT_LT(0, der3_len);
3083 bssl::UniquePtr<uint8_t> free_der3(der3);
3084
3085 // They must also encode identically.
David Benjamin7d7554b2017-02-04 11:48:59 -05003086 EXPECT_EQ(Bytes(der, der_len), Bytes(der2, der2_len));
3087 EXPECT_EQ(Bytes(der, der_len), Bytes(der3, der3_len));
David Benjaminb2ff2622017-02-03 17:06:18 -05003088}
3089
Adam Langleyd04ca952017-02-28 11:26:51 -08003090TEST(SSLTest, SetChainAndKeyMismatch) {
3091 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_with_buffers_method()));
3092 ASSERT_TRUE(ctx);
3093
3094 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3095 ASSERT_TRUE(key);
3096 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3097 ASSERT_TRUE(leaf);
3098 std::vector<CRYPTO_BUFFER*> chain = {
3099 leaf.get(),
3100 };
3101
3102 // Should fail because |GetTestKey| doesn't match the chain-test certificate.
3103 ASSERT_FALSE(SSL_CTX_set_chain_and_key(ctx.get(), &chain[0], chain.size(),
3104 key.get(), nullptr));
3105 ERR_clear_error();
3106}
3107
3108TEST(SSLTest, SetChainAndKey) {
3109 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3110 ASSERT_TRUE(client_ctx);
3111 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3112 ASSERT_TRUE(server_ctx);
3113
3114 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3115 ASSERT_TRUE(key);
3116 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3117 ASSERT_TRUE(leaf);
3118 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3119 GetChainTestIntermediateBuffer();
3120 ASSERT_TRUE(intermediate);
3121 std::vector<CRYPTO_BUFFER*> chain = {
3122 leaf.get(), intermediate.get(),
3123 };
3124 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3125 chain.size(), key.get(), nullptr));
3126
David Benjamin3a1dd462017-07-11 16:13:10 -04003127 SSL_CTX_set_custom_verify(
3128 client_ctx.get(), SSL_VERIFY_PEER,
3129 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3130 return ssl_verify_ok;
3131 });
Adam Langleyd04ca952017-02-28 11:26:51 -08003132
3133 bssl::UniquePtr<SSL> client, server;
3134 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003135 server_ctx.get()));
Adam Langleyd04ca952017-02-28 11:26:51 -08003136}
3137
Matthew Braithwaite5301c102018-01-23 12:08:55 -08003138TEST(SSLTest, BuffersFailWithoutCustomVerify) {
3139 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3140 ASSERT_TRUE(client_ctx);
3141 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3142 ASSERT_TRUE(server_ctx);
3143
3144 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3145 ASSERT_TRUE(key);
3146 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3147 ASSERT_TRUE(leaf);
3148 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
3149 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3150 chain.size(), key.get(), nullptr));
3151
3152 // Without SSL_CTX_set_custom_verify(), i.e. with everything in the default
3153 // configuration, certificate verification should fail.
3154 bssl::UniquePtr<SSL> client, server;
3155 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3156 server_ctx.get()));
3157
3158 // Whereas with a verifier, the connection should succeed.
3159 SSL_CTX_set_custom_verify(
3160 client_ctx.get(), SSL_VERIFY_PEER,
3161 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3162 return ssl_verify_ok;
3163 });
3164 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3165 server_ctx.get()));
3166}
3167
3168TEST(SSLTest, CustomVerify) {
3169 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3170 ASSERT_TRUE(client_ctx);
3171 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3172 ASSERT_TRUE(server_ctx);
3173
3174 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3175 ASSERT_TRUE(key);
3176 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3177 ASSERT_TRUE(leaf);
3178 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
3179 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3180 chain.size(), key.get(), nullptr));
3181
3182 SSL_CTX_set_custom_verify(
3183 client_ctx.get(), SSL_VERIFY_PEER,
3184 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3185 return ssl_verify_ok;
3186 });
3187
3188 bssl::UniquePtr<SSL> client, server;
3189 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3190 server_ctx.get()));
3191
3192 // With SSL_VERIFY_PEER, ssl_verify_invalid should result in a dropped
3193 // connection.
3194 SSL_CTX_set_custom_verify(
3195 client_ctx.get(), SSL_VERIFY_PEER,
3196 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3197 return ssl_verify_invalid;
3198 });
3199
3200 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3201 server_ctx.get()));
3202
3203 // But with SSL_VERIFY_NONE, ssl_verify_invalid should not cause a dropped
3204 // connection.
3205 SSL_CTX_set_custom_verify(
3206 client_ctx.get(), SSL_VERIFY_NONE,
3207 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3208 return ssl_verify_invalid;
3209 });
3210
3211 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3212 server_ctx.get()));
3213}
3214
David Benjamin71dfad42017-07-16 17:27:39 -04003215TEST(SSLTest, ClientCABuffers) {
3216 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3217 ASSERT_TRUE(client_ctx);
3218 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3219 ASSERT_TRUE(server_ctx);
3220
3221 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3222 ASSERT_TRUE(key);
3223 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3224 ASSERT_TRUE(leaf);
3225 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3226 GetChainTestIntermediateBuffer();
3227 ASSERT_TRUE(intermediate);
3228 std::vector<CRYPTO_BUFFER *> chain = {
3229 leaf.get(),
3230 intermediate.get(),
3231 };
3232 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3233 chain.size(), key.get(), nullptr));
3234
3235 bssl::UniquePtr<CRYPTO_BUFFER> ca_name(
3236 CRYPTO_BUFFER_new(kTestName, sizeof(kTestName), nullptr));
3237 ASSERT_TRUE(ca_name);
3238 bssl::UniquePtr<STACK_OF(CRYPTO_BUFFER)> ca_names(
3239 sk_CRYPTO_BUFFER_new_null());
3240 ASSERT_TRUE(ca_names);
David Benjamin2908dd12018-06-29 17:46:42 -04003241 ASSERT_TRUE(PushToStack(ca_names.get(), std::move(ca_name)));
David Benjamin71dfad42017-07-16 17:27:39 -04003242 SSL_CTX_set0_client_CAs(server_ctx.get(), ca_names.release());
3243
3244 // Configure client and server to accept all certificates.
3245 SSL_CTX_set_custom_verify(
3246 client_ctx.get(), SSL_VERIFY_PEER,
3247 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3248 return ssl_verify_ok;
3249 });
3250 SSL_CTX_set_custom_verify(
3251 server_ctx.get(), SSL_VERIFY_PEER,
3252 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3253 return ssl_verify_ok;
3254 });
3255
3256 bool cert_cb_called = false;
3257 SSL_CTX_set_cert_cb(
3258 client_ctx.get(),
3259 [](SSL *ssl, void *arg) -> int {
David Benjamin5f001d12018-05-08 16:46:48 -04003260 const STACK_OF(CRYPTO_BUFFER) *peer_names =
David Benjamin71dfad42017-07-16 17:27:39 -04003261 SSL_get0_server_requested_CAs(ssl);
3262 EXPECT_EQ(1u, sk_CRYPTO_BUFFER_num(peer_names));
3263 CRYPTO_BUFFER *peer_name = sk_CRYPTO_BUFFER_value(peer_names, 0);
3264 EXPECT_EQ(Bytes(kTestName), Bytes(CRYPTO_BUFFER_data(peer_name),
3265 CRYPTO_BUFFER_len(peer_name)));
3266 *reinterpret_cast<bool *>(arg) = true;
3267 return 1;
3268 },
3269 &cert_cb_called);
3270
3271 bssl::UniquePtr<SSL> client, server;
3272 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003273 server_ctx.get()));
David Benjamin71dfad42017-07-16 17:27:39 -04003274 EXPECT_TRUE(cert_cb_called);
3275}
3276
David Benjamin91222b82017-03-09 20:10:56 -05003277// Configuring the empty cipher list, though an error, should still modify the
3278// configuration.
3279TEST(SSLTest, EmptyCipherList) {
3280 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3281 ASSERT_TRUE(ctx);
3282
3283 // Initially, the cipher list is not empty.
3284 EXPECT_NE(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3285
3286 // Configuring the empty cipher list fails.
3287 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), ""));
3288 ERR_clear_error();
3289
3290 // But the cipher list is still updated to empty.
3291 EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3292}
3293
Adam Langley4c341d02017-03-08 19:33:21 -08003294// ssl_test_ticket_aead_failure_mode enumerates the possible ways in which the
3295// test |SSL_TICKET_AEAD_METHOD| can fail.
3296enum ssl_test_ticket_aead_failure_mode {
3297 ssl_test_ticket_aead_ok = 0,
3298 ssl_test_ticket_aead_seal_fail,
3299 ssl_test_ticket_aead_open_soft_fail,
3300 ssl_test_ticket_aead_open_hard_fail,
3301};
3302
3303struct ssl_test_ticket_aead_state {
3304 unsigned retry_count;
3305 ssl_test_ticket_aead_failure_mode failure_mode;
3306};
3307
3308static int ssl_test_ticket_aead_ex_index_dup(CRYPTO_EX_DATA *to,
3309 const CRYPTO_EX_DATA *from,
3310 void **from_d, int index,
3311 long argl, void *argp) {
3312 abort();
3313}
3314
3315static void ssl_test_ticket_aead_ex_index_free(void *parent, void *ptr,
3316 CRYPTO_EX_DATA *ad, int index,
3317 long argl, void *argp) {
3318 auto state = reinterpret_cast<ssl_test_ticket_aead_state*>(ptr);
3319 if (state == nullptr) {
3320 return;
3321 }
3322
3323 OPENSSL_free(state);
3324}
3325
3326static CRYPTO_once_t g_ssl_test_ticket_aead_ex_index_once = CRYPTO_ONCE_INIT;
3327static int g_ssl_test_ticket_aead_ex_index;
3328
3329static int ssl_test_ticket_aead_get_ex_index() {
3330 CRYPTO_once(&g_ssl_test_ticket_aead_ex_index_once, [] {
3331 g_ssl_test_ticket_aead_ex_index = SSL_get_ex_new_index(
3332 0, nullptr, nullptr, ssl_test_ticket_aead_ex_index_dup,
3333 ssl_test_ticket_aead_ex_index_free);
3334 });
3335 return g_ssl_test_ticket_aead_ex_index;
3336}
3337
3338static size_t ssl_test_ticket_aead_max_overhead(SSL *ssl) {
3339 return 1;
3340}
3341
3342static int ssl_test_ticket_aead_seal(SSL *ssl, uint8_t *out, size_t *out_len,
3343 size_t max_out_len, const uint8_t *in,
3344 size_t in_len) {
3345 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3346 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3347
3348 if (state->failure_mode == ssl_test_ticket_aead_seal_fail ||
3349 max_out_len < in_len + 1) {
3350 return 0;
3351 }
3352
3353 OPENSSL_memmove(out, in, in_len);
3354 out[in_len] = 0xff;
3355 *out_len = in_len + 1;
3356
3357 return 1;
3358}
3359
3360static ssl_ticket_aead_result_t ssl_test_ticket_aead_open(
3361 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len,
3362 const uint8_t *in, size_t in_len) {
3363 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3364 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3365
3366 if (state->retry_count > 0) {
3367 state->retry_count--;
3368 return ssl_ticket_aead_retry;
3369 }
3370
3371 switch (state->failure_mode) {
3372 case ssl_test_ticket_aead_ok:
3373 break;
3374 case ssl_test_ticket_aead_seal_fail:
3375 // If |seal| failed then there shouldn't be any ticket to try and
3376 // decrypt.
3377 abort();
3378 break;
3379 case ssl_test_ticket_aead_open_soft_fail:
3380 return ssl_ticket_aead_ignore_ticket;
3381 case ssl_test_ticket_aead_open_hard_fail:
3382 return ssl_ticket_aead_error;
3383 }
3384
3385 if (in_len == 0 || in[in_len - 1] != 0xff) {
3386 return ssl_ticket_aead_ignore_ticket;
3387 }
3388
3389 if (max_out_len < in_len - 1) {
3390 return ssl_ticket_aead_error;
3391 }
3392
3393 OPENSSL_memmove(out, in, in_len - 1);
3394 *out_len = in_len - 1;
3395 return ssl_ticket_aead_success;
3396}
3397
3398static const SSL_TICKET_AEAD_METHOD kSSLTestTicketMethod = {
3399 ssl_test_ticket_aead_max_overhead,
3400 ssl_test_ticket_aead_seal,
3401 ssl_test_ticket_aead_open,
3402};
3403
3404static void ConnectClientAndServerWithTicketMethod(
3405 bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
3406 SSL_CTX *client_ctx, SSL_CTX *server_ctx, unsigned retry_count,
3407 ssl_test_ticket_aead_failure_mode failure_mode, SSL_SESSION *session) {
3408 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
3409 ASSERT_TRUE(client);
3410 ASSERT_TRUE(server);
3411 SSL_set_connect_state(client.get());
3412 SSL_set_accept_state(server.get());
3413
3414 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3415 OPENSSL_malloc(sizeof(ssl_test_ticket_aead_state)));
3416 ASSERT_TRUE(state);
3417 OPENSSL_memset(state, 0, sizeof(ssl_test_ticket_aead_state));
3418 state->retry_count = retry_count;
3419 state->failure_mode = failure_mode;
3420
3421 ASSERT_TRUE(SSL_set_ex_data(server.get(), ssl_test_ticket_aead_get_ex_index(),
3422 state));
3423
3424 SSL_set_session(client.get(), session);
3425
3426 BIO *bio1, *bio2;
3427 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
3428
3429 // SSL_set_bio takes ownership.
3430 SSL_set_bio(client.get(), bio1, bio1);
3431 SSL_set_bio(server.get(), bio2, bio2);
3432
3433 if (CompleteHandshakes(client.get(), server.get())) {
3434 *out_client = std::move(client);
3435 *out_server = std::move(server);
3436 } else {
3437 out_client->reset();
3438 out_server->reset();
3439 }
3440}
3441
David Benjaminc9775322018-04-13 16:39:12 -04003442using TicketAEADMethodParam =
3443 testing::tuple<uint16_t, unsigned, ssl_test_ticket_aead_failure_mode>;
3444
Adam Langley4c341d02017-03-08 19:33:21 -08003445class TicketAEADMethodTest
David Benjaminc9775322018-04-13 16:39:12 -04003446 : public ::testing::TestWithParam<TicketAEADMethodParam> {};
Adam Langley4c341d02017-03-08 19:33:21 -08003447
3448TEST_P(TicketAEADMethodTest, Resume) {
3449 bssl::UniquePtr<X509> cert = GetTestCertificate();
3450 ASSERT_TRUE(cert);
3451 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3452 ASSERT_TRUE(key);
3453
3454 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
3455 ASSERT_TRUE(server_ctx);
3456 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
3457 ASSERT_TRUE(client_ctx);
3458
3459 const uint16_t version = testing::get<0>(GetParam());
3460 const unsigned retry_count = testing::get<1>(GetParam());
3461 const ssl_test_ticket_aead_failure_mode failure_mode =
3462 testing::get<2>(GetParam());
3463
3464 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3465 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3466 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), version));
3467 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), version));
3468 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), version));
3469 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), version));
3470
3471 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
3472 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
3473 SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
3474 SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
David Benjamin707af292017-03-10 17:47:18 -05003475 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langley4c341d02017-03-08 19:33:21 -08003476
3477 SSL_CTX_set_ticket_aead_method(server_ctx.get(), &kSSLTestTicketMethod);
3478
3479 bssl::UniquePtr<SSL> client, server;
3480 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3481 server_ctx.get(), retry_count,
3482 failure_mode, nullptr);
3483 switch (failure_mode) {
3484 case ssl_test_ticket_aead_ok:
3485 case ssl_test_ticket_aead_open_hard_fail:
3486 case ssl_test_ticket_aead_open_soft_fail:
3487 ASSERT_TRUE(client);
3488 break;
3489 case ssl_test_ticket_aead_seal_fail:
3490 EXPECT_FALSE(client);
3491 return;
3492 }
3493 EXPECT_FALSE(SSL_session_reused(client.get()));
3494 EXPECT_FALSE(SSL_session_reused(server.get()));
3495
David Benjamin707af292017-03-10 17:47:18 -05003496 // Run the read loop to account for post-handshake tickets in TLS 1.3.
3497 SSL_read(client.get(), nullptr, 0);
3498
3499 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
Adam Langley4c341d02017-03-08 19:33:21 -08003500 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3501 server_ctx.get(), retry_count,
David Benjamin707af292017-03-10 17:47:18 -05003502 failure_mode, session.get());
Adam Langley4c341d02017-03-08 19:33:21 -08003503 switch (failure_mode) {
3504 case ssl_test_ticket_aead_ok:
3505 ASSERT_TRUE(client);
3506 EXPECT_TRUE(SSL_session_reused(client.get()));
3507 EXPECT_TRUE(SSL_session_reused(server.get()));
3508 break;
3509 case ssl_test_ticket_aead_seal_fail:
3510 abort();
3511 break;
3512 case ssl_test_ticket_aead_open_hard_fail:
3513 EXPECT_FALSE(client);
3514 break;
3515 case ssl_test_ticket_aead_open_soft_fail:
3516 ASSERT_TRUE(client);
3517 EXPECT_FALSE(SSL_session_reused(client.get()));
3518 EXPECT_FALSE(SSL_session_reused(server.get()));
3519 }
3520}
3521
David Benjaminc9775322018-04-13 16:39:12 -04003522std::string TicketAEADMethodParamToString(
3523 const testing::TestParamInfo<TicketAEADMethodParam> &params) {
3524 std::string ret = GetVersionName(std::get<0>(params.param));
3525 // GTest only allows alphanumeric characters and '_' in the parameter
3526 // string. Additionally filter out the 'v' to get "TLS13" over "TLSv13".
3527 for (auto it = ret.begin(); it != ret.end();) {
3528 if (*it == '.' || *it == 'v') {
3529 it = ret.erase(it);
3530 } else {
3531 ++it;
3532 }
3533 }
3534 char retry_count[256];
3535 snprintf(retry_count, sizeof(retry_count), "%d", std::get<1>(params.param));
3536 ret += "_";
3537 ret += retry_count;
3538 ret += "Retries_";
3539 switch (std::get<2>(params.param)) {
3540 case ssl_test_ticket_aead_ok:
3541 ret += "OK";
3542 break;
3543 case ssl_test_ticket_aead_seal_fail:
3544 ret += "SealFail";
3545 break;
3546 case ssl_test_ticket_aead_open_soft_fail:
3547 ret += "OpenSoftFail";
3548 break;
3549 case ssl_test_ticket_aead_open_hard_fail:
3550 ret += "OpenHardFail";
3551 break;
3552 }
3553 return ret;
3554}
3555
Adam Langley4c341d02017-03-08 19:33:21 -08003556INSTANTIATE_TEST_CASE_P(
3557 TicketAEADMethodTests, TicketAEADMethodTest,
David Benjaminc9775322018-04-13 16:39:12 -04003558 testing::Combine(testing::Values(TLS1_2_VERSION, TLS1_3_VERSION),
3559 testing::Values(0, 1, 2),
3560 testing::Values(ssl_test_ticket_aead_ok,
3561 ssl_test_ticket_aead_seal_fail,
3562 ssl_test_ticket_aead_open_soft_fail,
3563 ssl_test_ticket_aead_open_hard_fail)),
3564 TicketAEADMethodParamToString);
Adam Langley4c341d02017-03-08 19:33:21 -08003565
David Benjaminca743582017-06-15 17:51:35 -04003566TEST(SSLTest, SelectNextProto) {
3567 uint8_t *result;
3568 uint8_t result_len;
3569
3570 // If there is an overlap, it should be returned.
3571 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3572 SSL_select_next_proto(&result, &result_len,
3573 (const uint8_t *)"\1a\2bb\3ccc", 9,
3574 (const uint8_t *)"\1x\1y\1a\1z", 8));
3575 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
3576
3577 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3578 SSL_select_next_proto(&result, &result_len,
3579 (const uint8_t *)"\1a\2bb\3ccc", 9,
3580 (const uint8_t *)"\1x\1y\2bb\1z", 9));
3581 EXPECT_EQ(Bytes("bb"), Bytes(result, result_len));
3582
3583 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3584 SSL_select_next_proto(&result, &result_len,
3585 (const uint8_t *)"\1a\2bb\3ccc", 9,
3586 (const uint8_t *)"\1x\1y\3ccc\1z", 10));
3587 EXPECT_EQ(Bytes("ccc"), Bytes(result, result_len));
3588
3589 // Peer preference order takes precedence over local.
3590 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3591 SSL_select_next_proto(&result, &result_len,
3592 (const uint8_t *)"\1a\2bb\3ccc", 9,
3593 (const uint8_t *)"\3ccc\2bb\1a", 9));
3594 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
3595
3596 // If there is no overlap, return the first local protocol.
3597 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
3598 SSL_select_next_proto(&result, &result_len,
3599 (const uint8_t *)"\1a\2bb\3ccc", 9,
3600 (const uint8_t *)"\1x\2yy\3zzz", 9));
3601 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
3602
3603 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
3604 SSL_select_next_proto(&result, &result_len, nullptr, 0,
3605 (const uint8_t *)"\1x\2yy\3zzz", 9));
3606 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
3607}
3608
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003609TEST(SSLTest, SealRecord) {
3610 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3611 server_ctx(SSL_CTX_new(TLS_method()));
3612 ASSERT_TRUE(client_ctx);
3613 ASSERT_TRUE(server_ctx);
3614
3615 bssl::UniquePtr<X509> cert = GetTestCertificate();
3616 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3617 ASSERT_TRUE(cert);
3618 ASSERT_TRUE(key);
3619 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3620 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3621
3622 bssl::UniquePtr<SSL> client, server;
3623 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003624 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003625
3626 const std::vector<uint8_t> record = {1, 2, 3, 4, 5};
3627 std::vector<uint8_t> prefix(
3628 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003629 body(record.size()),
3630 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003631 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3632 bssl::MakeSpan(body), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003633 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003634
3635 std::vector<uint8_t> sealed;
3636 sealed.insert(sealed.end(), prefix.begin(), prefix.end());
3637 sealed.insert(sealed.end(), body.begin(), body.end());
3638 sealed.insert(sealed.end(), suffix.begin(), suffix.end());
3639 std::vector<uint8_t> sealed_copy = sealed;
3640
3641 bssl::Span<uint8_t> plaintext;
3642 size_t record_len;
3643 uint8_t alert = 255;
3644 EXPECT_EQ(bssl::OpenRecord(server.get(), &plaintext, &record_len, &alert,
3645 bssl::MakeSpan(sealed)),
3646 bssl::OpenRecordResult::kOK);
3647 EXPECT_EQ(record_len, sealed.size());
3648 EXPECT_EQ(plaintext, record);
3649 EXPECT_EQ(255, alert);
3650}
3651
3652TEST(SSLTest, SealRecordInPlace) {
3653 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3654 server_ctx(SSL_CTX_new(TLS_method()));
3655 ASSERT_TRUE(client_ctx);
3656 ASSERT_TRUE(server_ctx);
3657
3658 bssl::UniquePtr<X509> cert = GetTestCertificate();
3659 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3660 ASSERT_TRUE(cert);
3661 ASSERT_TRUE(key);
3662 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3663 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3664
3665 bssl::UniquePtr<SSL> client, server;
3666 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003667 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003668
3669 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
3670 std::vector<uint8_t> record = plaintext;
3671 std::vector<uint8_t> prefix(
3672 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003673 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003674 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3675 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003676 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003677 record.insert(record.begin(), prefix.begin(), prefix.end());
3678 record.insert(record.end(), suffix.begin(), suffix.end());
3679
3680 bssl::Span<uint8_t> result;
3681 size_t record_len;
3682 uint8_t alert;
3683 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
3684 bssl::MakeSpan(record)),
3685 bssl::OpenRecordResult::kOK);
3686 EXPECT_EQ(record_len, record.size());
3687 EXPECT_EQ(plaintext, result);
3688}
3689
3690TEST(SSLTest, SealRecordTrailingData) {
3691 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3692 server_ctx(SSL_CTX_new(TLS_method()));
3693 ASSERT_TRUE(client_ctx);
3694 ASSERT_TRUE(server_ctx);
3695
3696 bssl::UniquePtr<X509> cert = GetTestCertificate();
3697 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3698 ASSERT_TRUE(cert);
3699 ASSERT_TRUE(key);
3700 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3701 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3702
3703 bssl::UniquePtr<SSL> client, server;
3704 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003705 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003706
3707 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
3708 std::vector<uint8_t> record = plaintext;
3709 std::vector<uint8_t> prefix(
3710 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003711 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003712 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3713 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003714 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003715 record.insert(record.begin(), prefix.begin(), prefix.end());
3716 record.insert(record.end(), suffix.begin(), suffix.end());
3717 record.insert(record.end(), {5, 4, 3, 2, 1});
3718
3719 bssl::Span<uint8_t> result;
3720 size_t record_len;
3721 uint8_t alert;
3722 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
3723 bssl::MakeSpan(record)),
3724 bssl::OpenRecordResult::kOK);
3725 EXPECT_EQ(record_len, record.size() - 5);
3726 EXPECT_EQ(plaintext, result);
3727}
3728
3729TEST(SSLTest, SealRecordInvalidSpanSize) {
3730 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3731 server_ctx(SSL_CTX_new(TLS_method()));
3732 ASSERT_TRUE(client_ctx);
3733 ASSERT_TRUE(server_ctx);
3734
3735 bssl::UniquePtr<X509> cert = GetTestCertificate();
3736 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3737 ASSERT_TRUE(cert);
3738 ASSERT_TRUE(key);
3739 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3740 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3741
3742 bssl::UniquePtr<SSL> client, server;
3743 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003744 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003745
3746 std::vector<uint8_t> record = {1, 2, 3, 4, 5};
3747 std::vector<uint8_t> prefix(
3748 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003749 body(record.size()),
3750 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003751
3752 auto expect_err = []() {
3753 int err = ERR_get_error();
3754 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
3755 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_BUFFER_TOO_SMALL);
3756 ERR_clear_error();
3757 };
3758 EXPECT_FALSE(bssl::SealRecord(
3759 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003760 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003761 expect_err();
3762 EXPECT_FALSE(bssl::SealRecord(
3763 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003764 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003765 expect_err();
3766
3767 EXPECT_FALSE(
3768 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3769 bssl::MakeSpan(record.data(), record.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003770 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003771 expect_err();
3772 EXPECT_FALSE(
3773 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3774 bssl::MakeSpan(record.data(), record.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003775 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003776 expect_err();
3777
3778 EXPECT_FALSE(bssl::SealRecord(
3779 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003780 bssl::MakeSpan(suffix.data(), suffix.size() - 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003781 expect_err();
3782 EXPECT_FALSE(bssl::SealRecord(
3783 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003784 bssl::MakeSpan(suffix.data(), suffix.size() + 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003785 expect_err();
3786}
3787
David Benjamin617b8182017-08-29 15:33:10 -04003788// The client should gracefully handle no suitable ciphers being enabled.
3789TEST(SSLTest, NoCiphersAvailable) {
3790 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3791 ASSERT_TRUE(ctx);
3792
3793 // Configure |client_ctx| with a cipher list that does not intersect with its
3794 // version configuration.
3795 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
3796 ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
3797 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
3798
3799 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3800 ASSERT_TRUE(ssl);
3801 SSL_set_connect_state(ssl.get());
3802
3803 UniquePtr<BIO> rbio(BIO_new(BIO_s_mem())), wbio(BIO_new(BIO_s_mem()));
3804 ASSERT_TRUE(rbio);
3805 ASSERT_TRUE(wbio);
3806 SSL_set0_rbio(ssl.get(), rbio.release());
3807 SSL_set0_wbio(ssl.get(), wbio.release());
3808
3809 int ret = SSL_do_handshake(ssl.get());
3810 EXPECT_EQ(-1, ret);
3811 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), ret));
3812 uint32_t err = ERR_get_error();
3813 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
3814 EXPECT_EQ(SSL_R_NO_CIPHERS_AVAILABLE, ERR_GET_REASON(err));
3815}
3816
David Benjamina4bafd32017-10-03 15:06:29 -04003817TEST_P(SSLVersionTest, SessionVersion) {
3818 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3819 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3820
3821 bssl::UniquePtr<SSL_SESSION> session =
3822 CreateClientSession(client_ctx_.get(), server_ctx_.get());
3823 ASSERT_TRUE(session);
3824 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
3825
3826 // Sessions in TLS 1.3 and later should be single-use.
3827 EXPECT_EQ(version() == TLS1_3_VERSION,
3828 !!SSL_SESSION_should_be_single_use(session.get()));
3829
3830 // Making fake sessions for testing works.
3831 session.reset(SSL_SESSION_new(client_ctx_.get()));
3832 ASSERT_TRUE(session);
3833 ASSERT_TRUE(SSL_SESSION_set_protocol_version(session.get(), version()));
3834 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
3835}
3836
David Benjaminfdb7a352017-10-12 17:34:18 -04003837TEST_P(SSLVersionTest, SSLPending) {
3838 UniquePtr<SSL> ssl(SSL_new(client_ctx_.get()));
3839 ASSERT_TRUE(ssl);
3840 EXPECT_EQ(0, SSL_pending(ssl.get()));
3841
3842 ASSERT_TRUE(Connect());
3843 EXPECT_EQ(0, SSL_pending(client_.get()));
3844
3845 ASSERT_EQ(5, SSL_write(server_.get(), "hello", 5));
3846 ASSERT_EQ(5, SSL_write(server_.get(), "world", 5));
3847 EXPECT_EQ(0, SSL_pending(client_.get()));
3848
3849 char buf[10];
3850 ASSERT_EQ(1, SSL_peek(client_.get(), buf, 1));
3851 EXPECT_EQ(5, SSL_pending(client_.get()));
3852
3853 ASSERT_EQ(1, SSL_read(client_.get(), buf, 1));
3854 EXPECT_EQ(4, SSL_pending(client_.get()));
3855
3856 ASSERT_EQ(4, SSL_read(client_.get(), buf, 10));
3857 EXPECT_EQ(0, SSL_pending(client_.get()));
3858
3859 ASSERT_EQ(2, SSL_read(client_.get(), buf, 2));
3860 EXPECT_EQ(3, SSL_pending(client_.get()));
3861}
3862
David Benjamina031b612017-10-11 20:48:25 -04003863// Test that post-handshake tickets consumed by |SSL_shutdown| are ignored.
3864TEST(SSLTest, ShutdownIgnoresTickets) {
3865 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3866 ASSERT_TRUE(ctx);
3867 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_3_VERSION));
3868 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
3869
3870 bssl::UniquePtr<X509> cert = GetTestCertificate();
3871 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3872 ASSERT_TRUE(cert);
3873 ASSERT_TRUE(key);
3874 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
3875 ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
3876
3877 SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_BOTH);
3878
3879 bssl::UniquePtr<SSL> client, server;
3880 ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
3881
3882 SSL_CTX_sess_set_new_cb(ctx.get(), [](SSL *ssl, SSL_SESSION *session) -> int {
3883 ADD_FAILURE() << "New session callback called during SSL_shutdown";
3884 return 0;
3885 });
3886
3887 // Send close_notify.
3888 EXPECT_EQ(0, SSL_shutdown(server.get()));
3889 EXPECT_EQ(0, SSL_shutdown(client.get()));
3890
3891 // Receive close_notify.
3892 EXPECT_EQ(1, SSL_shutdown(server.get()));
3893 EXPECT_EQ(1, SSL_shutdown(client.get()));
3894}
3895
David Benjamin6cc352e2017-11-02 17:21:39 -04003896TEST(SSLTest, SignatureAlgorithmProperties) {
3897 EXPECT_EQ(EVP_PKEY_NONE, SSL_get_signature_algorithm_key_type(0x1234));
3898 EXPECT_EQ(nullptr, SSL_get_signature_algorithm_digest(0x1234));
3899 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(0x1234));
3900
3901 EXPECT_EQ(EVP_PKEY_RSA,
3902 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
3903 EXPECT_EQ(EVP_md5_sha1(),
3904 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
3905 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
3906
3907 EXPECT_EQ(EVP_PKEY_EC, SSL_get_signature_algorithm_key_type(
3908 SSL_SIGN_ECDSA_SECP256R1_SHA256));
3909 EXPECT_EQ(EVP_sha256(), SSL_get_signature_algorithm_digest(
3910 SSL_SIGN_ECDSA_SECP256R1_SHA256));
3911 EXPECT_FALSE(
3912 SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_ECDSA_SECP256R1_SHA256));
3913
3914 EXPECT_EQ(EVP_PKEY_RSA,
David Benjamin6879e192018-04-13 16:01:02 -04003915 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04003916 EXPECT_EQ(EVP_sha384(),
David Benjamin6879e192018-04-13 16:01:02 -04003917 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PSS_RSAE_SHA384));
3918 EXPECT_TRUE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04003919}
3920
Adam Langley85967952018-07-03 08:04:58 -07003921static int XORCompressFunc(SSL *ssl, CBB *out, const uint8_t *in,
3922 size_t in_len) {
3923 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07003924 if (!CBB_add_u8(out, in[i] ^ 0x55)) {
Adam Langley85967952018-07-03 08:04:58 -07003925 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07003926 }
3927 }
3928
3929 SSL_set_app_data(ssl, XORCompressFunc);
3930
Adam Langley85967952018-07-03 08:04:58 -07003931 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07003932}
3933
Adam Langley85967952018-07-03 08:04:58 -07003934static int XORDecompressFunc(SSL *ssl, CRYPTO_BUFFER **out,
3935 size_t uncompressed_len, const uint8_t *in,
3936 size_t in_len) {
3937 if (in_len != uncompressed_len) {
3938 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07003939 }
3940
3941 uint8_t *data;
Adam Langley85967952018-07-03 08:04:58 -07003942 *out = CRYPTO_BUFFER_alloc(&data, uncompressed_len);
3943 if (*out == nullptr) {
3944 return 0;
Adam Langley0080d832018-06-07 16:39:49 -07003945 }
3946
Adam Langley85967952018-07-03 08:04:58 -07003947 for (size_t i = 0; i < in_len; i++) {
Adam Langley0080d832018-06-07 16:39:49 -07003948 data[i] = in[i] ^ 0x55;
3949 }
3950
3951 SSL_set_app_data(ssl, XORDecompressFunc);
3952
Adam Langley85967952018-07-03 08:04:58 -07003953 return 1;
Adam Langley0080d832018-06-07 16:39:49 -07003954}
3955
3956TEST(SSLTest, CertCompression) {
3957 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
3958 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
3959 ASSERT_TRUE(client_ctx);
3960 ASSERT_TRUE(server_ctx);
3961
3962 bssl::UniquePtr<X509> cert = GetTestCertificate();
3963 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3964 ASSERT_TRUE(cert);
3965 ASSERT_TRUE(key);
3966 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3967 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3968
3969 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
3970 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
3971 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
3972 client_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
3973 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
3974 server_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
3975
3976 bssl::UniquePtr<SSL> client, server;
3977 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3978 server_ctx.get()));
3979
3980 EXPECT_TRUE(SSL_get_app_data(client.get()) == XORDecompressFunc);
3981 EXPECT_TRUE(SSL_get_app_data(server.get()) == XORCompressFunc);
3982}
3983
Adam Langleyddb57cf2018-01-26 09:17:53 -08003984void MoveBIOs(SSL *dest, SSL *src) {
3985 BIO *rbio = SSL_get_rbio(src);
3986 BIO_up_ref(rbio);
3987 SSL_set0_rbio(dest, rbio);
3988
3989 BIO *wbio = SSL_get_wbio(src);
3990 BIO_up_ref(wbio);
3991 SSL_set0_wbio(dest, wbio);
3992
3993 SSL_set0_rbio(src, nullptr);
3994 SSL_set0_wbio(src, nullptr);
3995}
3996
3997TEST(SSLTest, Handoff) {
3998 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
3999 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4000 bssl::UniquePtr<SSL_CTX> handshaker_ctx(SSL_CTX_new(TLS_method()));
4001 ASSERT_TRUE(client_ctx);
4002 ASSERT_TRUE(server_ctx);
4003 ASSERT_TRUE(handshaker_ctx);
4004
4005 SSL_CTX_set_handoff_mode(server_ctx.get(), 1);
4006 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
4007 ASSERT_TRUE(
4008 SSL_CTX_set_max_proto_version(handshaker_ctx.get(), TLS1_2_VERSION));
4009
4010 bssl::UniquePtr<X509> cert = GetTestCertificate();
4011 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4012 ASSERT_TRUE(cert);
4013 ASSERT_TRUE(key);
4014 ASSERT_TRUE(SSL_CTX_use_certificate(handshaker_ctx.get(), cert.get()));
4015 ASSERT_TRUE(SSL_CTX_use_PrivateKey(handshaker_ctx.get(), key.get()));
4016
4017 bssl::UniquePtr<SSL> client, server;
4018 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4019 server_ctx.get(), ClientConfig(),
4020 false /* don't handshake */));
4021
4022 int client_ret = SSL_do_handshake(client.get());
4023 int client_err = SSL_get_error(client.get(), client_ret);
4024 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4025
4026 int server_ret = SSL_do_handshake(server.get());
4027 int server_err = SSL_get_error(server.get(), server_ret);
4028 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
4029
4030 ScopedCBB cbb;
4031 Array<uint8_t> handoff;
4032 ASSERT_TRUE(CBB_init(cbb.get(), 256));
4033 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get()));
4034 ASSERT_TRUE(CBBFinishArray(cbb.get(), &handoff));
4035
4036 bssl::UniquePtr<SSL> handshaker(SSL_new(handshaker_ctx.get()));
4037 ASSERT_TRUE(SSL_apply_handoff(handshaker.get(), handoff));
4038
4039 MoveBIOs(handshaker.get(), server.get());
4040
4041 int handshake_ret = SSL_do_handshake(handshaker.get());
4042 int handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
Matthew Braithwaite56986f92018-03-22 11:48:33 -07004043 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
Adam Langleyddb57cf2018-01-26 09:17:53 -08004044
Matthew Braithwaite56986f92018-03-22 11:48:33 -07004045 // Double-check that additional calls to |SSL_do_handshake| continue
4046 // to get |SSL_ERRROR_HANDBACK|.
4047 handshake_ret = SSL_do_handshake(handshaker.get());
4048 handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
4049 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
Adam Langleyddb57cf2018-01-26 09:17:53 -08004050
4051 ScopedCBB cbb_handback;
4052 Array<uint8_t> handback;
4053 ASSERT_TRUE(CBB_init(cbb_handback.get(), 1024));
4054 ASSERT_TRUE(SSL_serialize_handback(handshaker.get(), cbb_handback.get()));
4055 ASSERT_TRUE(CBBFinishArray(cbb_handback.get(), &handback));
4056
4057 bssl::UniquePtr<SSL> server2(SSL_new(server_ctx.get()));
4058 ASSERT_TRUE(SSL_apply_handback(server2.get(), handback));
4059
4060 MoveBIOs(server2.get(), handshaker.get());
Matthew Braithwaite56986f92018-03-22 11:48:33 -07004061 ASSERT_TRUE(CompleteHandshakes(client.get(), server2.get()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004062
4063 uint8_t byte = 42;
4064 EXPECT_EQ(SSL_write(client.get(), &byte, 1), 1);
4065 EXPECT_EQ(SSL_read(server2.get(), &byte, 1), 1);
4066 EXPECT_EQ(42, byte);
4067
4068 byte = 43;
4069 EXPECT_EQ(SSL_write(server2.get(), &byte, 1), 1);
4070 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
4071 EXPECT_EQ(43, byte);
4072}
4073
4074TEST(SSLTest, HandoffDeclined) {
4075 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4076 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4077 ASSERT_TRUE(client_ctx);
4078 ASSERT_TRUE(server_ctx);
4079
4080 SSL_CTX_set_handoff_mode(server_ctx.get(), 1);
4081 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
4082
4083 bssl::UniquePtr<X509> cert = GetTestCertificate();
4084 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4085 ASSERT_TRUE(cert);
4086 ASSERT_TRUE(key);
4087 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
4088 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
4089
4090 bssl::UniquePtr<SSL> client, server;
4091 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4092 server_ctx.get(), ClientConfig(),
4093 false /* don't handshake */));
4094
4095 int client_ret = SSL_do_handshake(client.get());
4096 int client_err = SSL_get_error(client.get(), client_ret);
4097 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4098
4099 int server_ret = SSL_do_handshake(server.get());
4100 int server_err = SSL_get_error(server.get(), server_ret);
4101 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
4102
4103 ScopedCBB cbb;
4104 ASSERT_TRUE(CBB_init(cbb.get(), 256));
4105 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get()));
4106
4107 ASSERT_TRUE(SSL_decline_handoff(server.get()));
4108
4109 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
4110
4111 uint8_t byte = 42;
4112 EXPECT_EQ(SSL_write(client.get(), &byte, 1), 1);
4113 EXPECT_EQ(SSL_read(server.get(), &byte, 1), 1);
4114 EXPECT_EQ(42, byte);
4115
4116 byte = 43;
4117 EXPECT_EQ(SSL_write(server.get(), &byte, 1), 1);
4118 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
4119 EXPECT_EQ(43, byte);
4120}
4121
Adam Langley826ce152018-08-03 10:31:21 -07004122static std::string SigAlgsToString(Span<const uint16_t> sigalgs) {
4123 std::string ret = "{";
4124
4125 for (uint16_t v : sigalgs) {
4126 if (ret.size() > 1) {
4127 ret += ", ";
4128 }
4129
4130 char buf[8];
4131 snprintf(buf, sizeof(buf) - 1, "0x%02x", v);
4132 buf[sizeof(buf)-1] = 0;
4133 ret += std::string(buf);
4134 }
4135
4136 ret += "}";
4137 return ret;
4138}
4139
4140void ExpectSigAlgsEqual(Span<const uint16_t> expected,
4141 Span<const uint16_t> actual) {
4142 bool matches = false;
4143 if (expected.size() == actual.size()) {
4144 matches = true;
4145
4146 for (size_t i = 0; i < expected.size(); i++) {
4147 if (expected[i] != actual[i]) {
4148 matches = false;
4149 break;
4150 }
4151 }
4152 }
4153
4154 if (!matches) {
4155 ADD_FAILURE() << "expected: " << SigAlgsToString(expected)
4156 << " got: " << SigAlgsToString(actual);
4157 }
4158}
4159
4160TEST(SSLTest, SigAlgs) {
4161 static const struct {
4162 std::vector<int> input;
4163 bool ok;
4164 std::vector<uint16_t> expected;
4165 } kTests[] = {
4166 {{}, true, {}},
4167 {{1}, false, {}},
4168 {{1, 2, 3}, false, {}},
4169 {{NID_sha256, EVP_PKEY_ED25519}, false, {}},
4170 {{NID_sha256, EVP_PKEY_RSA, NID_sha256, EVP_PKEY_RSA}, false, {}},
4171
4172 {{NID_sha256, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA256}},
4173 {{NID_sha512, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA512}},
4174 {{NID_sha256, EVP_PKEY_RSA_PSS}, true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4175 {{NID_undef, EVP_PKEY_ED25519}, true, {SSL_SIGN_ED25519}},
4176 {{NID_undef, EVP_PKEY_ED25519, NID_sha384, EVP_PKEY_EC},
4177 true,
4178 {SSL_SIGN_ED25519, SSL_SIGN_ECDSA_SECP384R1_SHA384}},
4179 };
4180
4181 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4182
4183 unsigned n = 1;
4184 for (const auto &test : kTests) {
4185 SCOPED_TRACE(n++);
4186
4187 const bool ok =
4188 SSL_CTX_set1_sigalgs(ctx.get(), test.input.data(), test.input.size());
4189 EXPECT_EQ(ok, test.ok);
4190
4191 if (!ok) {
4192 ERR_clear_error();
4193 }
4194
4195 if (!test.ok) {
4196 continue;
4197 }
4198
4199 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
4200 }
4201}
4202
4203TEST(SSLTest, SigAlgsList) {
4204 static const struct {
4205 const char *input;
4206 bool ok;
4207 std::vector<uint16_t> expected;
4208 } kTests[] = {
4209 {"", false, {}},
4210 {":", false, {}},
4211 {"+", false, {}},
4212 {"RSA", false, {}},
4213 {"RSA+", false, {}},
4214 {"RSA+SHA256:", false, {}},
4215 {":RSA+SHA256:", false, {}},
4216 {":RSA+SHA256+:", false, {}},
4217 {"!", false, {}},
4218 {"\x01", false, {}},
4219 {"RSA+SHA256:RSA+SHA384:RSA+SHA256", false, {}},
4220 {"RSA-PSS+SHA256:rsa_pss_rsae_sha256", false, {}},
4221
4222 {"RSA+SHA256", true, {SSL_SIGN_RSA_PKCS1_SHA256}},
4223 {"RSA+SHA256:ed25519",
4224 true,
4225 {SSL_SIGN_RSA_PKCS1_SHA256, SSL_SIGN_ED25519}},
4226 {"ECDSA+SHA256:RSA+SHA512",
4227 true,
4228 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PKCS1_SHA512}},
4229 {"ecdsa_secp256r1_sha256:rsa_pss_rsae_sha256",
4230 true,
4231 {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4232 {"RSA-PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4233 {"PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
4234 };
4235
4236 UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4237
4238 unsigned n = 1;
4239 for (const auto &test : kTests) {
4240 SCOPED_TRACE(n++);
4241
4242 const bool ok = SSL_CTX_set1_sigalgs_list(ctx.get(), test.input);
4243 EXPECT_EQ(ok, test.ok);
4244
4245 if (!ok) {
4246 if (test.ok) {
4247 ERR_print_errors_fp(stderr);
4248 }
4249 ERR_clear_error();
4250 }
4251
4252 if (!test.ok) {
4253 continue;
4254 }
4255
4256 ExpectSigAlgsEqual(test.expected, ctx->cert->sigalgs);
4257 }
4258}
4259
David Benjamin5869eb32018-07-17 00:59:45 -04004260TEST_P(SSLVersionTest, VerifyBeforeCertRequest) {
4261 // Configure the server to request client certificates.
4262 SSL_CTX_set_custom_verify(
4263 server_ctx_.get(), SSL_VERIFY_PEER,
4264 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
4265
4266 // Configure the client to reject the server certificate.
4267 SSL_CTX_set_custom_verify(
4268 client_ctx_.get(), SSL_VERIFY_PEER,
4269 [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_invalid; });
4270
4271 // cert_cb should not be called. Verification should fail first.
4272 SSL_CTX_set_cert_cb(client_ctx_.get(),
4273 [](SSL *ssl, void *arg) {
4274 ADD_FAILURE() << "cert_cb unexpectedly called";
4275 return 0;
4276 },
4277 nullptr);
4278
4279 bssl::UniquePtr<SSL> client, server;
4280 EXPECT_FALSE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
4281 server_ctx_.get()));
4282}
4283
David Benjamin492c9aa2018-08-31 16:35:22 -05004284// Test that ticket-based sessions on the client get fake session IDs.
4285TEST_P(SSLVersionTest, FakeIDsForTickets) {
4286 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4287 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4288
4289 bssl::UniquePtr<SSL_SESSION> session =
4290 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4291 ASSERT_TRUE(session);
4292
4293 EXPECT_TRUE(SSL_SESSION_has_ticket(session.get()));
4294 unsigned session_id_length;
4295 SSL_SESSION_get_id(session.get(), &session_id_length);
4296 EXPECT_NE(session_id_length, 0u);
4297}
4298
David Benjamin6c04bd12018-07-19 18:13:09 -04004299// These tests test multi-threaded behavior. They are intended to run with
4300// ThreadSanitizer.
David Benjamin5b33eff2018-09-22 16:52:48 -07004301#if defined(OPENSSL_THREADS)
David Benjamin6c04bd12018-07-19 18:13:09 -04004302TEST_P(SSLVersionTest, SessionCacheThreads) {
4303 SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
4304 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4305 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4306
4307 if (version() == TLS1_3_VERSION) {
4308 // Our TLS 1.3 implementation does not support stateful resumption.
4309 ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
4310 return;
4311 }
4312
4313 // Establish two client sessions to test with.
4314 bssl::UniquePtr<SSL_SESSION> session1 =
4315 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4316 ASSERT_TRUE(session1);
4317 bssl::UniquePtr<SSL_SESSION> session2 =
4318 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4319 ASSERT_TRUE(session2);
4320
4321 auto connect_with_session = [&](SSL_SESSION *session) {
4322 ClientConfig config;
4323 config.session = session;
4324 UniquePtr<SSL> client, server;
4325 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
4326 server_ctx_.get(), config));
4327 };
4328
4329 // Resume sessions in parallel with establishing new ones.
4330 {
4331 std::vector<std::thread> threads;
4332 threads.emplace_back([&] { connect_with_session(nullptr); });
4333 threads.emplace_back([&] { connect_with_session(nullptr); });
4334 threads.emplace_back([&] { connect_with_session(session1.get()); });
4335 threads.emplace_back([&] { connect_with_session(session1.get()); });
4336 threads.emplace_back([&] { connect_with_session(session2.get()); });
4337 threads.emplace_back([&] { connect_with_session(session2.get()); });
4338 for (auto &thread : threads) {
4339 thread.join();
4340 }
4341 }
4342
4343 // Hit the maximum session cache size across multiple threads
4344 size_t limit = SSL_CTX_sess_number(server_ctx_.get()) + 2;
4345 SSL_CTX_sess_set_cache_size(server_ctx_.get(), limit);
4346 {
4347 std::vector<std::thread> threads;
4348 for (int i = 0; i < 4; i++) {
4349 threads.emplace_back([&]() {
4350 connect_with_session(nullptr);
4351 EXPECT_LE(SSL_CTX_sess_number(server_ctx_.get()), limit);
4352 });
4353 }
4354 for (auto &thread : threads) {
4355 thread.join();
4356 }
4357 EXPECT_EQ(SSL_CTX_sess_number(server_ctx_.get()), limit);
4358 }
4359}
4360
4361TEST_P(SSLVersionTest, SessionTicketThreads) {
4362 for (bool renew_ticket : {false, true}) {
4363 SCOPED_TRACE(renew_ticket);
4364 ResetContexts();
4365 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4366 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4367 if (renew_ticket) {
4368 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
4369 }
4370
4371 // Establish two client sessions to test with.
4372 bssl::UniquePtr<SSL_SESSION> session1 =
4373 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4374 ASSERT_TRUE(session1);
4375 bssl::UniquePtr<SSL_SESSION> session2 =
4376 CreateClientSession(client_ctx_.get(), server_ctx_.get());
4377 ASSERT_TRUE(session2);
4378
4379 auto connect_with_session = [&](SSL_SESSION *session) {
4380 ClientConfig config;
4381 config.session = session;
4382 UniquePtr<SSL> client, server;
4383 EXPECT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
4384 server_ctx_.get(), config));
4385 };
4386
4387 // Resume sessions in parallel with establishing new ones.
4388 {
4389 std::vector<std::thread> threads;
4390 threads.emplace_back([&] { connect_with_session(nullptr); });
4391 threads.emplace_back([&] { connect_with_session(nullptr); });
4392 threads.emplace_back([&] { connect_with_session(session1.get()); });
4393 threads.emplace_back([&] { connect_with_session(session1.get()); });
4394 threads.emplace_back([&] { connect_with_session(session2.get()); });
4395 threads.emplace_back([&] { connect_with_session(session2.get()); });
4396 for (auto &thread : threads) {
4397 thread.join();
4398 }
4399 }
4400 }
4401}
4402
4403// SSL_CTX_get0_certificate needs to lock internally. Test this works.
4404TEST(SSLTest, GetCertificateThreads) {
4405 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4406 ASSERT_TRUE(ctx);
4407 bssl::UniquePtr<X509> cert = GetTestCertificate();
4408 ASSERT_TRUE(cert);
4409 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
4410
4411 // Existing code expects |SSL_CTX_get0_certificate| to be callable from two
4412 // threads concurrently. It originally was an immutable operation. Now we
4413 // implement it with a thread-safe cache, so it is worth testing.
4414 X509 *cert2_thread;
4415 std::thread thread(
4416 [&] { cert2_thread = SSL_CTX_get0_certificate(ctx.get()); });
4417 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
4418 thread.join();
4419
4420 EXPECT_EQ(cert2, cert2_thread);
4421 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
4422}
4423#endif
4424
David Benjamin96628432017-01-19 19:05:47 -05004425// TODO(davidben): Convert this file to GTest properly.
4426TEST(SSLTest, AllTests) {
David Benjamine11726a2017-04-23 12:14:28 -04004427 if (!TestSSL_SESSIONEncoding(kOpenSSLSession) ||
Adam Langley10f97f32016-07-12 08:09:33 -07004428 !TestSSL_SESSIONEncoding(kCustomSession) ||
4429 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
4430 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
4431 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
4432 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
Steven Valdeza833c352016-11-01 13:39:36 -04004433 // Test the padding extension at TLS 1.2.
4434 !TestPaddingExtension(TLS1_2_VERSION, TLS1_2_VERSION) ||
4435 // Test the padding extension at TLS 1.3 with a TLS 1.2 session, so there
4436 // will be no PSK binder after the padding extension.
4437 !TestPaddingExtension(TLS1_3_VERSION, TLS1_2_VERSION) ||
4438 // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
4439 // will be a PSK binder after the padding extension.
David Benjaminaaef8332018-06-29 16:45:49 -04004440 !TestPaddingExtension(TLS1_3_VERSION, TLS1_3_VERSION)) {
David Benjamin96628432017-01-19 19:05:47 -05004441 ADD_FAILURE() << "Tests failed";
David Benjaminbb0a17c2014-09-20 15:35:39 -04004442 }
David Benjamin2e521212014-07-16 14:37:51 -04004443}
Martin Kreichgauer72912d22017-08-04 12:06:43 -07004444
4445} // namespace
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -07004446BSSL_NAMESPACE_END