blob: d6e0713154d7915c4a2f0a2062f00548caa4cad5 [file] [log] [blame]
David Benjamin2e521212014-07-16 14:37:51 -04001/* Copyright (c) 2014, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15#include <stdio.h>
David Benjamin751e8892014-10-19 00:59:36 -040016#include <string.h>
David Benjamin1269ddd2015-10-18 15:18:55 -040017#include <time.h>
David Benjamin2e521212014-07-16 14:37:51 -040018
David Benjamin0f653952015-10-18 14:28:01 -040019#include <algorithm>
David Benjamin1d77e562015-03-22 17:22:08 -040020#include <string>
David Benjamin4f6acaf2015-11-21 03:00:50 -050021#include <utility>
David Benjamin1d77e562015-03-22 17:22:08 -040022#include <vector>
23
David Benjamin96628432017-01-19 19:05:47 -050024#include <gtest/gtest.h>
25
David Benjamin751e8892014-10-19 00:59:36 -040026#include <openssl/base64.h>
27#include <openssl/bio.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040028#include <openssl/cipher.h>
David Benjamin7a1eefd2015-10-17 23:39:22 -040029#include <openssl/crypto.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040030#include <openssl/err.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040031#include <openssl/hmac.h>
David Benjaminde942382016-02-11 12:02:01 -050032#include <openssl/pem.h>
David Benjamin25490f22016-07-14 00:22:54 -040033#include <openssl/sha.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040034#include <openssl/ssl.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040035#include <openssl/rand.h>
David Benjaminde942382016-02-11 12:02:01 -050036#include <openssl/x509.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040037
Steven Valdez87eab492016-06-27 16:34:59 -040038#include "internal.h"
Steven Valdezcb966542016-08-17 16:56:14 -040039#include "../crypto/internal.h"
Sigbjorn Vik2b23d242015-06-29 15:07:26 +020040#include "../crypto/test/test_util.h"
41
David Benjamin721e8b72016-08-03 13:13:17 -040042#if defined(OPENSSL_WINDOWS)
David Benjaminc11ea9422017-08-29 16:33:21 -040043// Windows defines struct timeval in winsock2.h.
David Benjamin721e8b72016-08-03 13:13:17 -040044OPENSSL_MSVC_PRAGMA(warning(push, 3))
45#include <winsock2.h>
46OPENSSL_MSVC_PRAGMA(warning(pop))
47#else
48#include <sys/time.h>
49#endif
50
David Benjamin1d77e562015-03-22 17:22:08 -040051
Martin Kreichgauer72912d22017-08-04 12:06:43 -070052namespace bssl {
53
54namespace {
55
Martin Kreichgauer1a663262017-08-16 14:54:04 -070056#define TRACED_CALL(code) \
57 do { \
58 SCOPED_TRACE("<- called from here"); \
59 code; \
60 if (::testing::Test::HasFatalFailure()) { \
61 return; \
62 } \
63 } while (false)
64
Martin Kreichgauer72912d22017-08-04 12:06:43 -070065struct VersionParam {
66 uint16_t version;
67 enum { is_tls, is_dtls } ssl_method;
68 const char name[8];
69};
70
71static const size_t kTicketKeyLen = 48;
72
73static const VersionParam kAllVersions[] = {
74 {SSL3_VERSION, VersionParam::is_tls, "SSL3"},
75 {TLS1_VERSION, VersionParam::is_tls, "TLS1"},
76 {TLS1_1_VERSION, VersionParam::is_tls, "TLS1_1"},
77 {TLS1_2_VERSION, VersionParam::is_tls, "TLS1_2"},
Martin Kreichgauer72912d22017-08-04 12:06:43 -070078 {TLS1_3_VERSION, VersionParam::is_tls, "TLS1_3"},
Martin Kreichgauer72912d22017-08-04 12:06:43 -070079 {DTLS1_VERSION, VersionParam::is_dtls, "DTLS1"},
80 {DTLS1_2_VERSION, VersionParam::is_dtls, "DTLS1_2"},
81};
82
David Benjamin1d77e562015-03-22 17:22:08 -040083struct ExpectedCipher {
84 unsigned long id;
David Benjaminbb0a17c2014-09-20 15:35:39 -040085 int in_group_flag;
David Benjamin1d77e562015-03-22 17:22:08 -040086};
David Benjaminbb0a17c2014-09-20 15:35:39 -040087
David Benjamin1d77e562015-03-22 17:22:08 -040088struct CipherTest {
89 // The rule string to apply.
David Benjaminbb0a17c2014-09-20 15:35:39 -040090 const char *rule;
David Benjaminfb974e62015-12-16 19:34:22 -050091 // The list of expected ciphers, in order.
92 std::vector<ExpectedCipher> expected;
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -080093 // True if this cipher list should fail in strict mode.
94 bool strict_fail;
David Benjamin1d77e562015-03-22 17:22:08 -040095};
David Benjaminbb0a17c2014-09-20 15:35:39 -040096
Alessandro Ghedini5fd18072016-09-28 21:04:25 +010097struct CurveTest {
98 // The rule string to apply.
99 const char *rule;
100 // The list of expected curves, in order.
101 std::vector<uint16_t> expected;
102};
103
David Benjaminfb974e62015-12-16 19:34:22 -0500104static const CipherTest kCipherTests[] = {
105 // Selecting individual ciphers should work.
106 {
107 "ECDHE-ECDSA-CHACHA20-POLY1305:"
108 "ECDHE-RSA-CHACHA20-POLY1305:"
109 "ECDHE-ECDSA-AES128-GCM-SHA256:"
110 "ECDHE-RSA-AES128-GCM-SHA256",
111 {
112 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500113 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500114 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
115 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
116 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800117 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500118 },
119 // + reorders selected ciphers to the end, keeping their relative order.
120 {
121 "ECDHE-ECDSA-CHACHA20-POLY1305:"
122 "ECDHE-RSA-CHACHA20-POLY1305:"
123 "ECDHE-ECDSA-AES128-GCM-SHA256:"
124 "ECDHE-RSA-AES128-GCM-SHA256:"
125 "+aRSA",
126 {
127 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500128 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
129 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500130 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
131 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800132 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500133 },
134 // ! banishes ciphers from future selections.
135 {
136 "!aRSA:"
137 "ECDHE-ECDSA-CHACHA20-POLY1305:"
138 "ECDHE-RSA-CHACHA20-POLY1305:"
139 "ECDHE-ECDSA-AES128-GCM-SHA256:"
140 "ECDHE-RSA-AES128-GCM-SHA256",
141 {
142 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500143 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
144 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800145 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500146 },
147 // Multiple masks can be ANDed in a single rule.
148 {
149 "kRSA+AESGCM+AES128",
150 {
151 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
152 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800153 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500154 },
155 // - removes selected ciphers, but preserves their order for future
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700156 // selections. Select AES_128_GCM, but order the key exchanges RSA,
David Benjaminfb974e62015-12-16 19:34:22 -0500157 // ECDHE_RSA.
158 {
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700159 "ALL:-kECDHE:"
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700160 "-kRSA:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500161 "AESGCM+AES128+aRSA",
162 {
163 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500164 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
165 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800166 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500167 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800168 // Unknown selectors are no-ops, except in strict mode.
David Benjaminfb974e62015-12-16 19:34:22 -0500169 {
170 "ECDHE-ECDSA-CHACHA20-POLY1305:"
171 "ECDHE-RSA-CHACHA20-POLY1305:"
172 "ECDHE-ECDSA-AES128-GCM-SHA256:"
173 "ECDHE-RSA-AES128-GCM-SHA256:"
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800174 "BOGUS1",
David Benjaminfb974e62015-12-16 19:34:22 -0500175 {
176 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500177 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500178 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
179 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
180 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800181 true,
182 },
183 // Unknown selectors are no-ops, except in strict mode.
184 {
185 "ECDHE-ECDSA-CHACHA20-POLY1305:"
186 "ECDHE-RSA-CHACHA20-POLY1305:"
187 "ECDHE-ECDSA-AES128-GCM-SHA256:"
188 "ECDHE-RSA-AES128-GCM-SHA256:"
189 "-BOGUS2:+BOGUS3:!BOGUS4",
190 {
191 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
192 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
193 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
194 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
195 },
196 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500197 },
198 // Square brackets specify equi-preference groups.
199 {
200 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
201 "[ECDHE-RSA-CHACHA20-POLY1305]:"
202 "ECDHE-RSA-AES128-GCM-SHA256",
203 {
204 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
David Benjaminfb974e62015-12-16 19:34:22 -0500205 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley2e839242017-01-19 15:12:44 -0800206 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500207 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
208 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800209 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500210 },
David Benjamin6fff3862017-06-21 21:07:04 -0400211 // Standard names may be used instead of OpenSSL names.
212 {
213 "[TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256|"
David Benjaminbf5f1922017-07-01 11:13:53 -0400214 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256]:"
David Benjamin6fff3862017-06-21 21:07:04 -0400215 "[TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256]:"
216 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
217 {
218 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
219 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
220 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
221 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
222 },
223 false,
224 },
David Benjaminfb974e62015-12-16 19:34:22 -0500225 // @STRENGTH performs a stable strength-sort of the selected ciphers and
226 // only the selected ciphers.
227 {
228 // To simplify things, banish all but {ECDHE_RSA,RSA} x
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700229 // {CHACHA20,AES_256_CBC,AES_128_CBC} x SHA1.
David Benjamin6e678ee2018-04-16 19:54:42 -0400230 "!AESGCM:!3DES:"
David Benjaminfb974e62015-12-16 19:34:22 -0500231 // Order some ciphers backwards by strength.
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700232 "ALL:-CHACHA20:-AES256:-AES128:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500233 // Select ECDHE ones and sort them by strength. Ties should resolve
234 // based on the order above.
235 "kECDHE:@STRENGTH:-ALL:"
236 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
237 // by strength. Then RSA, backwards by strength.
238 "aRSA",
239 {
240 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
241 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500242 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500243 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
244 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
245 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800246 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500247 },
David Benjaminbf5f1922017-07-01 11:13:53 -0400248 // Additional masks after @STRENGTH get silently discarded.
249 //
250 // TODO(davidben): Make this an error. If not silently discarded, they get
251 // interpreted as + opcodes which are very different.
252 {
253 "ECDHE-RSA-AES128-GCM-SHA256:"
254 "ECDHE-RSA-AES256-GCM-SHA384:"
255 "@STRENGTH+AES256",
256 {
257 {TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
258 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
259 },
260 false,
261 },
262 {
263 "ECDHE-RSA-AES128-GCM-SHA256:"
264 "ECDHE-RSA-AES256-GCM-SHA384:"
265 "@STRENGTH+AES256:"
266 "ECDHE-RSA-CHACHA20-POLY1305",
267 {
268 {TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
269 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
270 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
271 },
272 false,
273 },
David Benjaminfb974e62015-12-16 19:34:22 -0500274 // Exact ciphers may not be used in multi-part rules; they are treated
275 // as unknown aliases.
276 {
277 "ECDHE-ECDSA-AES128-GCM-SHA256:"
278 "ECDHE-RSA-AES128-GCM-SHA256:"
279 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
280 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
281 {
282 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
283 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
284 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800285 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500286 },
287 // SSLv3 matches everything that existed before TLS 1.2.
288 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400289 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!SSLv3",
David Benjaminfb974e62015-12-16 19:34:22 -0500290 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400291 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500292 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800293 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500294 },
295 // TLSv1.2 matches everything added in TLS 1.2.
296 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400297 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!TLSv1.2",
David Benjaminfb974e62015-12-16 19:34:22 -0500298 {
299 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
300 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800301 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500302 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800303 // The two directives have no intersection. But each component is valid, so
304 // even in strict mode it is accepted.
David Benjaminfb974e62015-12-16 19:34:22 -0500305 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400306 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!TLSv1.2+SSLv3",
David Benjaminfb974e62015-12-16 19:34:22 -0500307 {
308 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400309 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500310 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800311 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500312 },
Adam Langley22df6912017-07-25 12:27:37 -0700313 // Spaces, semi-colons and commas are separators.
314 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400315 "AES128-SHA: ECDHE-RSA-AES128-GCM-SHA256 AES256-SHA ,ECDHE-ECDSA-AES128-GCM-SHA256 ; AES128-GCM-SHA256",
Adam Langley22df6912017-07-25 12:27:37 -0700316 {
317 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400318 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley22df6912017-07-25 12:27:37 -0700319 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400320 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley22df6912017-07-25 12:27:37 -0700321 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
322 },
323 // …but not in strict mode.
324 true,
325 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400326};
327
328static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400329 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400330 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
331 "RSA]",
332 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400333 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400334 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400335 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400336 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400337 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400338 "",
339 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400340 // COMPLEMENTOFDEFAULT is empty.
341 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400342 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400343 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400344 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400345 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
346 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
347 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
348 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
Adam Langleyf99f2442016-10-02 09:53:38 -0700349 // Opcode supplied, but missing selector.
350 "+",
Adam Langley22df6912017-07-25 12:27:37 -0700351 // Spaces are forbidden in equal-preference groups.
352 "[AES128-SHA | AES128-SHA256]",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400353};
354
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700355static const char *kMustNotIncludeNull[] = {
356 "ALL",
357 "DEFAULT",
David Benjamind6e9eec2015-11-18 09:48:55 -0500358 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700359 "FIPS",
360 "SHA",
361 "SHA1",
362 "RSA",
363 "SSLv3",
364 "TLSv1",
365 "TLSv1.2",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700366};
367
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100368static const CurveTest kCurveTests[] = {
369 {
370 "P-256",
371 { SSL_CURVE_SECP256R1 },
372 },
373 {
374 "P-256:P-384:P-521:X25519",
375 {
376 SSL_CURVE_SECP256R1,
377 SSL_CURVE_SECP384R1,
378 SSL_CURVE_SECP521R1,
379 SSL_CURVE_X25519,
380 },
381 },
David Benjamin6dda1662017-11-02 20:44:26 -0400382 {
383 "prime256v1:secp384r1:secp521r1:x25519",
384 {
385 SSL_CURVE_SECP256R1,
386 SSL_CURVE_SECP384R1,
387 SSL_CURVE_SECP521R1,
388 SSL_CURVE_X25519,
389 },
390 },
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100391};
392
393static const char *kBadCurvesLists[] = {
394 "",
395 ":",
396 "::",
397 "P-256::X25519",
398 "RSA:P-256",
399 "P-256:RSA",
400 "X25519:P-256:",
401 ":X25519:P-256",
402};
403
David Benjamin70dbf042017-08-08 18:51:37 -0400404static std::string CipherListToString(SSL_CTX *ctx) {
David Benjamin1d77e562015-03-22 17:22:08 -0400405 bool in_group = false;
David Benjamine11726a2017-04-23 12:14:28 -0400406 std::string ret;
David Benjamin70dbf042017-08-08 18:51:37 -0400407 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
408 for (size_t i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
409 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
410 if (!in_group && SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400411 ret += "\t[\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400412 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400413 }
David Benjamine11726a2017-04-23 12:14:28 -0400414 ret += "\t";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400415 if (in_group) {
David Benjamine11726a2017-04-23 12:14:28 -0400416 ret += " ";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400417 }
David Benjamine11726a2017-04-23 12:14:28 -0400418 ret += SSL_CIPHER_get_name(cipher);
419 ret += "\n";
David Benjamin70dbf042017-08-08 18:51:37 -0400420 if (in_group && !SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400421 ret += "\t]\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400422 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400423 }
424 }
David Benjamine11726a2017-04-23 12:14:28 -0400425 return ret;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400426}
427
David Benjamin70dbf042017-08-08 18:51:37 -0400428static bool CipherListsEqual(SSL_CTX *ctx,
David Benjamine11726a2017-04-23 12:14:28 -0400429 const std::vector<ExpectedCipher> &expected) {
David Benjamin70dbf042017-08-08 18:51:37 -0400430 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
431 if (sk_SSL_CIPHER_num(ciphers) != expected.size()) {
David Benjamin1d77e562015-03-22 17:22:08 -0400432 return false;
David Benjamin65226252015-02-05 16:49:47 -0500433 }
434
David Benjamine11726a2017-04-23 12:14:28 -0400435 for (size_t i = 0; i < expected.size(); i++) {
David Benjamin70dbf042017-08-08 18:51:37 -0400436 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
David Benjamine11726a2017-04-23 12:14:28 -0400437 if (expected[i].id != SSL_CIPHER_get_id(cipher) ||
David Benjamin70dbf042017-08-08 18:51:37 -0400438 expected[i].in_group_flag != !!SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400439 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400440 }
441 }
442
David Benjamin1d77e562015-03-22 17:22:08 -0400443 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400444}
445
David Benjamine11726a2017-04-23 12:14:28 -0400446TEST(SSLTest, CipherRules) {
447 for (const CipherTest &t : kCipherTests) {
448 SCOPED_TRACE(t.rule);
449 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
450 ASSERT_TRUE(ctx);
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700451
David Benjamine11726a2017-04-23 12:14:28 -0400452 // Test lax mode.
453 ASSERT_TRUE(SSL_CTX_set_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400454 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400455 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400456 << CipherListToString(ctx.get());
David Benjamine11726a2017-04-23 12:14:28 -0400457
458 // Test strict mode.
459 if (t.strict_fail) {
460 EXPECT_FALSE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
461 } else {
462 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400463 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400464 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400465 << CipherListToString(ctx.get());
David Benjaminbb0a17c2014-09-20 15:35:39 -0400466 }
467 }
468
David Benjaminfb974e62015-12-16 19:34:22 -0500469 for (const char *rule : kBadRules) {
David Benjamine11726a2017-04-23 12:14:28 -0400470 SCOPED_TRACE(rule);
471 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
472 ASSERT_TRUE(ctx);
473
474 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), rule));
David Benjaminbb0a17c2014-09-20 15:35:39 -0400475 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400476 }
477
David Benjaminfb974e62015-12-16 19:34:22 -0500478 for (const char *rule : kMustNotIncludeNull) {
David Benjamine11726a2017-04-23 12:14:28 -0400479 SCOPED_TRACE(rule);
480 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
481 ASSERT_TRUE(ctx);
482
483 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400484 for (const SSL_CIPHER *cipher : SSL_CTX_get_ciphers(ctx.get())) {
David Benjamine3bb51c2017-08-22 23:16:02 -0700485 EXPECT_NE(NID_undef, SSL_CIPHER_get_cipher_nid(cipher));
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700486 }
487 }
David Benjaminbb0a17c2014-09-20 15:35:39 -0400488}
David Benjamin2e521212014-07-16 14:37:51 -0400489
David Benjamine11726a2017-04-23 12:14:28 -0400490TEST(SSLTest, CurveRules) {
491 for (const CurveTest &t : kCurveTests) {
492 SCOPED_TRACE(t.rule);
493 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
494 ASSERT_TRUE(ctx);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100495
David Benjamine11726a2017-04-23 12:14:28 -0400496 ASSERT_TRUE(SSL_CTX_set1_curves_list(ctx.get(), t.rule));
497 ASSERT_EQ(t.expected.size(), ctx->supported_group_list_len);
498 for (size_t i = 0; i < t.expected.size(); i++) {
499 EXPECT_EQ(t.expected[i], ctx->supported_group_list[i]);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100500 }
501 }
502
503 for (const char *rule : kBadCurvesLists) {
David Benjamine11726a2017-04-23 12:14:28 -0400504 SCOPED_TRACE(rule);
505 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
506 ASSERT_TRUE(ctx);
507
508 EXPECT_FALSE(SSL_CTX_set1_curves_list(ctx.get(), rule));
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100509 ERR_clear_error();
510 }
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100511}
512
Adam Langley364f7a62016-12-12 10:51:00 -0800513// kOpenSSLSession is a serialized SSL_SESSION.
Adam Langley10f97f32016-07-12 08:09:33 -0700514static const char kOpenSSLSession[] =
Adam Langley364f7a62016-12-12 10:51:00 -0800515 "MIIFqgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700516 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
517 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
518 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
519 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
520 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
521 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
522 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
523 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
524 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
525 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
526 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
527 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
528 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
529 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
530 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
531 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
532 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
533 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
534 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
535 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
536 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
537 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
538 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
539 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
540 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
541 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
542 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
543 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
544 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
Adam Langley364f7a62016-12-12 10:51:00 -0800545 "i4gv7Y5oliyntgMBAQA=";
Adam Langley10f97f32016-07-12 08:09:33 -0700546
547// kCustomSession is a custom serialized SSL_SESSION generated by
548// filling in missing fields from |kOpenSSLSession|. This includes
549// providing |peer_sha256|, so |peer| is not serialized.
550static const char kCustomSession[] =
David Benjamina8614602017-09-06 15:40:19 -0400551 "MIIBZAIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700552 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
David Benjamina8614602017-09-06 15:40:19 -0400553 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUqAcEBXdvcmxkqQUCAwGJwKqBpwSB"
554 "pBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38"
555 "VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd"
556 "3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hg"
557 "b+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYGBgYGBgYGBgYGBgYGBgYGBgYG"
558 "BgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
Adam Langley10f97f32016-07-12 08:09:33 -0700559
560// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
561static const char kBoringSSLSession[] =
562 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
563 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
564 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
565 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
566 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
567 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
568 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
569 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
570 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
571 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
572 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
573 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
574 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
575 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
576 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
577 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
578 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
579 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
580 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
581 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
582 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
583 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
584 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
585 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
586 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
587 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
588 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
589 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
590 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
591 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
592 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
593 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
594 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
595 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
596 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
597 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
598 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
599 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
600 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
601 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
602 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
603 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
604 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
605 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
606 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
607 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
608 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
609 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
610 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
611 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
612 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
613 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
614 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
615 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
616 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
617 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
618 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
619 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
620 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
621 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
622 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
623 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
624 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
625 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
626 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
627 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
628 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
629 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
630 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
631 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
632 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
633 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
634 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
635 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
636 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
637 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
638 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
639 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
640 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
641 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
642 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
643 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
644 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
645 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
646 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
647 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
648 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
649 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
650 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
651 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
652 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
653 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
654 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
655 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
656 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
657
658// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
659// the final (optional) element of |kCustomSession| with tag number 30.
660static const char kBadSessionExtraField[] =
661 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
662 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
663 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
664 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
665 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
666 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
667 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
668 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
669
670// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
671// the version of |kCustomSession| with 2.
672static const char kBadSessionVersion[] =
673 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
674 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
675 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
676 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
677 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
678 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
679 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
680 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
681
682// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
683// appended.
684static const char kBadSessionTrailingData[] =
685 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
686 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
687 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
688 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
689 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
690 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
691 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
692 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
693
David Benjamin1d77e562015-03-22 17:22:08 -0400694static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400695 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400696 if (!EVP_DecodedLength(&len, strlen(in))) {
697 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400698 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400699 }
700
David Benjamin1d77e562015-03-22 17:22:08 -0400701 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800702 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400703 strlen(in))) {
704 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400705 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400706 }
David Benjamin1d77e562015-03-22 17:22:08 -0400707 out->resize(len);
708 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400709}
710
David Benjamin1d77e562015-03-22 17:22:08 -0400711static bool TestSSL_SESSIONEncoding(const char *input_b64) {
David Benjamin751e8892014-10-19 00:59:36 -0400712 const uint8_t *cptr;
713 uint8_t *ptr;
David Benjamin751e8892014-10-19 00:59:36 -0400714
David Benjamin1d77e562015-03-22 17:22:08 -0400715 // Decode the input.
716 std::vector<uint8_t> input;
717 if (!DecodeBase64(&input, input_b64)) {
718 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400719 }
720
David Benjamin1d77e562015-03-22 17:22:08 -0400721 // Verify the SSL_SESSION decodes.
Adam Langley46db7af2017-02-01 15:49:37 -0800722 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
723 if (!ssl_ctx) {
724 return false;
725 }
726 bssl::UniquePtr<SSL_SESSION> session(
727 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
David Benjaminfd67aa82015-06-15 19:41:48 -0400728 if (!session) {
729 fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400730 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400731 }
732
David Benjamin1d77e562015-03-22 17:22:08 -0400733 // Verify the SSL_SESSION encoding round-trips.
734 size_t encoded_len;
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700735 bssl::UniquePtr<uint8_t> encoded;
David Benjamin1d77e562015-03-22 17:22:08 -0400736 uint8_t *encoded_raw;
737 if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
David Benjamin3cac4502014-10-21 01:46:30 -0400738 fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400739 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400740 }
David Benjamin1d77e562015-03-22 17:22:08 -0400741 encoded.reset(encoded_raw);
742 if (encoded_len != input.size() ||
David Benjamin17cf2cb2016-12-13 01:07:13 -0500743 OPENSSL_memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin3cac4502014-10-21 01:46:30 -0400744 fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
Sigbjorn Vik2b23d242015-06-29 15:07:26 +0200745 hexdump(stderr, "Before: ", input.data(), input.size());
746 hexdump(stderr, "After: ", encoded_raw, encoded_len);
David Benjamin1d77e562015-03-22 17:22:08 -0400747 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400748 }
David Benjamin3cac4502014-10-21 01:46:30 -0400749
David Benjaminfd67aa82015-06-15 19:41:48 -0400750 // Verify the SSL_SESSION also decodes with the legacy API.
David Benjaminef14b2d2015-11-11 14:01:27 -0800751 cptr = input.data();
David Benjaminfd67aa82015-06-15 19:41:48 -0400752 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
David Benjaminef14b2d2015-11-11 14:01:27 -0800753 if (!session || cptr != input.data() + input.size()) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400754 fprintf(stderr, "d2i_SSL_SESSION failed\n");
755 return false;
756 }
757
David Benjamin1d77e562015-03-22 17:22:08 -0400758 // Verify the SSL_SESSION encoding round-trips via the legacy API.
759 int len = i2d_SSL_SESSION(session.get(), NULL);
760 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400761 fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400762 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400763 }
764
David Benjamin1d77e562015-03-22 17:22:08 -0400765 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
766 if (!encoded) {
David Benjamin751e8892014-10-19 00:59:36 -0400767 fprintf(stderr, "malloc failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400768 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400769 }
David Benjamin1d77e562015-03-22 17:22:08 -0400770
771 ptr = encoded.get();
772 len = i2d_SSL_SESSION(session.get(), &ptr);
773 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400774 fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400775 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400776 }
David Benjamin1d77e562015-03-22 17:22:08 -0400777 if (ptr != encoded.get() + input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400778 fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400779 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400780 }
David Benjamin17cf2cb2016-12-13 01:07:13 -0500781 if (OPENSSL_memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin751e8892014-10-19 00:59:36 -0400782 fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400783 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400784 }
785
David Benjamin1d77e562015-03-22 17:22:08 -0400786 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400787}
788
David Benjaminf297e022015-05-28 19:55:29 -0400789static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
790 std::vector<uint8_t> input;
791 if (!DecodeBase64(&input, input_b64)) {
792 return false;
793 }
794
795 // Verify that the SSL_SESSION fails to decode.
Adam Langley46db7af2017-02-01 15:49:37 -0800796 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
797 if (!ssl_ctx) {
798 return false;
799 }
800 bssl::UniquePtr<SSL_SESSION> session(
801 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
David Benjaminf297e022015-05-28 19:55:29 -0400802 if (session) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400803 fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
David Benjaminf297e022015-05-28 19:55:29 -0400804 return false;
805 }
806 ERR_clear_error();
807 return true;
808}
809
David Benjamin321fcdc2017-04-24 11:42:42 -0400810static void ExpectDefaultVersion(uint16_t min_version, uint16_t max_version,
811 const SSL_METHOD *(*method)(void)) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700812 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
David Benjamin321fcdc2017-04-24 11:42:42 -0400813 ASSERT_TRUE(ctx);
David Benjaminfc08dfc2017-06-20 14:39:32 -0400814 EXPECT_EQ(min_version, ctx->conf_min_version);
815 EXPECT_EQ(max_version, ctx->conf_max_version);
David Benjamin321fcdc2017-04-24 11:42:42 -0400816}
817
818TEST(SSLTest, DefaultVersion) {
819 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
820 ExpectDefaultVersion(TLS1_VERSION, TLS1_2_VERSION, &TLS_method);
821 ExpectDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method);
822 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method);
823 ExpectDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method);
824 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method);
825 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method);
826 ExpectDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method);
David Benjamin82c9e902014-12-12 15:55:27 -0500827}
828
David Benjamin348f0d82017-08-10 16:06:27 -0400829TEST(SSLTest, CipherProperties) {
David Benjamin6fff3862017-06-21 21:07:04 -0400830 static const struct {
831 int id;
832 const char *standard_name;
David Benjamin348f0d82017-08-10 16:06:27 -0400833 int cipher_nid;
834 int digest_nid;
835 int kx_nid;
836 int auth_nid;
David Benjaminb1b76ae2017-09-21 17:03:34 -0400837 int prf_nid;
David Benjamin6fff3862017-06-21 21:07:04 -0400838 } kTests[] = {
David Benjamin348f0d82017-08-10 16:06:27 -0400839 {
840 SSL3_CK_RSA_DES_192_CBC3_SHA,
841 "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
842 NID_des_ede3_cbc,
843 NID_sha1,
844 NID_kx_rsa,
845 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400846 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400847 },
848 {
849 TLS1_CK_RSA_WITH_AES_128_SHA,
850 "TLS_RSA_WITH_AES_128_CBC_SHA",
851 NID_aes_128_cbc,
852 NID_sha1,
853 NID_kx_rsa,
854 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400855 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400856 },
857 {
858 TLS1_CK_PSK_WITH_AES_256_CBC_SHA,
859 "TLS_PSK_WITH_AES_256_CBC_SHA",
860 NID_aes_256_cbc,
861 NID_sha1,
862 NID_kx_psk,
863 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400864 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400865 },
866 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400867 TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA,
868 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
David Benjamin348f0d82017-08-10 16:06:27 -0400869 NID_aes_128_cbc,
David Benjamin6e678ee2018-04-16 19:54:42 -0400870 NID_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400871 NID_kx_ecdhe,
872 NID_auth_rsa,
David Benjamin6e678ee2018-04-16 19:54:42 -0400873 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400874 },
875 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400876 TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA,
877 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
David Benjamin348f0d82017-08-10 16:06:27 -0400878 NID_aes_256_cbc,
David Benjamin6e678ee2018-04-16 19:54:42 -0400879 NID_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400880 NID_kx_ecdhe,
881 NID_auth_rsa,
David Benjamin6e678ee2018-04-16 19:54:42 -0400882 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400883 },
884 {
885 TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
886 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
887 NID_aes_128_gcm,
888 NID_undef,
889 NID_kx_ecdhe,
890 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400891 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400892 },
893 {
894 TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
895 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
896 NID_aes_128_gcm,
897 NID_undef,
898 NID_kx_ecdhe,
899 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400900 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400901 },
902 {
903 TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
904 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
905 NID_aes_256_gcm,
906 NID_undef,
907 NID_kx_ecdhe,
908 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400909 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -0400910 },
911 {
912 TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
913 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
914 NID_aes_128_cbc,
915 NID_sha1,
916 NID_kx_ecdhe,
917 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400918 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400919 },
920 {
921 TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
922 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
923 NID_chacha20_poly1305,
924 NID_undef,
925 NID_kx_ecdhe,
926 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400927 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400928 },
929 {
930 TLS1_CK_AES_256_GCM_SHA384,
931 "TLS_AES_256_GCM_SHA384",
932 NID_aes_256_gcm,
933 NID_undef,
934 NID_kx_any,
935 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400936 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -0400937 },
938 {
939 TLS1_CK_AES_128_GCM_SHA256,
940 "TLS_AES_128_GCM_SHA256",
941 NID_aes_128_gcm,
942 NID_undef,
943 NID_kx_any,
944 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400945 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400946 },
947 {
948 TLS1_CK_CHACHA20_POLY1305_SHA256,
949 "TLS_CHACHA20_POLY1305_SHA256",
950 NID_chacha20_poly1305,
951 NID_undef,
952 NID_kx_any,
953 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400954 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400955 },
David Benjamin6fff3862017-06-21 21:07:04 -0400956 };
David Benjamin65226252015-02-05 16:49:47 -0500957
David Benjamin6fff3862017-06-21 21:07:04 -0400958 for (const auto &t : kTests) {
959 SCOPED_TRACE(t.standard_name);
David Benjamine11726a2017-04-23 12:14:28 -0400960
961 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(t.id & 0xffff);
962 ASSERT_TRUE(cipher);
David Benjamin6fff3862017-06-21 21:07:04 -0400963 EXPECT_STREQ(t.standard_name, SSL_CIPHER_standard_name(cipher));
964
David Benjamine11726a2017-04-23 12:14:28 -0400965 bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
966 ASSERT_TRUE(rfc_name);
David Benjamin6fff3862017-06-21 21:07:04 -0400967 EXPECT_STREQ(t.standard_name, rfc_name.get());
David Benjamin348f0d82017-08-10 16:06:27 -0400968
969 EXPECT_EQ(t.cipher_nid, SSL_CIPHER_get_cipher_nid(cipher));
970 EXPECT_EQ(t.digest_nid, SSL_CIPHER_get_digest_nid(cipher));
971 EXPECT_EQ(t.kx_nid, SSL_CIPHER_get_kx_nid(cipher));
972 EXPECT_EQ(t.auth_nid, SSL_CIPHER_get_auth_nid(cipher));
David Benjaminb1b76ae2017-09-21 17:03:34 -0400973 EXPECT_EQ(t.prf_nid, SSL_CIPHER_get_prf_nid(cipher));
David Benjamin65226252015-02-05 16:49:47 -0500974 }
David Benjamin65226252015-02-05 16:49:47 -0500975}
976
Steven Valdeza833c352016-11-01 13:39:36 -0400977// CreateSessionWithTicket returns a sample |SSL_SESSION| with the specified
978// version and ticket length or nullptr on failure.
979static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(uint16_t version,
980 size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -0400981 std::vector<uint8_t> der;
982 if (!DecodeBase64(&der, kOpenSSLSession)) {
983 return nullptr;
984 }
Adam Langley46db7af2017-02-01 15:49:37 -0800985
986 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
987 if (!ssl_ctx) {
988 return nullptr;
989 }
Steven Valdeza833c352016-11-01 13:39:36 -0400990 bssl::UniquePtr<SSL_SESSION> session(
Adam Langley46db7af2017-02-01 15:49:37 -0800991 SSL_SESSION_from_bytes(der.data(), der.size(), ssl_ctx.get()));
David Benjamin422fe082015-07-21 22:03:43 -0400992 if (!session) {
993 return nullptr;
994 }
995
Steven Valdeza833c352016-11-01 13:39:36 -0400996 session->ssl_version = version;
997
David Benjamin422fe082015-07-21 22:03:43 -0400998 // Swap out the ticket for a garbage one.
999 OPENSSL_free(session->tlsext_tick);
1000 session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len));
1001 if (session->tlsext_tick == nullptr) {
1002 return nullptr;
1003 }
David Benjamin17cf2cb2016-12-13 01:07:13 -05001004 OPENSSL_memset(session->tlsext_tick, 'a', ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -04001005 session->tlsext_ticklen = ticket_len;
David Benjamin1269ddd2015-10-18 15:18:55 -04001006
1007 // Fix up the timeout.
David Benjamin9b63f292016-11-15 00:44:05 -05001008#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
1009 session->time = 1234;
1010#else
David Benjamin1269ddd2015-10-18 15:18:55 -04001011 session->time = time(NULL);
David Benjamin9b63f292016-11-15 00:44:05 -05001012#endif
David Benjamin422fe082015-07-21 22:03:43 -04001013 return session;
1014}
1015
David Benjaminafc64de2016-07-19 17:12:41 +02001016static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001017 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +02001018 if (!bio) {
1019 return false;
1020 }
1021 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -04001022 BIO_up_ref(bio.get());
1023 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +02001024 int ret = SSL_connect(ssl);
1025 if (ret > 0) {
1026 // SSL_connect should fail without a BIO to write to.
1027 return false;
1028 }
1029 ERR_clear_error();
1030
1031 const uint8_t *client_hello;
1032 size_t client_hello_len;
1033 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
1034 return false;
1035 }
1036 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
1037 return true;
1038}
1039
Steven Valdeza833c352016-11-01 13:39:36 -04001040// GetClientHelloLen creates a client SSL connection with the specified version
1041// and ticket length. It returns the length of the ClientHello, not including
1042// the record header, on success and zero on error.
1043static size_t GetClientHelloLen(uint16_t max_version, uint16_t session_version,
1044 size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001045 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Steven Valdeza833c352016-11-01 13:39:36 -04001046 bssl::UniquePtr<SSL_SESSION> session =
1047 CreateSessionWithTicket(session_version, ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -04001048 if (!ctx || !session) {
1049 return 0;
1050 }
Steven Valdeza833c352016-11-01 13:39:36 -04001051
1052 // Set a one-element cipher list so the baseline ClientHello is unpadded.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001053 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
Steven Valdez2c62fe92016-10-14 12:08:12 -04001054 if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -08001055 !SSL_set_strict_cipher_list(ssl.get(), "ECDHE-RSA-AES128-GCM-SHA256") ||
Steven Valdeza833c352016-11-01 13:39:36 -04001056 !SSL_set_max_proto_version(ssl.get(), max_version)) {
David Benjamin422fe082015-07-21 22:03:43 -04001057 return 0;
1058 }
Steven Valdeza833c352016-11-01 13:39:36 -04001059
David Benjaminafc64de2016-07-19 17:12:41 +02001060 std::vector<uint8_t> client_hello;
1061 if (!GetClientHello(ssl.get(), &client_hello) ||
1062 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -04001063 return 0;
1064 }
Steven Valdeza833c352016-11-01 13:39:36 -04001065
David Benjaminafc64de2016-07-19 17:12:41 +02001066 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -04001067}
1068
1069struct PaddingTest {
1070 size_t input_len, padded_len;
1071};
1072
1073static const PaddingTest kPaddingTests[] = {
1074 // ClientHellos of length below 0x100 do not require padding.
1075 {0xfe, 0xfe},
1076 {0xff, 0xff},
1077 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
1078 {0x100, 0x200},
1079 {0x123, 0x200},
1080 {0x1fb, 0x200},
1081 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
1082 // padding extension takes a minimum of four bytes plus one required content
1083 // byte. (To work around yet more server bugs, we avoid empty final
1084 // extensions.)
1085 {0x1fc, 0x201},
1086 {0x1fd, 0x202},
1087 {0x1fe, 0x203},
1088 {0x1ff, 0x204},
1089 // Finally, larger ClientHellos need no padding.
1090 {0x200, 0x200},
1091 {0x201, 0x201},
1092};
1093
Steven Valdeza833c352016-11-01 13:39:36 -04001094static bool TestPaddingExtension(uint16_t max_version,
1095 uint16_t session_version) {
David Benjamin422fe082015-07-21 22:03:43 -04001096 // Sample a baseline length.
Steven Valdeza833c352016-11-01 13:39:36 -04001097 size_t base_len = GetClientHelloLen(max_version, session_version, 1);
David Benjamin422fe082015-07-21 22:03:43 -04001098 if (base_len == 0) {
1099 return false;
1100 }
1101
1102 for (const PaddingTest &test : kPaddingTests) {
1103 if (base_len > test.input_len) {
Steven Valdeza833c352016-11-01 13:39:36 -04001104 fprintf(stderr,
1105 "Baseline ClientHello too long (max_version = %04x, "
1106 "session_version = %04x).\n",
1107 max_version, session_version);
David Benjamin422fe082015-07-21 22:03:43 -04001108 return false;
1109 }
1110
Steven Valdeza833c352016-11-01 13:39:36 -04001111 size_t padded_len = GetClientHelloLen(max_version, session_version,
1112 1 + test.input_len - base_len);
David Benjamin422fe082015-07-21 22:03:43 -04001113 if (padded_len != test.padded_len) {
Steven Valdeza833c352016-11-01 13:39:36 -04001114 fprintf(stderr,
1115 "%u-byte ClientHello padded to %u bytes, not %u (max_version = "
1116 "%04x, session_version = %04x).\n",
David Benjamin422fe082015-07-21 22:03:43 -04001117 static_cast<unsigned>(test.input_len),
1118 static_cast<unsigned>(padded_len),
Steven Valdeza833c352016-11-01 13:39:36 -04001119 static_cast<unsigned>(test.padded_len), max_version,
1120 session_version);
David Benjamin422fe082015-07-21 22:03:43 -04001121 return false;
1122 }
1123 }
Steven Valdeza833c352016-11-01 13:39:36 -04001124
David Benjamin422fe082015-07-21 22:03:43 -04001125 return true;
1126}
1127
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001128static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001129 static const char kCertPEM[] =
1130 "-----BEGIN CERTIFICATE-----\n"
1131 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1132 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1133 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1134 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1135 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1136 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1137 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1138 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1139 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1140 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1141 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1142 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1143 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1144 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001145 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
David Benjamin1444c3a2016-12-20 17:23:11 -05001146 return bssl::UniquePtr<X509>(
1147 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjaminde942382016-02-11 12:02:01 -05001148}
1149
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001150static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001151 static const char kKeyPEM[] =
1152 "-----BEGIN RSA PRIVATE KEY-----\n"
1153 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1154 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1155 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1156 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1157 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1158 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1159 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1160 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1161 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1162 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1163 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1164 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1165 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1166 "-----END RSA PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001167 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1168 return bssl::UniquePtr<EVP_PKEY>(
David Benjaminde942382016-02-11 12:02:01 -05001169 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1170}
1171
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001172static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001173 static const char kCertPEM[] =
1174 "-----BEGIN CERTIFICATE-----\n"
1175 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1176 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1177 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1178 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1179 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1180 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1181 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1182 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1183 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1184 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1185 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001186 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1187 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjamin0fc37ef2016-08-17 15:29:46 -04001188}
1189
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001190static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001191 static const char kKeyPEM[] =
1192 "-----BEGIN PRIVATE KEY-----\n"
1193 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1194 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1195 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1196 "-----END PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001197 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1198 return bssl::UniquePtr<EVP_PKEY>(
David Benjamin0fc37ef2016-08-17 15:29:46 -04001199 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1200}
1201
Adam Langleyd04ca952017-02-28 11:26:51 -08001202static bssl::UniquePtr<CRYPTO_BUFFER> BufferFromPEM(const char *pem) {
1203 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1204 char *name, *header;
1205 uint8_t *data;
1206 long data_len;
1207 if (!PEM_read_bio(bio.get(), &name, &header, &data,
1208 &data_len)) {
1209 return nullptr;
1210 }
1211 OPENSSL_free(name);
1212 OPENSSL_free(header);
1213
1214 auto ret = bssl::UniquePtr<CRYPTO_BUFFER>(
1215 CRYPTO_BUFFER_new(data, data_len, nullptr));
1216 OPENSSL_free(data);
1217 return ret;
1218}
1219
1220static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestCertificateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001221 static const char kCertPEM[] =
1222 "-----BEGIN CERTIFICATE-----\n"
1223 "MIIC0jCCAbqgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQiBD\n"
1224 "QTAeFw0xNjAyMjgyMDI3MDNaFw0yNjAyMjUyMDI3MDNaMBgxFjAUBgNVBAMMDUNs\n"
1225 "aWVudCBDZXJ0IEEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRvaz8\n"
1226 "CC/cshpCafJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/\n"
1227 "kLRcH89M/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3\n"
1228 "tHb+xs2PSs8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+c\n"
1229 "IDs2rQ+lP7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1\n"
1230 "z7C8jU50Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9V\n"
1231 "iLeXANgZi+Xx9KgfAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI\n"
1232 "KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBFEVbmYl+2RtNw\n"
1233 "rDftRDF1v2QUbcN2ouSnQDHxeDQdSgasLzT3ui8iYu0Rw2WWcZ0DV5e0ztGPhWq7\n"
1234 "AO0B120aFRMOY+4+bzu9Q2FFkQqc7/fKTvTDzIJI5wrMnFvUfzzvxh3OHWMYSs/w\n"
1235 "giq33hTKeHEq6Jyk3btCny0Ycecyc3yGXH10sizUfiHlhviCkDuESk8mFDwDDzqW\n"
1236 "ZF0IipzFbEDHoIxLlm3GQxpiLoEV4k8KYJp3R5KBLFyxM6UGPz8h72mIPCJp2RuK\n"
1237 "MYgF91UDvVzvnYm6TfseM2+ewKirC00GOrZ7rEcFvtxnKSqYf4ckqfNdSU1Y+RRC\n"
1238 "1ngWZ7Ih\n"
1239 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001240 return BufferFromPEM(kCertPEM);
David Benjamin1444c3a2016-12-20 17:23:11 -05001241}
1242
Adam Langleyd04ca952017-02-28 11:26:51 -08001243static bssl::UniquePtr<X509> X509FromBuffer(
1244 bssl::UniquePtr<CRYPTO_BUFFER> buffer) {
1245 if (!buffer) {
1246 return nullptr;
1247 }
1248 const uint8_t *derp = CRYPTO_BUFFER_data(buffer.get());
1249 return bssl::UniquePtr<X509>(
1250 d2i_X509(NULL, &derp, CRYPTO_BUFFER_len(buffer.get())));
1251}
1252
1253static bssl::UniquePtr<X509> GetChainTestCertificate() {
1254 return X509FromBuffer(GetChainTestCertificateBuffer());
1255}
1256
1257static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestIntermediateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001258 static const char kCertPEM[] =
1259 "-----BEGIN CERTIFICATE-----\n"
1260 "MIICwjCCAaqgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS\n"
1261 "b290IENBMB4XDTE2MDIyODIwMjcwM1oXDTI2MDIyNTIwMjcwM1owDzENMAsGA1UE\n"
1262 "AwwEQiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALsSCYmDip2D\n"
1263 "GkjFxw7ykz26JSjELkl6ArlYjFJ3aT/SCh8qbS4gln7RH8CPBd78oFdfhIKQrwtZ\n"
1264 "3/q21ykD9BAS3qHe2YdcJfm8/kWAy5DvXk6NXU4qX334KofBAEpgdA/igEFq1P1l\n"
1265 "HAuIfZCpMRfT+i5WohVsGi8f/NgpRvVaMONLNfgw57mz1lbtFeBEISmX0kbsuJxF\n"
1266 "Qj/Bwhi5/0HAEXG8e7zN4cEx0yPRvmOATRdVb/8dW2pwOHRJq9R5M0NUkIsTSnL7\n"
1267 "6N/z8hRAHMsV3IudC5Yd7GXW1AGu9a+iKU+Q4xcZCoj0DC99tL4VKujrV1kAeqsM\n"
1268 "cz5/dKzi6+cCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
1269 "AQYwDQYJKoZIhvcNAQELBQADggEBAIIeZiEeNhWWQ8Y4D+AGDwqUUeG8NjCbKrXQ\n"
1270 "BlHg5wZ8xftFaiP1Dp/UAezmx2LNazdmuwrYB8lm3FVTyaPDTKEGIPS4wJKHgqH1\n"
1271 "QPDhqNm85ey7TEtI9oYjsNim/Rb+iGkIAMXaxt58SzxbjvP0kMr1JfJIZbic9vye\n"
1272 "NwIspMFIpP3FB8ywyu0T0hWtCQgL4J47nigCHpOu58deP88fS/Nyz/fyGVWOZ76b\n"
1273 "WhWwgM3P3X95fQ3d7oFPR/bVh0YV+Cf861INwplokXgXQ3/TCQ+HNXeAMWn3JLWv\n"
1274 "XFwk8owk9dq/kQGdndGgy3KTEW4ctPX5GNhf3LJ9Q7dLji4ReQ4=\n"
1275 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001276 return BufferFromPEM(kCertPEM);
1277}
1278
1279static bssl::UniquePtr<X509> GetChainTestIntermediate() {
1280 return X509FromBuffer(GetChainTestIntermediateBuffer());
David Benjamin1444c3a2016-12-20 17:23:11 -05001281}
1282
1283static bssl::UniquePtr<EVP_PKEY> GetChainTestKey() {
1284 static const char kKeyPEM[] =
1285 "-----BEGIN PRIVATE KEY-----\n"
1286 "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRvaz8CC/cshpC\n"
1287 "afJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/kLRcH89M\n"
1288 "/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3tHb+xs2P\n"
1289 "Ss8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+cIDs2rQ+l\n"
1290 "P7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1z7C8jU50\n"
1291 "Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9ViLeXANgZ\n"
1292 "i+Xx9KgfAgMBAAECggEBAK0VjSJzkyPaamcyTVSWjo7GdaBGcK60lk657RjR+lK0\n"
1293 "YJ7pkej4oM2hdsVZFsP8Cs4E33nXLa/0pDsRov/qrp0WQm2skwqGMC1I/bZ0WRPk\n"
1294 "wHaDrBBfESWnJDX/AGpVtlyOjPmgmK6J2usMPihQUDkKdAYrVWJePrMIxt1q6BMe\n"
1295 "iczs3qriMmtY3bUc4UyUwJ5fhDLjshHvfuIpYQyI6EXZM6dZksn9LylXJnigY6QJ\n"
1296 "HxOYO0BDwOsZ8yQ8J8afLk88i0GizEkgE1z3REtQUwgWfxr1WV/ud+T6/ZhSAgH9\n"
1297 "042mQvSFZnIUSEsmCvjhWuAunfxHKCTcAoYISWfzWpkCgYEA7gpf3HHU5Tn+CgUn\n"
1298 "1X5uGpG3DmcMgfeGgs2r2f/IIg/5Ac1dfYILiybL1tN9zbyLCJfcbFpWBc9hJL6f\n"
1299 "CPc5hUiwWFJqBJewxQkC1Ae/HakHbip+IZ+Jr0842O4BAArvixk4Lb7/N2Ct9sTE\n"
1300 "NJO6RtK9lbEZ5uK61DglHy8CS2UCgYEA4ZC1o36kPAMQBggajgnucb2yuUEelk0f\n"
1301 "AEr+GI32MGE+93xMr7rAhBoqLg4AITyIfEnOSQ5HwagnIHonBbv1LV/Gf9ursx8Z\n"
1302 "YOGbvT8zzzC+SU1bkDzdjAYnFQVGIjMtKOBJ3K07++ypwX1fr4QsQ8uKL8WSOWwt\n"
1303 "Z3Bym6XiZzMCgYADnhy+2OwHX85AkLt+PyGlPbmuelpyTzS4IDAQbBa6jcuW/2wA\n"
1304 "UE2km75VUXmD+u2R/9zVuLm99NzhFhSMqlUxdV1YukfqMfP5yp1EY6m/5aW7QuIP\n"
1305 "2MDa7TVL9rIFMiVZ09RKvbBbQxjhuzPQKL6X/PPspnhiTefQ+dl2k9xREQKBgHDS\n"
1306 "fMfGNEeAEKezrfSVqxphE9/tXms3L+ZpnCaT+yu/uEr5dTIAawKoQ6i9f/sf1/Sy\n"
1307 "xedsqR+IB+oKrzIDDWMgoJybN4pkZ8E5lzhVQIjFjKgFdWLzzqyW9z1gYfABQPlN\n"
1308 "FiS20WX0vgP1vcKAjdNrHzc9zyHBpgQzDmAj3NZZAoGBAI8vKCKdH7w3aL5CNkZQ\n"
1309 "2buIeWNA2HZazVwAGG5F2TU/LmXfRKnG6dX5bkU+AkBZh56jNZy//hfFSewJB4Kk\n"
1310 "buB7ERSdaNbO21zXt9FEA3+z0RfMd/Zv2vlIWOSB5nzl/7UKti3sribK6s9ZVLfi\n"
1311 "SxpiPQ8d/hmSGwn4ksrWUsJD\n"
1312 "-----END PRIVATE KEY-----\n";
1313 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1314 return bssl::UniquePtr<EVP_PKEY>(
1315 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1316}
1317
David Benjaminc79ae7a2017-08-29 16:09:44 -04001318// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
1319// before configuring as a server.
1320TEST(SSLTest, ClientCAList) {
1321 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1322 ASSERT_TRUE(ctx);
1323 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1324 ASSERT_TRUE(ssl);
1325
1326 bssl::UniquePtr<X509_NAME> name(X509_NAME_new());
1327 ASSERT_TRUE(name);
1328
1329 bssl::UniquePtr<X509_NAME> name_dup(X509_NAME_dup(name.get()));
1330 ASSERT_TRUE(name_dup);
1331
1332 bssl::UniquePtr<STACK_OF(X509_NAME)> stack(sk_X509_NAME_new_null());
1333 ASSERT_TRUE(stack);
1334
1335 ASSERT_TRUE(sk_X509_NAME_push(stack.get(), name_dup.get()));
1336 name_dup.release();
1337
1338 // |SSL_set_client_CA_list| takes ownership.
1339 SSL_set_client_CA_list(ssl.get(), stack.release());
1340
1341 STACK_OF(X509_NAME) *result = SSL_get_client_CA_list(ssl.get());
1342 ASSERT_TRUE(result);
1343 ASSERT_EQ(1u, sk_X509_NAME_num(result));
1344 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(result, 0), name.get()));
1345}
1346
1347TEST(SSLTest, AddClientCA) {
1348 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1349 ASSERT_TRUE(ctx);
1350 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1351 ASSERT_TRUE(ssl);
1352
1353 bssl::UniquePtr<X509> cert1 = GetTestCertificate();
1354 bssl::UniquePtr<X509> cert2 = GetChainTestCertificate();
1355 ASSERT_TRUE(cert1 && cert2);
1356 X509_NAME *name1 = X509_get_subject_name(cert1.get());
1357 X509_NAME *name2 = X509_get_subject_name(cert2.get());
1358
1359 EXPECT_EQ(0u, sk_X509_NAME_num(SSL_get_client_CA_list(ssl.get())));
1360
1361 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1362 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert2.get()));
1363
1364 STACK_OF(X509_NAME) *list = SSL_get_client_CA_list(ssl.get());
1365 ASSERT_EQ(2u, 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
1369 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1370
1371 list = SSL_get_client_CA_list(ssl.get());
1372 ASSERT_EQ(3u, sk_X509_NAME_num(list));
1373 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1374 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1375 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 2), name1));
1376}
1377
1378static void AppendSession(SSL_SESSION *session, void *arg) {
1379 std::vector<SSL_SESSION*> *out =
1380 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
1381 out->push_back(session);
1382}
1383
1384// CacheEquals returns true if |ctx|'s session cache consists of |expected|, in
1385// order.
1386static bool CacheEquals(SSL_CTX *ctx,
1387 const std::vector<SSL_SESSION*> &expected) {
1388 // Check the linked list.
1389 SSL_SESSION *ptr = ctx->session_cache_head;
1390 for (SSL_SESSION *session : expected) {
1391 if (ptr != session) {
1392 return false;
1393 }
1394 // TODO(davidben): This is an absurd way to denote the end of the list.
1395 if (ptr->next ==
1396 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
1397 ptr = nullptr;
1398 } else {
1399 ptr = ptr->next;
1400 }
1401 }
1402 if (ptr != nullptr) {
1403 return false;
1404 }
1405
1406 // Check the hash table.
1407 std::vector<SSL_SESSION*> actual, expected_copy;
David Benjamin9eaa3bd2017-09-27 17:03:54 -04001408 lh_SSL_SESSION_doall_arg(ctx->sessions, AppendSession, &actual);
David Benjaminc79ae7a2017-08-29 16:09:44 -04001409 expected_copy = expected;
1410
1411 std::sort(actual.begin(), actual.end());
1412 std::sort(expected_copy.begin(), expected_copy.end());
1413
1414 return actual == expected_copy;
1415}
1416
1417static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
1418 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
1419 if (!ssl_ctx) {
1420 return nullptr;
1421 }
1422 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new(ssl_ctx.get()));
1423 if (!ret) {
1424 return nullptr;
1425 }
1426
1427 ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
1428 OPENSSL_memset(ret->session_id, 0, ret->session_id_length);
1429 OPENSSL_memcpy(ret->session_id, &number, sizeof(number));
1430 return ret;
1431}
1432
1433// Test that the internal session cache behaves as expected.
1434TEST(SSLTest, InternalSessionCache) {
1435 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1436 ASSERT_TRUE(ctx);
1437
1438 // Prepare 10 test sessions.
1439 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
1440 for (int i = 0; i < 10; i++) {
1441 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
1442 ASSERT_TRUE(session);
1443 sessions.push_back(std::move(session));
1444 }
1445
1446 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1447
1448 // Insert all the test sessions.
1449 for (const auto &session : sessions) {
1450 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), session.get()));
1451 }
1452
1453 // Only the last five should be in the list.
1454 ASSERT_TRUE(CacheEquals(
1455 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
1456 sessions[6].get(), sessions[5].get()}));
1457
1458 // Inserting an element already in the cache should fail and leave the cache
1459 // unchanged.
1460 ASSERT_FALSE(SSL_CTX_add_session(ctx.get(), sessions[7].get()));
1461 ASSERT_TRUE(CacheEquals(
1462 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
1463 sessions[6].get(), sessions[5].get()}));
1464
1465 // Although collisions should be impossible (256-bit session IDs), the cache
1466 // must handle them gracefully.
1467 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
1468 ASSERT_TRUE(collision);
1469 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), collision.get()));
1470 ASSERT_TRUE(CacheEquals(
1471 ctx.get(), {collision.get(), sessions[9].get(), sessions[8].get(),
1472 sessions[6].get(), sessions[5].get()}));
1473
1474 // Removing sessions behaves correctly.
1475 ASSERT_TRUE(SSL_CTX_remove_session(ctx.get(), sessions[6].get()));
1476 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
1477 sessions[8].get(), sessions[5].get()}));
1478
1479 // Removing sessions requires an exact match.
1480 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[0].get()));
1481 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[7].get()));
1482
1483 // The cache remains unchanged.
1484 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
1485 sessions[8].get(), sessions[5].get()}));
1486}
1487
1488static uint16_t EpochFromSequence(uint64_t seq) {
1489 return static_cast<uint16_t>(seq >> 48);
1490}
1491
David Benjamin71dfad42017-07-16 17:27:39 -04001492static const uint8_t kTestName[] = {
1493 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
1494 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
1495 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
1496 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
1497 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
1498 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64,
1499};
1500
David Benjaminb79cc842016-12-07 15:57:14 -05001501static bool CompleteHandshakes(SSL *client, SSL *server) {
1502 // Drive both their handshakes to completion.
1503 for (;;) {
1504 int client_ret = SSL_do_handshake(client);
1505 int client_err = SSL_get_error(client, client_ret);
1506 if (client_err != SSL_ERROR_NONE &&
1507 client_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001508 client_err != SSL_ERROR_WANT_WRITE &&
1509 client_err != SSL_ERROR_PENDING_TICKET) {
David Benjaminb79cc842016-12-07 15:57:14 -05001510 fprintf(stderr, "Client error: %d\n", client_err);
1511 return false;
1512 }
1513
1514 int server_ret = SSL_do_handshake(server);
1515 int server_err = SSL_get_error(server, server_ret);
1516 if (server_err != SSL_ERROR_NONE &&
1517 server_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001518 server_err != SSL_ERROR_WANT_WRITE &&
1519 server_err != SSL_ERROR_PENDING_TICKET) {
David Benjaminb79cc842016-12-07 15:57:14 -05001520 fprintf(stderr, "Server error: %d\n", server_err);
1521 return false;
1522 }
1523
1524 if (client_ret == 1 && server_ret == 1) {
1525 break;
1526 }
1527 }
1528
1529 return true;
1530}
1531
David Benjamina8614602017-09-06 15:40:19 -04001532struct ClientConfig {
1533 SSL_SESSION *session = nullptr;
1534 std::string servername;
1535};
1536
David Benjaminb79cc842016-12-07 15:57:14 -05001537static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client,
1538 bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001539 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
Adam Langleyddb57cf2018-01-26 09:17:53 -08001540 const ClientConfig &config = ClientConfig(),
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001541 bool do_handshake = true,
1542 bool shed_handshake_config = true) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001543 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001544 if (!client || !server) {
1545 return false;
1546 }
1547 SSL_set_connect_state(client.get());
1548 SSL_set_accept_state(server.get());
1549
David Benjamina8614602017-09-06 15:40:19 -04001550 if (config.session) {
1551 SSL_set_session(client.get(), config.session);
1552 }
1553 if (!config.servername.empty() &&
1554 !SSL_set_tlsext_host_name(client.get(), config.servername.c_str())) {
1555 return false;
1556 }
David Benjamina20e5352016-08-02 19:09:41 -04001557
David Benjaminde942382016-02-11 12:02:01 -05001558 BIO *bio1, *bio2;
1559 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1560 return false;
1561 }
1562 // SSL_set_bio takes ownership.
1563 SSL_set_bio(client.get(), bio1, bio1);
1564 SSL_set_bio(server.get(), bio2, bio2);
1565
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001566 SSL_set_shed_handshake_config(client.get(), shed_handshake_config);
1567 SSL_set_shed_handshake_config(server.get(), shed_handshake_config);
1568
Adam Langleyddb57cf2018-01-26 09:17:53 -08001569 if (do_handshake && !CompleteHandshakes(client.get(), server.get())) {
David Benjaminb79cc842016-12-07 15:57:14 -05001570 return false;
David Benjaminde942382016-02-11 12:02:01 -05001571 }
1572
David Benjamin686bb192016-05-10 15:15:41 -04001573 *out_client = std::move(client);
1574 *out_server = std::move(server);
1575 return true;
1576}
1577
David Benjaminc11ea9422017-08-29 16:33:21 -04001578// SSLVersionTest executes its test cases under all available protocol versions.
1579// Test cases call |Connect| to create a connection using context objects with
1580// the protocol version fixed to the current version under test.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001581class SSLVersionTest : public ::testing::TestWithParam<VersionParam> {
1582 protected:
1583 SSLVersionTest() : cert_(GetTestCertificate()), key_(GetTestKey()) {}
1584
1585 void SetUp() { ResetContexts(); }
1586
1587 bssl::UniquePtr<SSL_CTX> CreateContext() const {
1588 const SSL_METHOD *method = is_dtls() ? DTLS_method() : TLS_method();
1589 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
1590 if (!ctx || !SSL_CTX_set_min_proto_version(ctx.get(), version()) ||
1591 !SSL_CTX_set_max_proto_version(ctx.get(), version())) {
1592 return nullptr;
1593 }
1594 return ctx;
David Benjamin0fef3052016-11-18 15:11:10 +09001595 }
David Benjamin686bb192016-05-10 15:15:41 -04001596
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001597 void ResetContexts() {
1598 ASSERT_TRUE(cert_);
1599 ASSERT_TRUE(key_);
1600 client_ctx_ = CreateContext();
1601 ASSERT_TRUE(client_ctx_);
1602 server_ctx_ = CreateContext();
1603 ASSERT_TRUE(server_ctx_);
1604 // Set up a server cert. Client certs can be set up explicitly.
1605 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09001606 }
David Benjamin686bb192016-05-10 15:15:41 -04001607
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001608 bool UseCertAndKey(SSL_CTX *ctx) const {
1609 return SSL_CTX_use_certificate(ctx, cert_.get()) &&
1610 SSL_CTX_use_PrivateKey(ctx, key_.get());
David Benjamin0fef3052016-11-18 15:11:10 +09001611 }
David Benjamin686bb192016-05-10 15:15:41 -04001612
David Benjamina8614602017-09-06 15:40:19 -04001613 bool Connect(const ClientConfig &config = ClientConfig()) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001614 return ConnectClientAndServer(&client_, &server_, client_ctx_.get(),
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001615 server_ctx_.get(), config, true,
1616 shed_handshake_config_);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001617 }
1618
1619 uint16_t version() const { return GetParam().version; }
1620
1621 bool is_dtls() const {
1622 return GetParam().ssl_method == VersionParam::is_dtls;
1623 }
1624
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001625 bool shed_handshake_config_ = true;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001626 bssl::UniquePtr<SSL> client_, server_;
1627 bssl::UniquePtr<SSL_CTX> server_ctx_, client_ctx_;
1628 bssl::UniquePtr<X509> cert_;
1629 bssl::UniquePtr<EVP_PKEY> key_;
1630};
1631
1632INSTANTIATE_TEST_CASE_P(WithVersion, SSLVersionTest,
1633 testing::ValuesIn(kAllVersions),
1634 [](const testing::TestParamInfo<VersionParam> &i) {
1635 return i.param.name;
1636 });
1637
1638TEST_P(SSLVersionTest, SequenceNumber) {
1639 ASSERT_TRUE(Connect());
1640
David Benjamin0fef3052016-11-18 15:11:10 +09001641 // Drain any post-handshake messages to ensure there are no unread records
1642 // on either end.
1643 uint8_t byte = 0;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001644 ASSERT_LE(SSL_read(client_.get(), &byte, 1), 0);
1645 ASSERT_LE(SSL_read(server_.get(), &byte, 1), 0);
David Benjaminde942382016-02-11 12:02:01 -05001646
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001647 uint64_t client_read_seq = SSL_get_read_sequence(client_.get());
1648 uint64_t client_write_seq = SSL_get_write_sequence(client_.get());
1649 uint64_t server_read_seq = SSL_get_read_sequence(server_.get());
1650 uint64_t server_write_seq = SSL_get_write_sequence(server_.get());
Steven Valdez2c62fe92016-10-14 12:08:12 -04001651
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001652 if (is_dtls()) {
David Benjamin0fef3052016-11-18 15:11:10 +09001653 // Both client and server must be at epoch 1.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001654 EXPECT_EQ(EpochFromSequence(client_read_seq), 1);
1655 EXPECT_EQ(EpochFromSequence(client_write_seq), 1);
1656 EXPECT_EQ(EpochFromSequence(server_read_seq), 1);
1657 EXPECT_EQ(EpochFromSequence(server_write_seq), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09001658
1659 // The next record to be written should exceed the largest received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001660 EXPECT_GT(client_write_seq, server_read_seq);
1661 EXPECT_GT(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09001662 } else {
1663 // The next record to be written should equal the next to be received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001664 EXPECT_EQ(client_write_seq, server_read_seq);
1665 EXPECT_EQ(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09001666 }
1667
1668 // Send a record from client to server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001669 EXPECT_EQ(SSL_write(client_.get(), &byte, 1), 1);
1670 EXPECT_EQ(SSL_read(server_.get(), &byte, 1), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09001671
1672 // The client write and server read sequence numbers should have
1673 // incremented.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001674 EXPECT_EQ(client_write_seq + 1, SSL_get_write_sequence(client_.get()));
1675 EXPECT_EQ(server_read_seq + 1, SSL_get_read_sequence(server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05001676}
1677
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001678TEST_P(SSLVersionTest, OneSidedShutdown) {
David Benjamin68f37b72016-11-18 15:14:42 +09001679 // SSL_shutdown is a no-op in DTLS.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001680 if (is_dtls()) {
1681 return;
David Benjamin686bb192016-05-10 15:15:41 -04001682 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001683 ASSERT_TRUE(Connect());
David Benjamin686bb192016-05-10 15:15:41 -04001684
1685 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1686 // one side has shut down.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001687 ASSERT_EQ(SSL_shutdown(client_.get()), 0);
David Benjamin686bb192016-05-10 15:15:41 -04001688
1689 // Reading from the server should consume the EOF.
1690 uint8_t byte;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001691 ASSERT_EQ(SSL_read(server_.get(), &byte, 1), 0);
1692 ASSERT_EQ(SSL_get_error(server_.get(), 0), SSL_ERROR_ZERO_RETURN);
David Benjamin686bb192016-05-10 15:15:41 -04001693
1694 // However, the server may continue to write data and then shut down the
1695 // connection.
1696 byte = 42;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001697 ASSERT_EQ(SSL_write(server_.get(), &byte, 1), 1);
1698 ASSERT_EQ(SSL_read(client_.get(), &byte, 1), 1);
1699 ASSERT_EQ(byte, 42);
David Benjamin686bb192016-05-10 15:15:41 -04001700
1701 // The server may then shutdown the connection.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001702 EXPECT_EQ(SSL_shutdown(server_.get()), 1);
1703 EXPECT_EQ(SSL_shutdown(client_.get()), 1);
David Benjamin686bb192016-05-10 15:15:41 -04001704}
David Benjamin68f37b72016-11-18 15:14:42 +09001705
David Benjaminf0d8e222017-02-04 10:58:26 -05001706TEST(SSLTest, SessionDuplication) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001707 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1708 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001709 ASSERT_TRUE(client_ctx);
1710 ASSERT_TRUE(server_ctx);
Steven Valdez87eab492016-06-27 16:34:59 -04001711
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001712 bssl::UniquePtr<X509> cert = GetTestCertificate();
1713 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminf0d8e222017-02-04 10:58:26 -05001714 ASSERT_TRUE(cert);
1715 ASSERT_TRUE(key);
1716 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
1717 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04001718
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001719 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05001720 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04001721 server_ctx.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04001722
1723 SSL_SESSION *session0 = SSL_get_session(client.get());
David Benjamin31b0c9b2017-07-20 14:49:15 -04001724 bssl::UniquePtr<SSL_SESSION> session1 =
1725 bssl::SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL);
David Benjaminf0d8e222017-02-04 10:58:26 -05001726 ASSERT_TRUE(session1);
David Benjamin4501bd52016-08-01 13:39:41 -04001727
Steven Valdez84b5c002016-08-25 16:30:58 -04001728 session1->not_resumable = 0;
1729
Steven Valdez87eab492016-06-27 16:34:59 -04001730 uint8_t *s0_bytes, *s1_bytes;
1731 size_t s0_len, s1_len;
1732
David Benjaminf0d8e222017-02-04 10:58:26 -05001733 ASSERT_TRUE(SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001734 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001735
David Benjaminf0d8e222017-02-04 10:58:26 -05001736 ASSERT_TRUE(SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001737 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001738
David Benjamin7d7554b2017-02-04 11:48:59 -05001739 EXPECT_EQ(Bytes(s0_bytes, s0_len), Bytes(s1_bytes, s1_len));
Steven Valdez87eab492016-06-27 16:34:59 -04001740}
David Benjamin686bb192016-05-10 15:15:41 -04001741
David Benjaminf0d8e222017-02-04 10:58:26 -05001742static void ExpectFDs(const SSL *ssl, int rfd, int wfd) {
David Benjaminca743582017-06-15 17:51:35 -04001743 EXPECT_EQ(rfd, SSL_get_fd(ssl));
David Benjaminf0d8e222017-02-04 10:58:26 -05001744 EXPECT_EQ(rfd, SSL_get_rfd(ssl));
1745 EXPECT_EQ(wfd, SSL_get_wfd(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04001746
1747 // The wrapper BIOs are always equal when fds are equal, even if set
1748 // individually.
David Benjaminf0d8e222017-02-04 10:58:26 -05001749 if (rfd == wfd) {
1750 EXPECT_EQ(SSL_get_rbio(ssl), SSL_get_wbio(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04001751 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001752}
1753
David Benjaminf0d8e222017-02-04 10:58:26 -05001754TEST(SSLTest, SetFD) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001755 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001756 ASSERT_TRUE(ctx);
David Benjamin5c0fb882016-06-14 14:03:51 -04001757
1758 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001759 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001760 ASSERT_TRUE(ssl);
1761 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1762 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
1763 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04001764
1765 // Test setting the same FD.
1766 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001767 ASSERT_TRUE(ssl);
1768 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1769 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001770
1771 // Test setting the same FD one side at a time.
1772 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001773 ASSERT_TRUE(ssl);
1774 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1775 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1776 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001777
1778 // Test setting the same FD in the other order.
1779 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001780 ASSERT_TRUE(ssl);
1781 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1782 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1783 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001784
David Benjamin5c0fb882016-06-14 14:03:51 -04001785 // Test changing the read FD partway through.
1786 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001787 ASSERT_TRUE(ssl);
1788 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1789 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 2));
1790 ExpectFDs(ssl.get(), 2, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001791
1792 // Test changing the write FD partway through.
1793 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001794 ASSERT_TRUE(ssl);
1795 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1796 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
1797 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04001798
1799 // Test a no-op change to the read FD partway through.
1800 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001801 ASSERT_TRUE(ssl);
1802 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1803 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1804 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001805
1806 // Test a no-op change to the write FD partway through.
1807 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001808 ASSERT_TRUE(ssl);
1809 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1810 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1811 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001812
1813 // ASan builds will implicitly test that the internal |BIO| reference-counting
1814 // is correct.
David Benjamin5c0fb882016-06-14 14:03:51 -04001815}
1816
David Benjaminf0d8e222017-02-04 10:58:26 -05001817TEST(SSLTest, SetBIO) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001818 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001819 ASSERT_TRUE(ctx);
David Benjamin4501bd52016-08-01 13:39:41 -04001820
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001821 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1822 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04001823 bio3(BIO_new(BIO_s_mem()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001824 ASSERT_TRUE(ssl);
1825 ASSERT_TRUE(bio1);
1826 ASSERT_TRUE(bio2);
1827 ASSERT_TRUE(bio3);
David Benjamin4501bd52016-08-01 13:39:41 -04001828
1829 // SSL_set_bio takes one reference when the parameters are the same.
1830 BIO_up_ref(bio1.get());
1831 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1832
1833 // Repeating the call does nothing.
1834 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1835
1836 // It takes one reference each when the parameters are different.
1837 BIO_up_ref(bio2.get());
1838 BIO_up_ref(bio3.get());
1839 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1840
1841 // Repeating the call does nothing.
1842 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1843
1844 // It takes one reference when changing only wbio.
1845 BIO_up_ref(bio1.get());
1846 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1847
1848 // It takes one reference when changing only rbio and the two are different.
1849 BIO_up_ref(bio3.get());
1850 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1851
1852 // If setting wbio to rbio, it takes no additional references.
1853 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1854
1855 // From there, wbio may be switched to something else.
1856 BIO_up_ref(bio1.get());
1857 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1858
1859 // If setting rbio to wbio, it takes no additional references.
1860 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1861
1862 // From there, rbio may be switched to something else, but, for historical
1863 // reasons, it takes a reference to both parameters.
1864 BIO_up_ref(bio1.get());
1865 BIO_up_ref(bio2.get());
1866 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1867
1868 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1869 // is correct.
David Benjamin4501bd52016-08-01 13:39:41 -04001870}
1871
David Benjamin25490f22016-07-14 00:22:54 -04001872static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1873
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001874TEST_P(SSLVersionTest, GetPeerCertificate) {
1875 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04001876
David Benjamin0fef3052016-11-18 15:11:10 +09001877 // Configure both client and server to accept any certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001878 SSL_CTX_set_verify(client_ctx_.get(),
1879 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1880 nullptr);
1881 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
1882 SSL_CTX_set_verify(server_ctx_.get(),
1883 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1884 nullptr);
1885 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjaminadd5e522016-07-14 00:33:24 -04001886
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001887 ASSERT_TRUE(Connect());
David Benjaminadd5e522016-07-14 00:33:24 -04001888
David Benjamin0fef3052016-11-18 15:11:10 +09001889 // Client and server should both see the leaf certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001890 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1891 ASSERT_TRUE(peer);
1892 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04001893
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001894 peer.reset(SSL_get_peer_certificate(client_.get()));
1895 ASSERT_TRUE(peer);
1896 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04001897
David Benjamine664a532017-07-20 20:19:36 -04001898 // However, for historical reasons, the X509 chain includes the leaf on the
David Benjamin0fef3052016-11-18 15:11:10 +09001899 // client, but does not on the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001900 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(client_.get())), 1u);
1901 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(client_.get())),
1902 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04001903
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001904 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(server_.get())), 0u);
1905 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(server_.get())),
1906 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04001907}
1908
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001909TEST_P(SSLVersionTest, NoPeerCertificate) {
1910 SSL_CTX_set_verify(server_ctx_.get(), SSL_VERIFY_PEER, nullptr);
1911 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
1912 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
David Benjamine664a532017-07-20 20:19:36 -04001913
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001914 ASSERT_TRUE(Connect());
David Benjamine664a532017-07-20 20:19:36 -04001915
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001916 // Server should not see a peer certificate.
1917 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1918 ASSERT_FALSE(peer);
1919 ASSERT_FALSE(SSL_get0_peer_certificates(server_.get()));
David Benjamine664a532017-07-20 20:19:36 -04001920}
1921
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001922TEST_P(SSLVersionTest, RetainOnlySHA256OfCerts) {
David Benjamin25490f22016-07-14 00:22:54 -04001923 uint8_t *cert_der = NULL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001924 int cert_der_len = i2d_X509(cert_.get(), &cert_der);
1925 ASSERT_GE(cert_der_len, 0);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001926 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04001927
1928 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1929 SHA256(cert_der, cert_der_len, cert_sha256);
1930
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001931 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
1932
David Benjamin0fef3052016-11-18 15:11:10 +09001933 // Configure both client and server to accept any certificate, but the
1934 // server must retain only the SHA-256 of the peer.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001935 SSL_CTX_set_verify(client_ctx_.get(),
1936 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1937 nullptr);
1938 SSL_CTX_set_verify(server_ctx_.get(),
1939 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1940 nullptr);
1941 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
1942 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
1943 SSL_CTX_set_retain_only_sha256_of_client_certs(server_ctx_.get(), 1);
David Benjamin25490f22016-07-14 00:22:54 -04001944
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001945 ASSERT_TRUE(Connect());
David Benjamin25490f22016-07-14 00:22:54 -04001946
David Benjamin0fef3052016-11-18 15:11:10 +09001947 // The peer certificate has been dropped.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001948 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1949 EXPECT_FALSE(peer);
David Benjamin25490f22016-07-14 00:22:54 -04001950
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001951 SSL_SESSION *session = SSL_get_session(server_.get());
David Benjamin02de7bd2018-05-08 18:13:54 -04001952 EXPECT_TRUE(SSL_SESSION_has_peer_sha256(session));
David Benjamin25490f22016-07-14 00:22:54 -04001953
David Benjamin02de7bd2018-05-08 18:13:54 -04001954 const uint8_t *peer_sha256;
1955 size_t peer_sha256_len;
1956 SSL_SESSION_get0_peer_sha256(session, &peer_sha256, &peer_sha256_len);
1957 EXPECT_EQ(Bytes(cert_sha256), Bytes(peer_sha256, peer_sha256_len));
David Benjamin25490f22016-07-14 00:22:54 -04001958}
1959
David Benjamin737d2df2017-09-25 15:05:19 -04001960// Tests that our ClientHellos do not change unexpectedly. These are purely
1961// change detection tests. If they fail as part of an intentional ClientHello
1962// change, update the test vector.
1963TEST(SSLTest, ClientHello) {
1964 struct {
1965 uint16_t max_version;
1966 std::vector<uint8_t> expected;
1967 } kTests[] = {
1968 {SSL3_VERSION,
1969 {0x16, 0x03, 0x00, 0x00, 0x3b, 0x01, 0x00, 0x00, 0x37, 0x03, 0x00,
1970 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1971 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1972 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1973 0x00, 0x10, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00,
1974 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x00, 0xff, 0x01, 0x00}},
1975 {TLS1_VERSION,
1976 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x01, 0x00,
1977 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1978 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1979 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
1980 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001981 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1982 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
David Benjamin737d2df2017-09-25 15:05:19 -04001983 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18}},
1984 {TLS1_1_VERSION,
1985 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x02, 0x00,
1986 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1987 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1988 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
1989 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001990 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1991 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
David Benjamin737d2df2017-09-25 15:05:19 -04001992 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18}},
David Benjamin737d2df2017-09-25 15:05:19 -04001993 {TLS1_2_VERSION,
David Benjamin6e678ee2018-04-16 19:54:42 -04001994 {0x16, 0x03, 0x01, 0x00, 0x82, 0x01, 0x00, 0x00, 0x7e, 0x03, 0x03, 0x00,
David Benjamin737d2df2017-09-25 15:05:19 -04001995 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1996 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
David Benjamin6e678ee2018-04-16 19:54:42 -04001997 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xcc, 0xa9,
David Benjamin737d2df2017-09-25 15:05:19 -04001998 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xc0, 0x09,
David Benjamin6e678ee2018-04-16 19:54:42 -04001999 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
2000 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37, 0xff, 0x01, 0x00, 0x01,
David Benjamin737d2df2017-09-25 15:05:19 -04002001 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
2002 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
2003 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x00, 0x0b, 0x00,
2004 0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00,
2005 0x17, 0x00, 0x18}},
David Benjamin737d2df2017-09-25 15:05:19 -04002006 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
2007 // implementation has settled enough that it won't change.
David Benjaminafc64de2016-07-19 17:12:41 +02002008 };
David Benjamin737d2df2017-09-25 15:05:19 -04002009
2010 for (const auto &t : kTests) {
2011 SCOPED_TRACE(t.max_version);
2012
2013 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2014 ASSERT_TRUE(ctx);
2015 // Our default cipher list varies by CPU capabilities, so manually place the
2016 // ChaCha20 ciphers in front.
2017 const char *cipher_list = "CHACHA20:ALL";
2018 // SSLv3 is off by default.
2019 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION));
2020 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), t.max_version));
2021 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list));
2022
2023 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
2024 ASSERT_TRUE(ssl);
2025 std::vector<uint8_t> client_hello;
2026 ASSERT_TRUE(GetClientHello(ssl.get(), &client_hello));
2027
2028 // Zero the client_random.
2029 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
2030 1 + 3 + // handshake message header
2031 2; // client_version
2032 ASSERT_GE(client_hello.size(), kRandomOffset + SSL3_RANDOM_SIZE);
2033 OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
2034
2035 if (client_hello != t.expected) {
2036 ADD_FAILURE() << "ClientHellos did not match.";
2037 // Print the value manually so it is easier to update the test vector.
2038 for (size_t i = 0; i < client_hello.size(); i += 12) {
2039 printf(" %c", i == 0 ? '{' : ' ');
2040 for (size_t j = i; j < client_hello.size() && j < i + 12; j++) {
2041 if (j > i) {
2042 printf(" ");
2043 }
2044 printf("0x%02x", client_hello[j]);
2045 if (j < client_hello.size() - 1) {
2046 printf(",");
2047 }
2048 }
2049 if (i + 12 >= client_hello.size()) {
2050 printf("}}");
2051 }
2052 printf("\n");
2053 }
2054 }
David Benjaminafc64de2016-07-19 17:12:41 +02002055 }
David Benjaminafc64de2016-07-19 17:12:41 +02002056}
2057
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002058static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04002059
2060static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
2061 // Save the most recent session.
2062 g_last_session.reset(session);
2063 return 1;
2064}
2065
David Benjamina8614602017-09-06 15:40:19 -04002066static bssl::UniquePtr<SSL_SESSION> CreateClientSession(
2067 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2068 const ClientConfig &config = ClientConfig()) {
David Benjamina20e5352016-08-02 19:09:41 -04002069 g_last_session = nullptr;
2070 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2071
2072 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002073 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04002074 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
David Benjamina8614602017-09-06 15:40:19 -04002075 config)) {
David Benjamina20e5352016-08-02 19:09:41 -04002076 fprintf(stderr, "Failed to connect client and server.\n");
2077 return nullptr;
2078 }
2079
2080 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2081 SSL_read(client.get(), nullptr, 0);
2082
2083 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2084
2085 if (!g_last_session) {
2086 fprintf(stderr, "Client did not receive a session.\n");
2087 return nullptr;
2088 }
2089 return std::move(g_last_session);
2090}
2091
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002092static void ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2093 SSL_SESSION *session, bool want_reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002094 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002095 ClientConfig config;
2096 config.session = session;
2097 EXPECT_TRUE(
2098 ConnectClientAndServer(&client, &server, client_ctx, server_ctx, config));
David Benjamina20e5352016-08-02 19:09:41 -04002099
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002100 EXPECT_EQ(SSL_session_reused(client.get()), SSL_session_reused(server.get()));
David Benjamina20e5352016-08-02 19:09:41 -04002101
2102 bool was_reused = !!SSL_session_reused(client.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002103 EXPECT_EQ(was_reused, want_reused);
David Benjamina20e5352016-08-02 19:09:41 -04002104}
2105
David Benjamin3c51d9b2016-11-01 17:50:42 -04002106static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
2107 SSL_CTX *server_ctx,
2108 SSL_SESSION *session) {
2109 g_last_session = nullptr;
2110 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2111
2112 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002113 ClientConfig config;
2114 config.session = session;
2115 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
2116 config)) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002117 fprintf(stderr, "Failed to connect client and server.\n");
2118 return nullptr;
2119 }
2120
2121 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2122 fprintf(stderr, "Client and server were inconsistent.\n");
2123 return nullptr;
2124 }
2125
2126 if (!SSL_session_reused(client.get())) {
2127 fprintf(stderr, "Session was not reused.\n");
2128 return nullptr;
2129 }
2130
2131 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2132 SSL_read(client.get(), nullptr, 0);
2133
2134 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2135
2136 if (!g_last_session) {
2137 fprintf(stderr, "Client did not receive a renewed session.\n");
2138 return nullptr;
2139 }
2140 return std::move(g_last_session);
2141}
2142
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002143static void ExpectTicketKeyChanged(SSL_CTX *ctx, uint8_t *inout_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002144 bool changed) {
2145 uint8_t new_key[kTicketKeyLen];
David Benjaminc11ea9422017-08-29 16:33:21 -04002146 // May return 0, 1 or 48.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002147 ASSERT_EQ(SSL_CTX_get_tlsext_ticket_keys(ctx, new_key, kTicketKeyLen), 1);
2148 if (changed) {
2149 ASSERT_NE(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
2150 } else {
2151 ASSERT_EQ(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002152 }
2153 OPENSSL_memcpy(inout_key, new_key, kTicketKeyLen);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002154}
2155
David Benjamina933c382016-10-28 00:10:03 -04002156static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
2157 static const uint8_t kContext[] = {3};
2158
2159 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
2160 return SSL_TLSEXT_ERR_ALERT_FATAL;
2161 }
2162
2163 return SSL_TLSEXT_ERR_OK;
2164}
2165
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002166TEST_P(SSLVersionTest, SessionIDContext) {
David Benjamina20e5352016-08-02 19:09:41 -04002167 static const uint8_t kContext1[] = {1};
2168 static const uint8_t kContext2[] = {2};
2169
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002170 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2171 sizeof(kContext1)));
David Benjamina20e5352016-08-02 19:09:41 -04002172
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002173 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2174 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002175
David Benjamin0fef3052016-11-18 15:11:10 +09002176 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002177 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2178 ASSERT_TRUE(session);
David Benjamina20e5352016-08-02 19:09:41 -04002179
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002180 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2181 session.get(),
2182 true /* expect session reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002183
David Benjamin0fef3052016-11-18 15:11:10 +09002184 // Change the session ID context.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002185 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext2,
2186 sizeof(kContext2)));
David Benjamina20e5352016-08-02 19:09:41 -04002187
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002188 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2189 session.get(),
2190 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002191
David Benjamin0fef3052016-11-18 15:11:10 +09002192 // Change the session ID context back and install an SNI callback to switch
2193 // it.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002194 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2195 sizeof(kContext1)));
David Benjamina933c382016-10-28 00:10:03 -04002196
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002197 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09002198 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04002199
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002200 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2201 session.get(),
2202 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002203
David Benjamin0fef3052016-11-18 15:11:10 +09002204 // Switch the session ID context with the early callback instead.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002205 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), nullptr);
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002206 SSL_CTX_set_select_certificate_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002207 server_ctx_.get(),
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002208 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
2209 static const uint8_t kContext[] = {3};
2210
2211 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
2212 sizeof(kContext))) {
2213 return ssl_select_cert_error;
2214 }
2215
2216 return ssl_select_cert_success;
2217 });
David Benjamina933c382016-10-28 00:10:03 -04002218
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002219 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2220 session.get(),
2221 false /* expect session not reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002222}
2223
David Benjamin721e8b72016-08-03 13:13:17 -04002224static timeval g_current_time;
2225
2226static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2227 *out_clock = g_current_time;
2228}
2229
David Benjamin17b30832017-01-28 14:00:32 -05002230static void FrozenTimeCallback(const SSL *ssl, timeval *out_clock) {
2231 out_clock->tv_sec = 1000;
2232 out_clock->tv_usec = 0;
2233}
2234
David Benjamin3c51d9b2016-11-01 17:50:42 -04002235static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
2236 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
2237 int encrypt) {
2238 static const uint8_t kZeros[16] = {0};
2239
2240 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -05002241 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamin3c51d9b2016-11-01 17:50:42 -04002242 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -05002243 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002244 return 0;
2245 }
2246
2247 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
2248 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
2249 return -1;
2250 }
2251
2252 // Returning two from the callback in decrypt mode renews the
2253 // session in TLS 1.2 and below.
2254 return encrypt ? 1 : 2;
2255}
2256
David Benjamin123db572016-11-03 16:59:25 -04002257static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjamin123db572016-11-03 16:59:25 -04002258 if (session->tlsext_ticklen < 16 + 16 + SHA256_DIGEST_LENGTH) {
2259 return false;
2260 }
2261
David Benjamin123db572016-11-03 16:59:25 -04002262 const uint8_t *ciphertext = session->tlsext_tick + 16 + 16;
2263 size_t len = session->tlsext_ticklen - 16 - 16 - SHA256_DIGEST_LENGTH;
2264 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
2265
David Benjamin9b63f292016-11-15 00:44:05 -05002266#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
2267 // Fuzzer-mode tickets are unencrypted.
David Benjamin17cf2cb2016-12-13 01:07:13 -05002268 OPENSSL_memcpy(plaintext.get(), ciphertext, len);
David Benjamin9b63f292016-11-15 00:44:05 -05002269#else
2270 static const uint8_t kZeros[16] = {0};
2271 const uint8_t *iv = session->tlsext_tick + 16;
David Benjamin123db572016-11-03 16:59:25 -04002272 bssl::ScopedEVP_CIPHER_CTX ctx;
2273 int len1, len2;
2274 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
2275 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
2276 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
2277 return false;
2278 }
2279
2280 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05002281#endif
David Benjamin123db572016-11-03 16:59:25 -04002282
Adam Langley46db7af2017-02-01 15:49:37 -08002283 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
2284 if (!ssl_ctx) {
2285 return false;
2286 }
David Benjamin123db572016-11-03 16:59:25 -04002287 bssl::UniquePtr<SSL_SESSION> server_session(
Adam Langley46db7af2017-02-01 15:49:37 -08002288 SSL_SESSION_from_bytes(plaintext.get(), len, ssl_ctx.get()));
David Benjamin123db572016-11-03 16:59:25 -04002289 if (!server_session) {
2290 return false;
2291 }
2292
2293 *out = server_session->time;
2294 return true;
2295}
2296
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002297TEST_P(SSLVersionTest, SessionTimeout) {
2298 for (bool server_test : {false, true}) {
2299 SCOPED_TRACE(server_test);
David Benjamin721e8b72016-08-03 13:13:17 -04002300
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002301 ResetContexts();
2302 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2303 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
2304
David Benjamin17b30832017-01-28 14:00:32 -05002305 static const time_t kStartTime = 1000;
David Benjamin0fef3052016-11-18 15:11:10 +09002306 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002307
David Benjamin17b30832017-01-28 14:00:32 -05002308 // We are willing to use a longer lifetime for TLS 1.3 sessions as
2309 // resumptions still perform ECDHE.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002310 const time_t timeout = version() == TLS1_3_VERSION
David Benjamin17b30832017-01-28 14:00:32 -05002311 ? SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT
2312 : SSL_DEFAULT_SESSION_TIMEOUT;
2313
David Benjamin17b30832017-01-28 14:00:32 -05002314 // Both client and server must enforce session timeouts. We configure the
2315 // other side with a frozen clock so it never expires tickets.
David Benjamin0fef3052016-11-18 15:11:10 +09002316 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002317 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2318 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002319 } else {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002320 SSL_CTX_set_current_time_cb(client_ctx_.get(), CurrentTimeCallback);
2321 SSL_CTX_set_current_time_cb(server_ctx_.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002322 }
2323
2324 // Configure a ticket callback which renews tickets.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002325 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002326
2327 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002328 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2329 ASSERT_TRUE(session);
David Benjamin0fef3052016-11-18 15:11:10 +09002330
2331 // Advance the clock just behind the timeout.
David Benjamin17b30832017-01-28 14:00:32 -05002332 g_current_time.tv_sec += timeout - 1;
David Benjamin0fef3052016-11-18 15:11:10 +09002333
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002334 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2335 session.get(),
2336 true /* expect session reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002337
2338 // Advance the clock one more second.
2339 g_current_time.tv_sec++;
2340
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002341 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2342 session.get(),
2343 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002344
2345 // Rewind the clock to before the session was minted.
2346 g_current_time.tv_sec = kStartTime - 1;
2347
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002348 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2349 session.get(),
2350 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002351
2352 // SSL 3.0 cannot renew sessions.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002353 if (version() == SSL3_VERSION) {
David Benjamin0fef3052016-11-18 15:11:10 +09002354 continue;
2355 }
2356
2357 // Renew the session 10 seconds before expiration.
David Benjamin17b30832017-01-28 14:00:32 -05002358 time_t new_start_time = kStartTime + timeout - 10;
2359 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002360 bssl::UniquePtr<SSL_SESSION> new_session = ExpectSessionRenewed(
2361 client_ctx_.get(), server_ctx_.get(), session.get());
2362 ASSERT_TRUE(new_session);
David Benjamin0fef3052016-11-18 15:11:10 +09002363
2364 // This new session is not the same object as before.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002365 EXPECT_NE(session.get(), new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002366
2367 // Check the sessions have timestamps measured from issuance.
2368 long session_time = 0;
2369 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002370 ASSERT_TRUE(GetServerTicketTime(&session_time, new_session.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09002371 } else {
2372 session_time = new_session->time;
2373 }
David Benjamin721e8b72016-08-03 13:13:17 -04002374
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002375 ASSERT_EQ(session_time, g_current_time.tv_sec);
David Benjamin721e8b72016-08-03 13:13:17 -04002376
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002377 if (version() == TLS1_3_VERSION) {
David Benjamin17b30832017-01-28 14:00:32 -05002378 // Renewal incorporates fresh key material in TLS 1.3, so we extend the
2379 // lifetime TLS 1.3.
2380 g_current_time.tv_sec = new_start_time + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002381 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2382 new_session.get(),
2383 true /* expect session reused */));
David Benjamin721e8b72016-08-03 13:13:17 -04002384
David Benjamin17b30832017-01-28 14:00:32 -05002385 // The new session expires after the new timeout.
2386 g_current_time.tv_sec = new_start_time + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002387 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2388 new_session.get(),
2389 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002390
2391 // Renew the session until it begins just past the auth timeout.
2392 time_t auth_end_time = kStartTime + SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
2393 while (new_start_time < auth_end_time - 1000) {
2394 // Get as close as possible to target start time.
2395 new_start_time =
2396 std::min(auth_end_time - 1000, new_start_time + timeout - 1);
2397 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002398 new_session = ExpectSessionRenewed(client_ctx_.get(), server_ctx_.get(),
David Benjamin17b30832017-01-28 14:00:32 -05002399 new_session.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002400 ASSERT_TRUE(new_session);
David Benjamin17b30832017-01-28 14:00:32 -05002401 }
2402
2403 // Now the session's lifetime is bound by the auth timeout.
2404 g_current_time.tv_sec = auth_end_time - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002405 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2406 new_session.get(),
2407 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002408
2409 g_current_time.tv_sec = auth_end_time + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002410 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2411 new_session.get(),
2412 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002413 } else {
2414 // The new session is usable just before the old expiration.
2415 g_current_time.tv_sec = kStartTime + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002416 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2417 new_session.get(),
2418 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002419
2420 // Renewal does not extend the lifetime, so it is not usable beyond the
2421 // old expiration.
2422 g_current_time.tv_sec = kStartTime + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002423 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2424 new_session.get(),
2425 false /* expect session not reused */));
David Benjamin1b22f852016-10-27 16:36:32 -04002426 }
David Benjamin721e8b72016-08-03 13:13:17 -04002427 }
David Benjamin721e8b72016-08-03 13:13:17 -04002428}
2429
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002430TEST_P(SSLVersionTest, DefaultTicketKeyInitialization) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002431 static const uint8_t kZeroKey[kTicketKeyLen] = {};
2432 uint8_t ticket_key[kTicketKeyLen];
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002433 ASSERT_EQ(1, SSL_CTX_get_tlsext_ticket_keys(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002434 kTicketKeyLen));
2435 ASSERT_NE(0, OPENSSL_memcmp(ticket_key, kZeroKey, kTicketKeyLen));
2436}
2437
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002438TEST_P(SSLVersionTest, DefaultTicketKeyRotation) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002439 if (GetParam().version == SSL3_VERSION) {
2440 return;
2441 }
2442
2443 static const time_t kStartTime = 1001;
2444 g_current_time.tv_sec = kStartTime;
2445 uint8_t ticket_key[kTicketKeyLen];
2446
David Benjaminc11ea9422017-08-29 16:33:21 -04002447 // We use session reuse as a proxy for ticket decryption success, hence
2448 // disable session timeouts.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002449 SSL_CTX_set_timeout(server_ctx_.get(), std::numeric_limits<uint32_t>::max());
2450 SSL_CTX_set_session_psk_dhe_timeout(server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002451 std::numeric_limits<uint32_t>::max());
2452
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002453 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2454 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002455
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002456 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2457 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_OFF);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002458
David Benjaminc11ea9422017-08-29 16:33:21 -04002459 // Initialize ticket_key with the current key.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002460 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2461 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002462
David Benjaminc11ea9422017-08-29 16:33:21 -04002463 // Verify ticket resumption actually works.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002464 bssl::UniquePtr<SSL> client, server;
2465 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002466 CreateClientSession(client_ctx_.get(), server_ctx_.get());
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002467 ASSERT_TRUE(session);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002468 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002469 session.get(), true /* reused */));
2470
David Benjaminc11ea9422017-08-29 16:33:21 -04002471 // Advance time to just before key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002472 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002473 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002474 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002475 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002476 false /* NOT changed */));
2477
David Benjaminc11ea9422017-08-29 16:33:21 -04002478 // Force key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002479 g_current_time.tv_sec += 1;
2480 bssl::UniquePtr<SSL_SESSION> new_session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002481 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2482 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2483 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002484
David Benjaminc11ea9422017-08-29 16:33:21 -04002485 // Resumption with both old and new ticket should work.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002486 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002487 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002488 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002489 new_session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002490 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002491 false /* NOT changed */));
2492
David Benjaminc11ea9422017-08-29 16:33:21 -04002493 // Force key rotation again. Resumption with the old ticket now fails.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002494 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002495 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002496 session.get(), false /* NOT reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002497 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2498 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002499
David Benjaminc11ea9422017-08-29 16:33:21 -04002500 // But resumption with the newer session still works.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002501 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002502 new_session.get(), true /* reused */));
2503}
2504
David Benjamin0fc37ef2016-08-17 15:29:46 -04002505static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002506 SSL_CTX *ctx = reinterpret_cast<SSL_CTX *>(arg);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002507 SSL_set_SSL_CTX(ssl, ctx);
2508 return SSL_TLSEXT_ERR_OK;
2509}
2510
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002511TEST_P(SSLVersionTest, SNICallback) {
David Benjamin0fef3052016-11-18 15:11:10 +09002512 // SSL 3.0 lacks extensions.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002513 if (version() == SSL3_VERSION) {
2514 return;
David Benjamin0fef3052016-11-18 15:11:10 +09002515 }
2516
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002517 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002518 ASSERT_TRUE(cert2);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002519 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002520 ASSERT_TRUE(key2);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002521
David Benjamin0fef3052016-11-18 15:11:10 +09002522 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
2523 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002524
David Benjamin83a32122017-02-14 18:34:54 -05002525 static const uint8_t kSCTList[] = {0, 6, 0, 4, 5, 6, 7, 8};
2526 static const uint8_t kOCSPResponse[] = {1, 2, 3, 4};
2527
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002528 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
2529 ASSERT_TRUE(server_ctx2);
2530 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()));
2531 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()));
2532 ASSERT_TRUE(SSL_CTX_set_signed_cert_timestamp_list(
2533 server_ctx2.get(), kSCTList, sizeof(kSCTList)));
2534 ASSERT_TRUE(SSL_CTX_set_ocsp_response(server_ctx2.get(), kOCSPResponse,
2535 sizeof(kOCSPResponse)));
2536 // Historically signing preferences would be lost in some cases with the
2537 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2538 // this doesn't happen when |version| is TLS 1.2, configure the private
2539 // key to only sign SHA-256.
2540 ASSERT_TRUE(SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
2541 &kECDSAWithSHA256, 1));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002542
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002543 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), SwitchContext);
2544 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002545
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002546 SSL_CTX_enable_signed_cert_timestamps(client_ctx_.get());
2547 SSL_CTX_enable_ocsp_stapling(client_ctx_.get());
David Benjamin83a32122017-02-14 18:34:54 -05002548
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002549 ASSERT_TRUE(Connect());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002550
David Benjamin0fef3052016-11-18 15:11:10 +09002551 // The client should have received |cert2|.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002552 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client_.get()));
2553 ASSERT_TRUE(peer);
2554 EXPECT_EQ(X509_cmp(peer.get(), cert2.get()), 0);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002555
David Benjamin83a32122017-02-14 18:34:54 -05002556 // The client should have received |server_ctx2|'s SCT list.
2557 const uint8_t *data;
2558 size_t len;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002559 SSL_get0_signed_cert_timestamp_list(client_.get(), &data, &len);
2560 EXPECT_EQ(Bytes(kSCTList), Bytes(data, len));
David Benjamin83a32122017-02-14 18:34:54 -05002561
2562 // The client should have received |server_ctx2|'s OCSP response.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002563 SSL_get0_ocsp_response(client_.get(), &data, &len);
2564 EXPECT_EQ(Bytes(kOCSPResponse), Bytes(data, len));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002565}
2566
David Benjaminf0d8e222017-02-04 10:58:26 -05002567// Test that the early callback can swap the maximum version.
2568TEST(SSLTest, EarlyCallbackVersionSwitch) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002569 bssl::UniquePtr<X509> cert = GetTestCertificate();
2570 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2571 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2572 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002573 ASSERT_TRUE(cert);
2574 ASSERT_TRUE(key);
2575 ASSERT_TRUE(server_ctx);
2576 ASSERT_TRUE(client_ctx);
2577 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
2578 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
2579 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
2580 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
David Benjamin99620572016-08-30 00:35:36 -04002581
David Benjaminf0d8e222017-02-04 10:58:26 -05002582 SSL_CTX_set_select_certificate_cb(
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002583 server_ctx.get(),
2584 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
David Benjaminf0d8e222017-02-04 10:58:26 -05002585 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002586 return ssl_select_cert_error;
David Benjaminf0d8e222017-02-04 10:58:26 -05002587 }
2588
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002589 return ssl_select_cert_success;
David Benjaminf0d8e222017-02-04 10:58:26 -05002590 });
David Benjamin99620572016-08-30 00:35:36 -04002591
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002592 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05002593 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04002594 server_ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002595 EXPECT_EQ(TLS1_2_VERSION, SSL_version(client.get()));
David Benjamin99620572016-08-30 00:35:36 -04002596}
2597
David Benjaminf0d8e222017-02-04 10:58:26 -05002598TEST(SSLTest, SetVersion) {
David Benjamin2dc02042016-09-19 19:57:37 -04002599 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002600 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002601
David Benjaminf0d8e222017-02-04 10:58:26 -05002602 // Set valid TLS versions.
2603 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2604 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
2605 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2606 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002607
David Benjaminf0d8e222017-02-04 10:58:26 -05002608 // Invalid TLS versions are rejected.
2609 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2610 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x0200));
2611 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2612 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2613 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x0200));
2614 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002615
David Benjaminf0d8e222017-02-04 10:58:26 -05002616 // Zero is the default version.
2617 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002618 EXPECT_EQ(TLS1_2_VERSION, ctx->conf_max_version);
David Benjaminf0d8e222017-02-04 10:58:26 -05002619 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002620 EXPECT_EQ(TLS1_VERSION, ctx->conf_min_version);
David Benjamin3cfeb952017-03-01 16:48:38 -05002621
2622 // SSL 3.0 and TLS 1.3 are available, but not by default.
2623 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002624 EXPECT_EQ(SSL3_VERSION, ctx->conf_min_version);
David Benjamin3cfeb952017-03-01 16:48:38 -05002625 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002626 EXPECT_EQ(TLS1_3_VERSION, ctx->conf_max_version);
David Benjamine34bcc92016-09-21 16:53:09 -04002627
David Benjamin353577c2017-06-29 15:54:58 -04002628 // TLS1_3_DRAFT_VERSION is not an API-level version.
Steven Valdez64cc1212017-12-04 11:15:37 -05002629 EXPECT_FALSE(
Steven Valdez7e5dd252018-01-22 15:20:31 -05002630 SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_DRAFT23_VERSION));
David Benjamin353577c2017-06-29 15:54:58 -04002631 ERR_clear_error();
2632
David Benjamin2dc02042016-09-19 19:57:37 -04002633 ctx.reset(SSL_CTX_new(DTLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002634 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002635
David Benjaminf0d8e222017-02-04 10:58:26 -05002636 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2637 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION));
2638 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2639 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002640
David Benjaminf0d8e222017-02-04 10:58:26 -05002641 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2642 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2643 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2644 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2645 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2646 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2647 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2648 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002649
David Benjaminf0d8e222017-02-04 10:58:26 -05002650 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002651 EXPECT_EQ(TLS1_2_VERSION, ctx->conf_max_version);
David Benjaminf0d8e222017-02-04 10:58:26 -05002652 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002653 EXPECT_EQ(TLS1_1_VERSION, ctx->conf_min_version);
David Benjamin2dc02042016-09-19 19:57:37 -04002654}
2655
David Benjamin458334a2016-12-15 13:53:25 -05002656static const char *GetVersionName(uint16_t version) {
2657 switch (version) {
2658 case SSL3_VERSION:
2659 return "SSLv3";
2660 case TLS1_VERSION:
2661 return "TLSv1";
2662 case TLS1_1_VERSION:
2663 return "TLSv1.1";
2664 case TLS1_2_VERSION:
2665 return "TLSv1.2";
2666 case TLS1_3_VERSION:
2667 return "TLSv1.3";
2668 case DTLS1_VERSION:
2669 return "DTLSv1";
2670 case DTLS1_2_VERSION:
2671 return "DTLSv1.2";
2672 default:
2673 return "???";
2674 }
2675}
2676
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002677TEST_P(SSLVersionTest, Version) {
2678 ASSERT_TRUE(Connect());
David Benjamincb18ac22016-09-27 14:09:15 -04002679
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002680 EXPECT_EQ(SSL_version(client_.get()), version());
2681 EXPECT_EQ(SSL_version(server_.get()), version());
David Benjamincb18ac22016-09-27 14:09:15 -04002682
David Benjamin458334a2016-12-15 13:53:25 -05002683 // Test the version name is reported as expected.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002684 const char *version_name = GetVersionName(version());
2685 EXPECT_EQ(strcmp(version_name, SSL_get_version(client_.get())), 0);
2686 EXPECT_EQ(strcmp(version_name, SSL_get_version(server_.get())), 0);
David Benjamin458334a2016-12-15 13:53:25 -05002687
2688 // Test SSL_SESSION reports the same name.
2689 const char *client_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002690 SSL_SESSION_get_version(SSL_get_session(client_.get()));
David Benjamin458334a2016-12-15 13:53:25 -05002691 const char *server_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002692 SSL_SESSION_get_version(SSL_get_session(server_.get()));
2693 EXPECT_EQ(strcmp(version_name, client_name), 0);
2694 EXPECT_EQ(strcmp(version_name, server_name), 0);
David Benjamincb18ac22016-09-27 14:09:15 -04002695}
2696
David Benjamin9ef31f02016-10-31 18:01:13 -04002697// Tests that that |SSL_get_pending_cipher| is available during the ALPN
2698// selection callback.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002699TEST_P(SSLVersionTest, ALPNCipherAvailable) {
David Benjamin0fef3052016-11-18 15:11:10 +09002700 // SSL 3.0 lacks extensions.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002701 if (version() == SSL3_VERSION) {
2702 return;
David Benjamin0fef3052016-11-18 15:11:10 +09002703 }
2704
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002705 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2706
David Benjamin9ef31f02016-10-31 18:01:13 -04002707 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002708 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
2709 sizeof(kALPNProtos)),
2710 0);
David Benjamin0fef3052016-11-18 15:11:10 +09002711
2712 // The ALPN callback does not fail the handshake on error, so have the
2713 // callback write a boolean.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002714 std::pair<uint16_t, bool> callback_state(version(), false);
David Benjamin0fef3052016-11-18 15:11:10 +09002715 SSL_CTX_set_alpn_select_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002716 server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09002717 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
2718 unsigned in_len, void *arg) -> int {
2719 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
2720 if (SSL_get_pending_cipher(ssl) != nullptr &&
2721 SSL_version(ssl) == state->first) {
2722 state->second = true;
2723 }
2724 return SSL_TLSEXT_ERR_NOACK;
2725 },
2726 &callback_state);
2727
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002728 ASSERT_TRUE(Connect());
David Benjamin0fef3052016-11-18 15:11:10 +09002729
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002730 ASSERT_TRUE(callback_state.second);
David Benjamin0fef3052016-11-18 15:11:10 +09002731}
2732
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002733TEST_P(SSLVersionTest, SSLClearSessionResumption) {
David Benjaminb79cc842016-12-07 15:57:14 -05002734 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
2735 // API pattern.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002736 if (version() == TLS1_3_VERSION) {
2737 return;
David Benjaminb79cc842016-12-07 15:57:14 -05002738 }
2739
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07002740 shed_handshake_config_ = false;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002741 ASSERT_TRUE(Connect());
David Benjaminb79cc842016-12-07 15:57:14 -05002742
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002743 EXPECT_FALSE(SSL_session_reused(client_.get()));
2744 EXPECT_FALSE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002745
2746 // Reset everything.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002747 ASSERT_TRUE(SSL_clear(client_.get()));
2748 ASSERT_TRUE(SSL_clear(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002749
2750 // Attempt to connect a second time.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002751 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002752
2753 // |SSL_clear| should implicitly offer the previous session to the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002754 EXPECT_TRUE(SSL_session_reused(client_.get()));
2755 EXPECT_TRUE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002756}
2757
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07002758TEST_P(SSLVersionTest, SSLClearFailsWithShedding) {
2759 shed_handshake_config_ = false;
2760 ASSERT_TRUE(Connect());
2761 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
2762
2763 // Reset everything.
2764 ASSERT_TRUE(SSL_clear(client_.get()));
2765 ASSERT_TRUE(SSL_clear(server_.get()));
2766
2767 // Now enable shedding, and connect a second time.
2768 shed_handshake_config_ = true;
2769 ASSERT_TRUE(Connect());
2770 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
2771
2772 // |SSL_clear| should now fail.
2773 ASSERT_FALSE(SSL_clear(client_.get()));
2774 ASSERT_FALSE(SSL_clear(server_.get()));
2775}
2776
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002777static bool ChainsEqual(STACK_OF(X509) * chain,
2778 const std::vector<X509 *> &expected) {
David Benjamin1444c3a2016-12-20 17:23:11 -05002779 if (sk_X509_num(chain) != expected.size()) {
2780 return false;
2781 }
2782
2783 for (size_t i = 0; i < expected.size(); i++) {
2784 if (X509_cmp(sk_X509_value(chain, i), expected[i]) != 0) {
2785 return false;
2786 }
2787 }
2788
2789 return true;
2790}
2791
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002792TEST_P(SSLVersionTest, AutoChain) {
2793 cert_ = GetChainTestCertificate();
2794 ASSERT_TRUE(cert_);
2795 key_ = GetChainTestKey();
2796 ASSERT_TRUE(key_);
David Benjamin1444c3a2016-12-20 17:23:11 -05002797 bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002798 ASSERT_TRUE(intermediate);
2799
2800 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2801 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin1444c3a2016-12-20 17:23:11 -05002802
2803 // Configure both client and server to accept any certificate. Add
2804 // |intermediate| to the cert store.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002805 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx_.get()),
2806 intermediate.get()));
2807 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(server_ctx_.get()),
2808 intermediate.get()));
2809 SSL_CTX_set_verify(client_ctx_.get(),
2810 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2811 nullptr);
2812 SSL_CTX_set_verify(server_ctx_.get(),
2813 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2814 nullptr);
2815 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
2816 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjamin1444c3a2016-12-20 17:23:11 -05002817
2818 // By default, the client and server should each only send the leaf.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002819 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002820
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002821 EXPECT_TRUE(
2822 ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()), {cert_.get()}));
2823 EXPECT_TRUE(
2824 ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()), {cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002825
2826 // If auto-chaining is enabled, then the intermediate is sent.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002827 SSL_CTX_clear_mode(client_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
2828 SSL_CTX_clear_mode(server_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
2829 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002830
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002831 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
2832 {cert_.get(), intermediate.get()}));
2833 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
2834 {cert_.get(), intermediate.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002835
2836 // Auto-chaining does not override explicitly-configured intermediates.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002837 ASSERT_TRUE(SSL_CTX_add1_chain_cert(client_ctx_.get(), cert_.get()));
2838 ASSERT_TRUE(SSL_CTX_add1_chain_cert(server_ctx_.get(), cert_.get()));
2839 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002840
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002841 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
2842 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002843
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002844 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
2845 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002846}
2847
David Benjamin48063c22017-01-01 23:56:36 -05002848static bool ExpectBadWriteRetry() {
2849 int err = ERR_get_error();
2850 if (ERR_GET_LIB(err) != ERR_LIB_SSL ||
2851 ERR_GET_REASON(err) != SSL_R_BAD_WRITE_RETRY) {
2852 char buf[ERR_ERROR_STRING_BUF_LEN];
2853 ERR_error_string_n(err, buf, sizeof(buf));
2854 fprintf(stderr, "Wanted SSL_R_BAD_WRITE_RETRY, got: %s.\n", buf);
2855 return false;
2856 }
2857
2858 if (ERR_peek_error() != 0) {
2859 fprintf(stderr, "Unexpected error following SSL_R_BAD_WRITE_RETRY.\n");
2860 return false;
2861 }
2862
2863 return true;
2864}
2865
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002866TEST_P(SSLVersionTest, SSLWriteRetry) {
2867 if (is_dtls()) {
2868 return;
David Benjamin48063c22017-01-01 23:56:36 -05002869 }
2870
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002871 for (bool enable_partial_write : {false, true}) {
2872 SCOPED_TRACE(enable_partial_write);
2873
David Benjamin48063c22017-01-01 23:56:36 -05002874 // Connect a client and server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002875 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2876
2877 ASSERT_TRUE(Connect());
David Benjamin48063c22017-01-01 23:56:36 -05002878
2879 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002880 SSL_set_mode(client_.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002881 }
2882
2883 // Write without reading until the buffer is full and we have an unfinished
2884 // write. Keep a count so we may reread it again later. "hello!" will be
2885 // written in two chunks, "hello" and "!".
2886 char data[] = "hello!";
2887 static const int kChunkLen = 5; // The length of "hello".
2888 unsigned count = 0;
2889 for (;;) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002890 int ret = SSL_write(client_.get(), data, kChunkLen);
David Benjamin48063c22017-01-01 23:56:36 -05002891 if (ret <= 0) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002892 ASSERT_EQ(SSL_get_error(client_.get(), ret), SSL_ERROR_WANT_WRITE);
2893 break;
David Benjamin48063c22017-01-01 23:56:36 -05002894 }
2895
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002896 ASSERT_EQ(ret, 5);
David Benjamin48063c22017-01-01 23:56:36 -05002897
2898 count++;
2899 }
2900
2901 // Retrying with the same parameters is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002902 ASSERT_EQ(
2903 SSL_get_error(client_.get(), SSL_write(client_.get(), data, kChunkLen)),
2904 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002905
2906 // Retrying with the same buffer but shorter length is not legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002907 ASSERT_EQ(SSL_get_error(client_.get(),
2908 SSL_write(client_.get(), data, kChunkLen - 1)),
2909 SSL_ERROR_SSL);
2910 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002911
2912 // Retrying with a different buffer pointer is not legal.
2913 char data2[] = "hello";
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002914 ASSERT_EQ(SSL_get_error(client_.get(),
2915 SSL_write(client_.get(), data2, kChunkLen)),
2916 SSL_ERROR_SSL);
2917 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002918
2919 // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002920 SSL_set_mode(client_.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
2921 ASSERT_EQ(SSL_get_error(client_.get(),
2922 SSL_write(client_.get(), data2, kChunkLen)),
2923 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002924
2925 // |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| does not disable length checks.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002926 ASSERT_EQ(SSL_get_error(client_.get(),
2927 SSL_write(client_.get(), data2, kChunkLen - 1)),
2928 SSL_ERROR_SSL);
2929 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002930
2931 // Retrying with a larger buffer is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002932 ASSERT_EQ(SSL_get_error(client_.get(),
2933 SSL_write(client_.get(), data, kChunkLen + 1)),
2934 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002935
2936 // Drain the buffer.
2937 char buf[20];
2938 for (unsigned i = 0; i < count; i++) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002939 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
2940 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
David Benjamin48063c22017-01-01 23:56:36 -05002941 }
2942
2943 // Now that there is space, a retry with a larger buffer should flush the
2944 // pending record, skip over that many bytes of input (on assumption they
2945 // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE
2946 // is set, this will complete in two steps.
2947 char data3[] = "_____!";
2948 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002949 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen);
2950 ASSERT_EQ(SSL_write(client_.get(), data3 + kChunkLen, 1), 1);
2951 } else {
2952 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen + 1);
David Benjamin48063c22017-01-01 23:56:36 -05002953 }
2954
2955 // Check the last write was correct. The data will be spread over two
2956 // records, so SSL_read returns twice.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002957 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
2958 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
2959 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), 1);
2960 ASSERT_EQ(buf[0], '!');
David Benjamin48063c22017-01-01 23:56:36 -05002961 }
David Benjamin48063c22017-01-01 23:56:36 -05002962}
2963
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002964TEST_P(SSLVersionTest, RecordCallback) {
2965 for (bool test_server : {true, false}) {
2966 SCOPED_TRACE(test_server);
2967 ResetContexts();
David Benjamin5df5be12017-06-22 19:43:11 -04002968
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002969 bool read_seen = false;
2970 bool write_seen = false;
2971 auto cb = [&](int is_write, int cb_version, int cb_type, const void *buf,
2972 size_t len, SSL *ssl) {
2973 if (cb_type != SSL3_RT_HEADER) {
2974 return;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002975 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002976
2977 // The callback does not report a version for records.
2978 EXPECT_EQ(0, cb_version);
2979
2980 if (is_write) {
2981 write_seen = true;
2982 } else {
2983 read_seen = true;
2984 }
2985
2986 // Sanity-check that the record header is plausible.
2987 CBS cbs;
2988 CBS_init(&cbs, reinterpret_cast<const uint8_t *>(buf), len);
2989 uint8_t type;
2990 uint16_t record_version, length;
2991 ASSERT_TRUE(CBS_get_u8(&cbs, &type));
2992 ASSERT_TRUE(CBS_get_u16(&cbs, &record_version));
Steven Valdez64cc1212017-12-04 11:15:37 -05002993 EXPECT_EQ(record_version & 0xff00, version() & 0xff00);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002994 if (is_dtls()) {
2995 uint16_t epoch;
2996 ASSERT_TRUE(CBS_get_u16(&cbs, &epoch));
2997 EXPECT_TRUE(epoch == 0 || epoch == 1) << "Invalid epoch: " << epoch;
2998 ASSERT_TRUE(CBS_skip(&cbs, 6));
2999 }
3000 ASSERT_TRUE(CBS_get_u16(&cbs, &length));
3001 EXPECT_EQ(0u, CBS_len(&cbs));
3002 };
3003 using CallbackType = decltype(cb);
3004 SSL_CTX *ctx = test_server ? server_ctx_.get() : client_ctx_.get();
3005 SSL_CTX_set_msg_callback(
3006 ctx, [](int is_write, int cb_version, int cb_type, const void *buf,
3007 size_t len, SSL *ssl, void *arg) {
3008 CallbackType *cb_ptr = reinterpret_cast<CallbackType *>(arg);
3009 (*cb_ptr)(is_write, cb_version, cb_type, buf, len, ssl);
3010 });
3011 SSL_CTX_set_msg_callback_arg(ctx, &cb);
3012
3013 ASSERT_TRUE(Connect());
3014
3015 EXPECT_TRUE(read_seen);
3016 EXPECT_TRUE(write_seen);
David Benjamin0fef3052016-11-18 15:11:10 +09003017 }
David Benjamin9ef31f02016-10-31 18:01:13 -04003018}
3019
David Benjamina8614602017-09-06 15:40:19 -04003020TEST_P(SSLVersionTest, GetServerName) {
3021 // No extensions in SSL 3.0.
3022 if (version() == SSL3_VERSION) {
3023 return;
3024 }
3025
3026 ClientConfig config;
3027 config.servername = "host1";
3028
3029 SSL_CTX_set_tlsext_servername_callback(
3030 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
3031 // During the handshake, |SSL_get_servername| must match |config|.
3032 ClientConfig *config_p = reinterpret_cast<ClientConfig *>(arg);
3033 EXPECT_STREQ(config_p->servername.c_str(),
3034 SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name));
3035 return SSL_TLSEXT_ERR_OK;
3036 });
3037 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), &config);
3038
3039 ASSERT_TRUE(Connect(config));
3040 // After the handshake, it must also be available.
3041 EXPECT_STREQ(config.servername.c_str(),
3042 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3043
3044 // Establish a session under host1.
3045 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3046 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3047 bssl::UniquePtr<SSL_SESSION> session =
3048 CreateClientSession(client_ctx_.get(), server_ctx_.get(), config);
3049
3050 // If the client resumes a session with a different name, |SSL_get_servername|
3051 // must return the new name.
3052 ASSERT_TRUE(session);
3053 config.session = session.get();
3054 config.servername = "host2";
3055 ASSERT_TRUE(Connect(config));
3056 EXPECT_STREQ(config.servername.c_str(),
3057 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3058}
3059
David Benjamin3d8f0802017-09-06 16:12:52 -04003060// Test that session cache mode bits are honored in the client session callback.
3061TEST_P(SSLVersionTest, ClientSessionCacheMode) {
3062 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_OFF);
3063 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3064
3065 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_CLIENT);
3066 EXPECT_TRUE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3067
3068 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_SERVER);
3069 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3070}
3071
Adam Langleye1e78132017-01-31 15:24:31 -08003072TEST(SSLTest, AddChainCertHack) {
3073 // Ensure that we don't accidently break the hack that we have in place to
3074 // keep curl and serf happy when they use an |X509| even after transfering
3075 // ownership.
3076
3077 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3078 ASSERT_TRUE(ctx);
3079 X509 *cert = GetTestCertificate().release();
3080 ASSERT_TRUE(cert);
3081 SSL_CTX_add0_chain_cert(ctx.get(), cert);
3082
3083 // This should not trigger a use-after-free.
3084 X509_cmp(cert, cert);
3085}
3086
David Benjaminb2ff2622017-02-03 17:06:18 -05003087TEST(SSLTest, GetCertificate) {
3088 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3089 ASSERT_TRUE(ctx);
3090 bssl::UniquePtr<X509> cert = GetTestCertificate();
3091 ASSERT_TRUE(cert);
3092 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
3093 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3094 ASSERT_TRUE(ssl);
3095
3096 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
3097 ASSERT_TRUE(cert2);
3098 X509 *cert3 = SSL_get_certificate(ssl.get());
3099 ASSERT_TRUE(cert3);
3100
3101 // The old and new certificates must be identical.
3102 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
3103 EXPECT_EQ(0, X509_cmp(cert.get(), cert3));
3104
3105 uint8_t *der = nullptr;
3106 long der_len = i2d_X509(cert.get(), &der);
3107 ASSERT_LT(0, der_len);
3108 bssl::UniquePtr<uint8_t> free_der(der);
3109
3110 uint8_t *der2 = nullptr;
3111 long der2_len = i2d_X509(cert2, &der2);
3112 ASSERT_LT(0, der2_len);
3113 bssl::UniquePtr<uint8_t> free_der2(der2);
3114
3115 uint8_t *der3 = nullptr;
3116 long der3_len = i2d_X509(cert3, &der3);
3117 ASSERT_LT(0, der3_len);
3118 bssl::UniquePtr<uint8_t> free_der3(der3);
3119
3120 // They must also encode identically.
David Benjamin7d7554b2017-02-04 11:48:59 -05003121 EXPECT_EQ(Bytes(der, der_len), Bytes(der2, der2_len));
3122 EXPECT_EQ(Bytes(der, der_len), Bytes(der3, der3_len));
David Benjaminb2ff2622017-02-03 17:06:18 -05003123}
3124
Adam Langleyd04ca952017-02-28 11:26:51 -08003125TEST(SSLTest, SetChainAndKeyMismatch) {
3126 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_with_buffers_method()));
3127 ASSERT_TRUE(ctx);
3128
3129 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3130 ASSERT_TRUE(key);
3131 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3132 ASSERT_TRUE(leaf);
3133 std::vector<CRYPTO_BUFFER*> chain = {
3134 leaf.get(),
3135 };
3136
3137 // Should fail because |GetTestKey| doesn't match the chain-test certificate.
3138 ASSERT_FALSE(SSL_CTX_set_chain_and_key(ctx.get(), &chain[0], chain.size(),
3139 key.get(), nullptr));
3140 ERR_clear_error();
3141}
3142
3143TEST(SSLTest, SetChainAndKey) {
3144 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3145 ASSERT_TRUE(client_ctx);
3146 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3147 ASSERT_TRUE(server_ctx);
3148
3149 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3150 ASSERT_TRUE(key);
3151 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3152 ASSERT_TRUE(leaf);
3153 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3154 GetChainTestIntermediateBuffer();
3155 ASSERT_TRUE(intermediate);
3156 std::vector<CRYPTO_BUFFER*> chain = {
3157 leaf.get(), intermediate.get(),
3158 };
3159 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3160 chain.size(), key.get(), nullptr));
3161
David Benjamin3a1dd462017-07-11 16:13:10 -04003162 SSL_CTX_set_custom_verify(
3163 client_ctx.get(), SSL_VERIFY_PEER,
3164 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3165 return ssl_verify_ok;
3166 });
Adam Langleyd04ca952017-02-28 11:26:51 -08003167
3168 bssl::UniquePtr<SSL> client, server;
3169 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003170 server_ctx.get()));
Adam Langleyd04ca952017-02-28 11:26:51 -08003171}
3172
Matthew Braithwaite5301c102018-01-23 12:08:55 -08003173TEST(SSLTest, BuffersFailWithoutCustomVerify) {
3174 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3175 ASSERT_TRUE(client_ctx);
3176 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3177 ASSERT_TRUE(server_ctx);
3178
3179 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3180 ASSERT_TRUE(key);
3181 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3182 ASSERT_TRUE(leaf);
3183 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
3184 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3185 chain.size(), key.get(), nullptr));
3186
3187 // Without SSL_CTX_set_custom_verify(), i.e. with everything in the default
3188 // configuration, certificate verification should fail.
3189 bssl::UniquePtr<SSL> client, server;
3190 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3191 server_ctx.get()));
3192
3193 // Whereas with a verifier, the connection should succeed.
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_ok;
3198 });
3199 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3200 server_ctx.get()));
3201}
3202
3203TEST(SSLTest, CustomVerify) {
3204 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3205 ASSERT_TRUE(client_ctx);
3206 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3207 ASSERT_TRUE(server_ctx);
3208
3209 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3210 ASSERT_TRUE(key);
3211 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3212 ASSERT_TRUE(leaf);
3213 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
3214 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3215 chain.size(), key.get(), nullptr));
3216
3217 SSL_CTX_set_custom_verify(
3218 client_ctx.get(), SSL_VERIFY_PEER,
3219 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3220 return ssl_verify_ok;
3221 });
3222
3223 bssl::UniquePtr<SSL> client, server;
3224 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3225 server_ctx.get()));
3226
3227 // With SSL_VERIFY_PEER, ssl_verify_invalid should result in a dropped
3228 // connection.
3229 SSL_CTX_set_custom_verify(
3230 client_ctx.get(), SSL_VERIFY_PEER,
3231 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3232 return ssl_verify_invalid;
3233 });
3234
3235 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3236 server_ctx.get()));
3237
3238 // But with SSL_VERIFY_NONE, ssl_verify_invalid should not cause a dropped
3239 // connection.
3240 SSL_CTX_set_custom_verify(
3241 client_ctx.get(), SSL_VERIFY_NONE,
3242 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3243 return ssl_verify_invalid;
3244 });
3245
3246 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3247 server_ctx.get()));
3248}
3249
David Benjamin71dfad42017-07-16 17:27:39 -04003250TEST(SSLTest, ClientCABuffers) {
3251 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3252 ASSERT_TRUE(client_ctx);
3253 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3254 ASSERT_TRUE(server_ctx);
3255
3256 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3257 ASSERT_TRUE(key);
3258 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3259 ASSERT_TRUE(leaf);
3260 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3261 GetChainTestIntermediateBuffer();
3262 ASSERT_TRUE(intermediate);
3263 std::vector<CRYPTO_BUFFER *> chain = {
3264 leaf.get(),
3265 intermediate.get(),
3266 };
3267 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3268 chain.size(), key.get(), nullptr));
3269
3270 bssl::UniquePtr<CRYPTO_BUFFER> ca_name(
3271 CRYPTO_BUFFER_new(kTestName, sizeof(kTestName), nullptr));
3272 ASSERT_TRUE(ca_name);
3273 bssl::UniquePtr<STACK_OF(CRYPTO_BUFFER)> ca_names(
3274 sk_CRYPTO_BUFFER_new_null());
3275 ASSERT_TRUE(ca_names);
3276 ASSERT_TRUE(sk_CRYPTO_BUFFER_push(ca_names.get(), ca_name.get()));
3277 ca_name.release();
3278 SSL_CTX_set0_client_CAs(server_ctx.get(), ca_names.release());
3279
3280 // Configure client and server to accept all certificates.
3281 SSL_CTX_set_custom_verify(
3282 client_ctx.get(), SSL_VERIFY_PEER,
3283 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3284 return ssl_verify_ok;
3285 });
3286 SSL_CTX_set_custom_verify(
3287 server_ctx.get(), SSL_VERIFY_PEER,
3288 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3289 return ssl_verify_ok;
3290 });
3291
3292 bool cert_cb_called = false;
3293 SSL_CTX_set_cert_cb(
3294 client_ctx.get(),
3295 [](SSL *ssl, void *arg) -> int {
David Benjamin5f001d12018-05-08 16:46:48 -04003296 const STACK_OF(CRYPTO_BUFFER) *peer_names =
David Benjamin71dfad42017-07-16 17:27:39 -04003297 SSL_get0_server_requested_CAs(ssl);
3298 EXPECT_EQ(1u, sk_CRYPTO_BUFFER_num(peer_names));
3299 CRYPTO_BUFFER *peer_name = sk_CRYPTO_BUFFER_value(peer_names, 0);
3300 EXPECT_EQ(Bytes(kTestName), Bytes(CRYPTO_BUFFER_data(peer_name),
3301 CRYPTO_BUFFER_len(peer_name)));
3302 *reinterpret_cast<bool *>(arg) = true;
3303 return 1;
3304 },
3305 &cert_cb_called);
3306
3307 bssl::UniquePtr<SSL> client, server;
3308 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003309 server_ctx.get()));
David Benjamin71dfad42017-07-16 17:27:39 -04003310 EXPECT_TRUE(cert_cb_called);
3311}
3312
David Benjamin91222b82017-03-09 20:10:56 -05003313// Configuring the empty cipher list, though an error, should still modify the
3314// configuration.
3315TEST(SSLTest, EmptyCipherList) {
3316 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3317 ASSERT_TRUE(ctx);
3318
3319 // Initially, the cipher list is not empty.
3320 EXPECT_NE(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3321
3322 // Configuring the empty cipher list fails.
3323 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), ""));
3324 ERR_clear_error();
3325
3326 // But the cipher list is still updated to empty.
3327 EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3328}
3329
Adam Langley4c341d02017-03-08 19:33:21 -08003330// ssl_test_ticket_aead_failure_mode enumerates the possible ways in which the
3331// test |SSL_TICKET_AEAD_METHOD| can fail.
3332enum ssl_test_ticket_aead_failure_mode {
3333 ssl_test_ticket_aead_ok = 0,
3334 ssl_test_ticket_aead_seal_fail,
3335 ssl_test_ticket_aead_open_soft_fail,
3336 ssl_test_ticket_aead_open_hard_fail,
3337};
3338
3339struct ssl_test_ticket_aead_state {
3340 unsigned retry_count;
3341 ssl_test_ticket_aead_failure_mode failure_mode;
3342};
3343
3344static int ssl_test_ticket_aead_ex_index_dup(CRYPTO_EX_DATA *to,
3345 const CRYPTO_EX_DATA *from,
3346 void **from_d, int index,
3347 long argl, void *argp) {
3348 abort();
3349}
3350
3351static void ssl_test_ticket_aead_ex_index_free(void *parent, void *ptr,
3352 CRYPTO_EX_DATA *ad, int index,
3353 long argl, void *argp) {
3354 auto state = reinterpret_cast<ssl_test_ticket_aead_state*>(ptr);
3355 if (state == nullptr) {
3356 return;
3357 }
3358
3359 OPENSSL_free(state);
3360}
3361
3362static CRYPTO_once_t g_ssl_test_ticket_aead_ex_index_once = CRYPTO_ONCE_INIT;
3363static int g_ssl_test_ticket_aead_ex_index;
3364
3365static int ssl_test_ticket_aead_get_ex_index() {
3366 CRYPTO_once(&g_ssl_test_ticket_aead_ex_index_once, [] {
3367 g_ssl_test_ticket_aead_ex_index = SSL_get_ex_new_index(
3368 0, nullptr, nullptr, ssl_test_ticket_aead_ex_index_dup,
3369 ssl_test_ticket_aead_ex_index_free);
3370 });
3371 return g_ssl_test_ticket_aead_ex_index;
3372}
3373
3374static size_t ssl_test_ticket_aead_max_overhead(SSL *ssl) {
3375 return 1;
3376}
3377
3378static int ssl_test_ticket_aead_seal(SSL *ssl, uint8_t *out, size_t *out_len,
3379 size_t max_out_len, const uint8_t *in,
3380 size_t in_len) {
3381 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3382 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3383
3384 if (state->failure_mode == ssl_test_ticket_aead_seal_fail ||
3385 max_out_len < in_len + 1) {
3386 return 0;
3387 }
3388
3389 OPENSSL_memmove(out, in, in_len);
3390 out[in_len] = 0xff;
3391 *out_len = in_len + 1;
3392
3393 return 1;
3394}
3395
3396static ssl_ticket_aead_result_t ssl_test_ticket_aead_open(
3397 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len,
3398 const uint8_t *in, size_t in_len) {
3399 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3400 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3401
3402 if (state->retry_count > 0) {
3403 state->retry_count--;
3404 return ssl_ticket_aead_retry;
3405 }
3406
3407 switch (state->failure_mode) {
3408 case ssl_test_ticket_aead_ok:
3409 break;
3410 case ssl_test_ticket_aead_seal_fail:
3411 // If |seal| failed then there shouldn't be any ticket to try and
3412 // decrypt.
3413 abort();
3414 break;
3415 case ssl_test_ticket_aead_open_soft_fail:
3416 return ssl_ticket_aead_ignore_ticket;
3417 case ssl_test_ticket_aead_open_hard_fail:
3418 return ssl_ticket_aead_error;
3419 }
3420
3421 if (in_len == 0 || in[in_len - 1] != 0xff) {
3422 return ssl_ticket_aead_ignore_ticket;
3423 }
3424
3425 if (max_out_len < in_len - 1) {
3426 return ssl_ticket_aead_error;
3427 }
3428
3429 OPENSSL_memmove(out, in, in_len - 1);
3430 *out_len = in_len - 1;
3431 return ssl_ticket_aead_success;
3432}
3433
3434static const SSL_TICKET_AEAD_METHOD kSSLTestTicketMethod = {
3435 ssl_test_ticket_aead_max_overhead,
3436 ssl_test_ticket_aead_seal,
3437 ssl_test_ticket_aead_open,
3438};
3439
3440static void ConnectClientAndServerWithTicketMethod(
3441 bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
3442 SSL_CTX *client_ctx, SSL_CTX *server_ctx, unsigned retry_count,
3443 ssl_test_ticket_aead_failure_mode failure_mode, SSL_SESSION *session) {
3444 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
3445 ASSERT_TRUE(client);
3446 ASSERT_TRUE(server);
3447 SSL_set_connect_state(client.get());
3448 SSL_set_accept_state(server.get());
3449
3450 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3451 OPENSSL_malloc(sizeof(ssl_test_ticket_aead_state)));
3452 ASSERT_TRUE(state);
3453 OPENSSL_memset(state, 0, sizeof(ssl_test_ticket_aead_state));
3454 state->retry_count = retry_count;
3455 state->failure_mode = failure_mode;
3456
3457 ASSERT_TRUE(SSL_set_ex_data(server.get(), ssl_test_ticket_aead_get_ex_index(),
3458 state));
3459
3460 SSL_set_session(client.get(), session);
3461
3462 BIO *bio1, *bio2;
3463 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
3464
3465 // SSL_set_bio takes ownership.
3466 SSL_set_bio(client.get(), bio1, bio1);
3467 SSL_set_bio(server.get(), bio2, bio2);
3468
3469 if (CompleteHandshakes(client.get(), server.get())) {
3470 *out_client = std::move(client);
3471 *out_server = std::move(server);
3472 } else {
3473 out_client->reset();
3474 out_server->reset();
3475 }
3476}
3477
David Benjaminc9775322018-04-13 16:39:12 -04003478using TicketAEADMethodParam =
3479 testing::tuple<uint16_t, unsigned, ssl_test_ticket_aead_failure_mode>;
3480
Adam Langley4c341d02017-03-08 19:33:21 -08003481class TicketAEADMethodTest
David Benjaminc9775322018-04-13 16:39:12 -04003482 : public ::testing::TestWithParam<TicketAEADMethodParam> {};
Adam Langley4c341d02017-03-08 19:33:21 -08003483
3484TEST_P(TicketAEADMethodTest, Resume) {
3485 bssl::UniquePtr<X509> cert = GetTestCertificate();
3486 ASSERT_TRUE(cert);
3487 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3488 ASSERT_TRUE(key);
3489
3490 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
3491 ASSERT_TRUE(server_ctx);
3492 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
3493 ASSERT_TRUE(client_ctx);
3494
3495 const uint16_t version = testing::get<0>(GetParam());
3496 const unsigned retry_count = testing::get<1>(GetParam());
3497 const ssl_test_ticket_aead_failure_mode failure_mode =
3498 testing::get<2>(GetParam());
3499
3500 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3501 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3502 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), version));
3503 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), version));
3504 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), version));
3505 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), version));
3506
3507 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
3508 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
3509 SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
3510 SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
David Benjamin707af292017-03-10 17:47:18 -05003511 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langley4c341d02017-03-08 19:33:21 -08003512
3513 SSL_CTX_set_ticket_aead_method(server_ctx.get(), &kSSLTestTicketMethod);
3514
3515 bssl::UniquePtr<SSL> client, server;
3516 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3517 server_ctx.get(), retry_count,
3518 failure_mode, nullptr);
3519 switch (failure_mode) {
3520 case ssl_test_ticket_aead_ok:
3521 case ssl_test_ticket_aead_open_hard_fail:
3522 case ssl_test_ticket_aead_open_soft_fail:
3523 ASSERT_TRUE(client);
3524 break;
3525 case ssl_test_ticket_aead_seal_fail:
3526 EXPECT_FALSE(client);
3527 return;
3528 }
3529 EXPECT_FALSE(SSL_session_reused(client.get()));
3530 EXPECT_FALSE(SSL_session_reused(server.get()));
3531
David Benjamin707af292017-03-10 17:47:18 -05003532 // Run the read loop to account for post-handshake tickets in TLS 1.3.
3533 SSL_read(client.get(), nullptr, 0);
3534
3535 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
Adam Langley4c341d02017-03-08 19:33:21 -08003536 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3537 server_ctx.get(), retry_count,
David Benjamin707af292017-03-10 17:47:18 -05003538 failure_mode, session.get());
Adam Langley4c341d02017-03-08 19:33:21 -08003539 switch (failure_mode) {
3540 case ssl_test_ticket_aead_ok:
3541 ASSERT_TRUE(client);
3542 EXPECT_TRUE(SSL_session_reused(client.get()));
3543 EXPECT_TRUE(SSL_session_reused(server.get()));
3544 break;
3545 case ssl_test_ticket_aead_seal_fail:
3546 abort();
3547 break;
3548 case ssl_test_ticket_aead_open_hard_fail:
3549 EXPECT_FALSE(client);
3550 break;
3551 case ssl_test_ticket_aead_open_soft_fail:
3552 ASSERT_TRUE(client);
3553 EXPECT_FALSE(SSL_session_reused(client.get()));
3554 EXPECT_FALSE(SSL_session_reused(server.get()));
3555 }
3556}
3557
David Benjaminc9775322018-04-13 16:39:12 -04003558std::string TicketAEADMethodParamToString(
3559 const testing::TestParamInfo<TicketAEADMethodParam> &params) {
3560 std::string ret = GetVersionName(std::get<0>(params.param));
3561 // GTest only allows alphanumeric characters and '_' in the parameter
3562 // string. Additionally filter out the 'v' to get "TLS13" over "TLSv13".
3563 for (auto it = ret.begin(); it != ret.end();) {
3564 if (*it == '.' || *it == 'v') {
3565 it = ret.erase(it);
3566 } else {
3567 ++it;
3568 }
3569 }
3570 char retry_count[256];
3571 snprintf(retry_count, sizeof(retry_count), "%d", std::get<1>(params.param));
3572 ret += "_";
3573 ret += retry_count;
3574 ret += "Retries_";
3575 switch (std::get<2>(params.param)) {
3576 case ssl_test_ticket_aead_ok:
3577 ret += "OK";
3578 break;
3579 case ssl_test_ticket_aead_seal_fail:
3580 ret += "SealFail";
3581 break;
3582 case ssl_test_ticket_aead_open_soft_fail:
3583 ret += "OpenSoftFail";
3584 break;
3585 case ssl_test_ticket_aead_open_hard_fail:
3586 ret += "OpenHardFail";
3587 break;
3588 }
3589 return ret;
3590}
3591
Adam Langley4c341d02017-03-08 19:33:21 -08003592INSTANTIATE_TEST_CASE_P(
3593 TicketAEADMethodTests, TicketAEADMethodTest,
David Benjaminc9775322018-04-13 16:39:12 -04003594 testing::Combine(testing::Values(TLS1_2_VERSION, TLS1_3_VERSION),
3595 testing::Values(0, 1, 2),
3596 testing::Values(ssl_test_ticket_aead_ok,
3597 ssl_test_ticket_aead_seal_fail,
3598 ssl_test_ticket_aead_open_soft_fail,
3599 ssl_test_ticket_aead_open_hard_fail)),
3600 TicketAEADMethodParamToString);
Adam Langley4c341d02017-03-08 19:33:21 -08003601
David Benjaminca743582017-06-15 17:51:35 -04003602TEST(SSLTest, SelectNextProto) {
3603 uint8_t *result;
3604 uint8_t result_len;
3605
3606 // If there is an overlap, it should be returned.
3607 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3608 SSL_select_next_proto(&result, &result_len,
3609 (const uint8_t *)"\1a\2bb\3ccc", 9,
3610 (const uint8_t *)"\1x\1y\1a\1z", 8));
3611 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
3612
3613 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3614 SSL_select_next_proto(&result, &result_len,
3615 (const uint8_t *)"\1a\2bb\3ccc", 9,
3616 (const uint8_t *)"\1x\1y\2bb\1z", 9));
3617 EXPECT_EQ(Bytes("bb"), Bytes(result, result_len));
3618
3619 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3620 SSL_select_next_proto(&result, &result_len,
3621 (const uint8_t *)"\1a\2bb\3ccc", 9,
3622 (const uint8_t *)"\1x\1y\3ccc\1z", 10));
3623 EXPECT_EQ(Bytes("ccc"), Bytes(result, result_len));
3624
3625 // Peer preference order takes precedence over local.
3626 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3627 SSL_select_next_proto(&result, &result_len,
3628 (const uint8_t *)"\1a\2bb\3ccc", 9,
3629 (const uint8_t *)"\3ccc\2bb\1a", 9));
3630 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
3631
3632 // If there is no overlap, return the first local protocol.
3633 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
3634 SSL_select_next_proto(&result, &result_len,
3635 (const uint8_t *)"\1a\2bb\3ccc", 9,
3636 (const uint8_t *)"\1x\2yy\3zzz", 9));
3637 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
3638
3639 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
3640 SSL_select_next_proto(&result, &result_len, nullptr, 0,
3641 (const uint8_t *)"\1x\2yy\3zzz", 9));
3642 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
3643}
3644
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003645TEST(SSLTest, SealRecord) {
3646 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3647 server_ctx(SSL_CTX_new(TLS_method()));
3648 ASSERT_TRUE(client_ctx);
3649 ASSERT_TRUE(server_ctx);
3650
3651 bssl::UniquePtr<X509> cert = GetTestCertificate();
3652 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3653 ASSERT_TRUE(cert);
3654 ASSERT_TRUE(key);
3655 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3656 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3657
3658 bssl::UniquePtr<SSL> client, server;
3659 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003660 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003661
3662 const std::vector<uint8_t> record = {1, 2, 3, 4, 5};
3663 std::vector<uint8_t> prefix(
3664 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003665 body(record.size()),
3666 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003667 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3668 bssl::MakeSpan(body), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003669 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003670
3671 std::vector<uint8_t> sealed;
3672 sealed.insert(sealed.end(), prefix.begin(), prefix.end());
3673 sealed.insert(sealed.end(), body.begin(), body.end());
3674 sealed.insert(sealed.end(), suffix.begin(), suffix.end());
3675 std::vector<uint8_t> sealed_copy = sealed;
3676
3677 bssl::Span<uint8_t> plaintext;
3678 size_t record_len;
3679 uint8_t alert = 255;
3680 EXPECT_EQ(bssl::OpenRecord(server.get(), &plaintext, &record_len, &alert,
3681 bssl::MakeSpan(sealed)),
3682 bssl::OpenRecordResult::kOK);
3683 EXPECT_EQ(record_len, sealed.size());
3684 EXPECT_EQ(plaintext, record);
3685 EXPECT_EQ(255, alert);
3686}
3687
3688TEST(SSLTest, SealRecordInPlace) {
3689 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3690 server_ctx(SSL_CTX_new(TLS_method()));
3691 ASSERT_TRUE(client_ctx);
3692 ASSERT_TRUE(server_ctx);
3693
3694 bssl::UniquePtr<X509> cert = GetTestCertificate();
3695 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3696 ASSERT_TRUE(cert);
3697 ASSERT_TRUE(key);
3698 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3699 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3700
3701 bssl::UniquePtr<SSL> client, server;
3702 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003703 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003704
3705 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
3706 std::vector<uint8_t> record = plaintext;
3707 std::vector<uint8_t> prefix(
3708 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003709 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003710 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3711 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003712 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003713 record.insert(record.begin(), prefix.begin(), prefix.end());
3714 record.insert(record.end(), suffix.begin(), suffix.end());
3715
3716 bssl::Span<uint8_t> result;
3717 size_t record_len;
3718 uint8_t alert;
3719 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
3720 bssl::MakeSpan(record)),
3721 bssl::OpenRecordResult::kOK);
3722 EXPECT_EQ(record_len, record.size());
3723 EXPECT_EQ(plaintext, result);
3724}
3725
3726TEST(SSLTest, SealRecordTrailingData) {
3727 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3728 server_ctx(SSL_CTX_new(TLS_method()));
3729 ASSERT_TRUE(client_ctx);
3730 ASSERT_TRUE(server_ctx);
3731
3732 bssl::UniquePtr<X509> cert = GetTestCertificate();
3733 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3734 ASSERT_TRUE(cert);
3735 ASSERT_TRUE(key);
3736 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3737 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3738
3739 bssl::UniquePtr<SSL> client, server;
3740 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003741 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003742
3743 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
3744 std::vector<uint8_t> record = plaintext;
3745 std::vector<uint8_t> prefix(
3746 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003747 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003748 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3749 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003750 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003751 record.insert(record.begin(), prefix.begin(), prefix.end());
3752 record.insert(record.end(), suffix.begin(), suffix.end());
3753 record.insert(record.end(), {5, 4, 3, 2, 1});
3754
3755 bssl::Span<uint8_t> result;
3756 size_t record_len;
3757 uint8_t alert;
3758 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
3759 bssl::MakeSpan(record)),
3760 bssl::OpenRecordResult::kOK);
3761 EXPECT_EQ(record_len, record.size() - 5);
3762 EXPECT_EQ(plaintext, result);
3763}
3764
3765TEST(SSLTest, SealRecordInvalidSpanSize) {
3766 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3767 server_ctx(SSL_CTX_new(TLS_method()));
3768 ASSERT_TRUE(client_ctx);
3769 ASSERT_TRUE(server_ctx);
3770
3771 bssl::UniquePtr<X509> cert = GetTestCertificate();
3772 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3773 ASSERT_TRUE(cert);
3774 ASSERT_TRUE(key);
3775 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3776 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3777
3778 bssl::UniquePtr<SSL> client, server;
3779 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003780 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003781
3782 std::vector<uint8_t> record = {1, 2, 3, 4, 5};
3783 std::vector<uint8_t> prefix(
3784 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003785 body(record.size()),
3786 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003787
3788 auto expect_err = []() {
3789 int err = ERR_get_error();
3790 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
3791 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_BUFFER_TOO_SMALL);
3792 ERR_clear_error();
3793 };
3794 EXPECT_FALSE(bssl::SealRecord(
3795 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003796 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003797 expect_err();
3798 EXPECT_FALSE(bssl::SealRecord(
3799 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003800 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003801 expect_err();
3802
3803 EXPECT_FALSE(
3804 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3805 bssl::MakeSpan(record.data(), record.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003806 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003807 expect_err();
3808 EXPECT_FALSE(
3809 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3810 bssl::MakeSpan(record.data(), record.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003811 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003812 expect_err();
3813
3814 EXPECT_FALSE(bssl::SealRecord(
3815 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003816 bssl::MakeSpan(suffix.data(), suffix.size() - 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003817 expect_err();
3818 EXPECT_FALSE(bssl::SealRecord(
3819 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003820 bssl::MakeSpan(suffix.data(), suffix.size() + 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003821 expect_err();
3822}
3823
David Benjamin617b8182017-08-29 15:33:10 -04003824// The client should gracefully handle no suitable ciphers being enabled.
3825TEST(SSLTest, NoCiphersAvailable) {
3826 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3827 ASSERT_TRUE(ctx);
3828
3829 // Configure |client_ctx| with a cipher list that does not intersect with its
3830 // version configuration.
3831 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
3832 ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
3833 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
3834
3835 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3836 ASSERT_TRUE(ssl);
3837 SSL_set_connect_state(ssl.get());
3838
3839 UniquePtr<BIO> rbio(BIO_new(BIO_s_mem())), wbio(BIO_new(BIO_s_mem()));
3840 ASSERT_TRUE(rbio);
3841 ASSERT_TRUE(wbio);
3842 SSL_set0_rbio(ssl.get(), rbio.release());
3843 SSL_set0_wbio(ssl.get(), wbio.release());
3844
3845 int ret = SSL_do_handshake(ssl.get());
3846 EXPECT_EQ(-1, ret);
3847 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), ret));
3848 uint32_t err = ERR_get_error();
3849 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
3850 EXPECT_EQ(SSL_R_NO_CIPHERS_AVAILABLE, ERR_GET_REASON(err));
3851}
3852
David Benjamina4bafd32017-10-03 15:06:29 -04003853TEST_P(SSLVersionTest, SessionVersion) {
3854 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3855 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3856
3857 bssl::UniquePtr<SSL_SESSION> session =
3858 CreateClientSession(client_ctx_.get(), server_ctx_.get());
3859 ASSERT_TRUE(session);
3860 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
3861
3862 // Sessions in TLS 1.3 and later should be single-use.
3863 EXPECT_EQ(version() == TLS1_3_VERSION,
3864 !!SSL_SESSION_should_be_single_use(session.get()));
3865
3866 // Making fake sessions for testing works.
3867 session.reset(SSL_SESSION_new(client_ctx_.get()));
3868 ASSERT_TRUE(session);
3869 ASSERT_TRUE(SSL_SESSION_set_protocol_version(session.get(), version()));
3870 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
3871}
3872
David Benjaminfdb7a352017-10-12 17:34:18 -04003873TEST_P(SSLVersionTest, SSLPending) {
3874 UniquePtr<SSL> ssl(SSL_new(client_ctx_.get()));
3875 ASSERT_TRUE(ssl);
3876 EXPECT_EQ(0, SSL_pending(ssl.get()));
3877
3878 ASSERT_TRUE(Connect());
3879 EXPECT_EQ(0, SSL_pending(client_.get()));
3880
3881 ASSERT_EQ(5, SSL_write(server_.get(), "hello", 5));
3882 ASSERT_EQ(5, SSL_write(server_.get(), "world", 5));
3883 EXPECT_EQ(0, SSL_pending(client_.get()));
3884
3885 char buf[10];
3886 ASSERT_EQ(1, SSL_peek(client_.get(), buf, 1));
3887 EXPECT_EQ(5, SSL_pending(client_.get()));
3888
3889 ASSERT_EQ(1, SSL_read(client_.get(), buf, 1));
3890 EXPECT_EQ(4, SSL_pending(client_.get()));
3891
3892 ASSERT_EQ(4, SSL_read(client_.get(), buf, 10));
3893 EXPECT_EQ(0, SSL_pending(client_.get()));
3894
3895 ASSERT_EQ(2, SSL_read(client_.get(), buf, 2));
3896 EXPECT_EQ(3, SSL_pending(client_.get()));
3897}
3898
David Benjamina031b612017-10-11 20:48:25 -04003899// Test that post-handshake tickets consumed by |SSL_shutdown| are ignored.
3900TEST(SSLTest, ShutdownIgnoresTickets) {
3901 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3902 ASSERT_TRUE(ctx);
3903 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_3_VERSION));
3904 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
3905
3906 bssl::UniquePtr<X509> cert = GetTestCertificate();
3907 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3908 ASSERT_TRUE(cert);
3909 ASSERT_TRUE(key);
3910 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
3911 ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
3912
3913 SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_BOTH);
3914
3915 bssl::UniquePtr<SSL> client, server;
3916 ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
3917
3918 SSL_CTX_sess_set_new_cb(ctx.get(), [](SSL *ssl, SSL_SESSION *session) -> int {
3919 ADD_FAILURE() << "New session callback called during SSL_shutdown";
3920 return 0;
3921 });
3922
3923 // Send close_notify.
3924 EXPECT_EQ(0, SSL_shutdown(server.get()));
3925 EXPECT_EQ(0, SSL_shutdown(client.get()));
3926
3927 // Receive close_notify.
3928 EXPECT_EQ(1, SSL_shutdown(server.get()));
3929 EXPECT_EQ(1, SSL_shutdown(client.get()));
3930}
3931
David Benjamin6cc352e2017-11-02 17:21:39 -04003932TEST(SSLTest, SignatureAlgorithmProperties) {
3933 EXPECT_EQ(EVP_PKEY_NONE, SSL_get_signature_algorithm_key_type(0x1234));
3934 EXPECT_EQ(nullptr, SSL_get_signature_algorithm_digest(0x1234));
3935 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(0x1234));
3936
3937 EXPECT_EQ(EVP_PKEY_RSA,
3938 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
3939 EXPECT_EQ(EVP_md5_sha1(),
3940 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
3941 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
3942
3943 EXPECT_EQ(EVP_PKEY_EC, SSL_get_signature_algorithm_key_type(
3944 SSL_SIGN_ECDSA_SECP256R1_SHA256));
3945 EXPECT_EQ(EVP_sha256(), SSL_get_signature_algorithm_digest(
3946 SSL_SIGN_ECDSA_SECP256R1_SHA256));
3947 EXPECT_FALSE(
3948 SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_ECDSA_SECP256R1_SHA256));
3949
3950 EXPECT_EQ(EVP_PKEY_RSA,
David Benjamin6879e192018-04-13 16:01:02 -04003951 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04003952 EXPECT_EQ(EVP_sha384(),
David Benjamin6879e192018-04-13 16:01:02 -04003953 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PSS_RSAE_SHA384));
3954 EXPECT_TRUE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04003955}
3956
Adam Langley0080d832018-06-07 16:39:49 -07003957static bool XORCompressFunc(SSL *ssl, CBB *out, Span<const uint8_t> in) {
3958 for (size_t i = 0; i < in.size(); i++) {
3959 if (!CBB_add_u8(out, in[i] ^ 0x55)) {
3960 return false;
3961 }
3962 }
3963
3964 SSL_set_app_data(ssl, XORCompressFunc);
3965
3966 return true;
3967}
3968
3969static bool XORDecompressFunc(SSL *ssl, bssl::UniquePtr<CRYPTO_BUFFER> *out,
3970 size_t uncompressed_len, Span<const uint8_t> in) {
3971 if (in.size() != uncompressed_len) {
3972 return false;
3973 }
3974
3975 uint8_t *data;
3976 out->reset(CRYPTO_BUFFER_alloc(&data, uncompressed_len));
3977 if (out->get() == nullptr) {
3978 return false;
3979 }
3980
3981 for (size_t i = 0; i < in.size(); i++) {
3982 data[i] = in[i] ^ 0x55;
3983 }
3984
3985 SSL_set_app_data(ssl, XORDecompressFunc);
3986
3987 return true;
3988}
3989
3990TEST(SSLTest, CertCompression) {
3991 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
3992 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
3993 ASSERT_TRUE(client_ctx);
3994 ASSERT_TRUE(server_ctx);
3995
3996 bssl::UniquePtr<X509> cert = GetTestCertificate();
3997 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3998 ASSERT_TRUE(cert);
3999 ASSERT_TRUE(key);
4000 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
4001 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
4002
4003 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
4004 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
4005 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
4006 client_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
4007 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
4008 server_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
4009
4010 bssl::UniquePtr<SSL> client, server;
4011 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4012 server_ctx.get()));
4013
4014 EXPECT_TRUE(SSL_get_app_data(client.get()) == XORDecompressFunc);
4015 EXPECT_TRUE(SSL_get_app_data(server.get()) == XORCompressFunc);
4016}
4017
Adam Langleyddb57cf2018-01-26 09:17:53 -08004018void MoveBIOs(SSL *dest, SSL *src) {
4019 BIO *rbio = SSL_get_rbio(src);
4020 BIO_up_ref(rbio);
4021 SSL_set0_rbio(dest, rbio);
4022
4023 BIO *wbio = SSL_get_wbio(src);
4024 BIO_up_ref(wbio);
4025 SSL_set0_wbio(dest, wbio);
4026
4027 SSL_set0_rbio(src, nullptr);
4028 SSL_set0_wbio(src, nullptr);
4029}
4030
4031TEST(SSLTest, Handoff) {
4032 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4033 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4034 bssl::UniquePtr<SSL_CTX> handshaker_ctx(SSL_CTX_new(TLS_method()));
4035 ASSERT_TRUE(client_ctx);
4036 ASSERT_TRUE(server_ctx);
4037 ASSERT_TRUE(handshaker_ctx);
4038
4039 SSL_CTX_set_handoff_mode(server_ctx.get(), 1);
4040 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
4041 ASSERT_TRUE(
4042 SSL_CTX_set_max_proto_version(handshaker_ctx.get(), TLS1_2_VERSION));
4043
4044 bssl::UniquePtr<X509> cert = GetTestCertificate();
4045 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4046 ASSERT_TRUE(cert);
4047 ASSERT_TRUE(key);
4048 ASSERT_TRUE(SSL_CTX_use_certificate(handshaker_ctx.get(), cert.get()));
4049 ASSERT_TRUE(SSL_CTX_use_PrivateKey(handshaker_ctx.get(), key.get()));
4050
4051 bssl::UniquePtr<SSL> client, server;
4052 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4053 server_ctx.get(), ClientConfig(),
4054 false /* don't handshake */));
4055
4056 int client_ret = SSL_do_handshake(client.get());
4057 int client_err = SSL_get_error(client.get(), client_ret);
4058 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4059
4060 int server_ret = SSL_do_handshake(server.get());
4061 int server_err = SSL_get_error(server.get(), server_ret);
4062 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
4063
4064 ScopedCBB cbb;
4065 Array<uint8_t> handoff;
4066 ASSERT_TRUE(CBB_init(cbb.get(), 256));
4067 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get()));
4068 ASSERT_TRUE(CBBFinishArray(cbb.get(), &handoff));
4069
4070 bssl::UniquePtr<SSL> handshaker(SSL_new(handshaker_ctx.get()));
4071 ASSERT_TRUE(SSL_apply_handoff(handshaker.get(), handoff));
4072
4073 MoveBIOs(handshaker.get(), server.get());
4074
4075 int handshake_ret = SSL_do_handshake(handshaker.get());
4076 int handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
Matthew Braithwaite56986f92018-03-22 11:48:33 -07004077 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
Adam Langleyddb57cf2018-01-26 09:17:53 -08004078
Matthew Braithwaite56986f92018-03-22 11:48:33 -07004079 // Double-check that additional calls to |SSL_do_handshake| continue
4080 // to get |SSL_ERRROR_HANDBACK|.
4081 handshake_ret = SSL_do_handshake(handshaker.get());
4082 handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
4083 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
Adam Langleyddb57cf2018-01-26 09:17:53 -08004084
4085 ScopedCBB cbb_handback;
4086 Array<uint8_t> handback;
4087 ASSERT_TRUE(CBB_init(cbb_handback.get(), 1024));
4088 ASSERT_TRUE(SSL_serialize_handback(handshaker.get(), cbb_handback.get()));
4089 ASSERT_TRUE(CBBFinishArray(cbb_handback.get(), &handback));
4090
4091 bssl::UniquePtr<SSL> server2(SSL_new(server_ctx.get()));
4092 ASSERT_TRUE(SSL_apply_handback(server2.get(), handback));
4093
4094 MoveBIOs(server2.get(), handshaker.get());
Matthew Braithwaite56986f92018-03-22 11:48:33 -07004095 ASSERT_TRUE(CompleteHandshakes(client.get(), server2.get()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004096
4097 uint8_t byte = 42;
4098 EXPECT_EQ(SSL_write(client.get(), &byte, 1), 1);
4099 EXPECT_EQ(SSL_read(server2.get(), &byte, 1), 1);
4100 EXPECT_EQ(42, byte);
4101
4102 byte = 43;
4103 EXPECT_EQ(SSL_write(server2.get(), &byte, 1), 1);
4104 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
4105 EXPECT_EQ(43, byte);
4106}
4107
4108TEST(SSLTest, HandoffDeclined) {
4109 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4110 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4111 ASSERT_TRUE(client_ctx);
4112 ASSERT_TRUE(server_ctx);
4113
4114 SSL_CTX_set_handoff_mode(server_ctx.get(), 1);
4115 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
4116
4117 bssl::UniquePtr<X509> cert = GetTestCertificate();
4118 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4119 ASSERT_TRUE(cert);
4120 ASSERT_TRUE(key);
4121 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
4122 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
4123
4124 bssl::UniquePtr<SSL> client, server;
4125 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4126 server_ctx.get(), ClientConfig(),
4127 false /* don't handshake */));
4128
4129 int client_ret = SSL_do_handshake(client.get());
4130 int client_err = SSL_get_error(client.get(), client_ret);
4131 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4132
4133 int server_ret = SSL_do_handshake(server.get());
4134 int server_err = SSL_get_error(server.get(), server_ret);
4135 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
4136
4137 ScopedCBB cbb;
4138 ASSERT_TRUE(CBB_init(cbb.get(), 256));
4139 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get()));
4140
4141 ASSERT_TRUE(SSL_decline_handoff(server.get()));
4142
4143 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
4144
4145 uint8_t byte = 42;
4146 EXPECT_EQ(SSL_write(client.get(), &byte, 1), 1);
4147 EXPECT_EQ(SSL_read(server.get(), &byte, 1), 1);
4148 EXPECT_EQ(42, byte);
4149
4150 byte = 43;
4151 EXPECT_EQ(SSL_write(server.get(), &byte, 1), 1);
4152 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
4153 EXPECT_EQ(43, byte);
4154}
4155
David Benjamin96628432017-01-19 19:05:47 -05004156// TODO(davidben): Convert this file to GTest properly.
4157TEST(SSLTest, AllTests) {
David Benjamine11726a2017-04-23 12:14:28 -04004158 if (!TestSSL_SESSIONEncoding(kOpenSSLSession) ||
Adam Langley10f97f32016-07-12 08:09:33 -07004159 !TestSSL_SESSIONEncoding(kCustomSession) ||
4160 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
4161 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
4162 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
4163 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
Steven Valdeza833c352016-11-01 13:39:36 -04004164 // Test the padding extension at TLS 1.2.
4165 !TestPaddingExtension(TLS1_2_VERSION, TLS1_2_VERSION) ||
4166 // Test the padding extension at TLS 1.3 with a TLS 1.2 session, so there
4167 // will be no PSK binder after the padding extension.
4168 !TestPaddingExtension(TLS1_3_VERSION, TLS1_2_VERSION) ||
4169 // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
4170 // will be a PSK binder after the padding extension.
Steven Valdez74666da2018-01-09 06:18:36 -05004171 !TestPaddingExtension(TLS1_3_VERSION, TLS1_3_DRAFT23_VERSION)) {
David Benjamin96628432017-01-19 19:05:47 -05004172 ADD_FAILURE() << "Tests failed";
David Benjaminbb0a17c2014-09-20 15:35:39 -04004173 }
David Benjamin2e521212014-07-16 14:37:51 -04004174}
Martin Kreichgauer72912d22017-08-04 12:06:43 -07004175
4176} // namespace
4177} // namespace bssl