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