blob: 7f5361f981c4f6fc9547f0f7460ae7e1b0f8ca23 [file] [log] [blame]
David Benjamin2e521212014-07-16 14:37:51 -04001/* Copyright (c) 2014, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15#include <stdio.h>
David Benjamin751e8892014-10-19 00:59:36 -040016#include <string.h>
David Benjamin1269ddd2015-10-18 15:18:55 -040017#include <time.h>
David Benjamin2e521212014-07-16 14:37:51 -040018
David Benjamin0f653952015-10-18 14:28:01 -040019#include <algorithm>
David Benjamin1d77e562015-03-22 17:22:08 -040020#include <string>
David Benjamin4f6acaf2015-11-21 03:00:50 -050021#include <utility>
David Benjamin1d77e562015-03-22 17:22:08 -040022#include <vector>
23
David Benjamin96628432017-01-19 19:05:47 -050024#include <gtest/gtest.h>
25
David Benjamin751e8892014-10-19 00:59:36 -040026#include <openssl/base64.h>
27#include <openssl/bio.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040028#include <openssl/cipher.h>
David Benjamin7a1eefd2015-10-17 23:39:22 -040029#include <openssl/crypto.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040030#include <openssl/err.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040031#include <openssl/hmac.h>
David Benjaminde942382016-02-11 12:02:01 -050032#include <openssl/pem.h>
David Benjamin25490f22016-07-14 00:22:54 -040033#include <openssl/sha.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040034#include <openssl/ssl.h>
David Benjamin3c51d9b2016-11-01 17:50:42 -040035#include <openssl/rand.h>
David Benjaminde942382016-02-11 12:02:01 -050036#include <openssl/x509.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040037
Steven Valdez87eab492016-06-27 16:34:59 -040038#include "internal.h"
Steven Valdezcb966542016-08-17 16:56:14 -040039#include "../crypto/internal.h"
Sigbjorn Vik2b23d242015-06-29 15:07:26 +020040#include "../crypto/test/test_util.h"
41
David Benjamin721e8b72016-08-03 13:13:17 -040042#if defined(OPENSSL_WINDOWS)
David Benjaminc11ea9422017-08-29 16:33:21 -040043// Windows defines struct timeval in winsock2.h.
David Benjamin721e8b72016-08-03 13:13:17 -040044OPENSSL_MSVC_PRAGMA(warning(push, 3))
45#include <winsock2.h>
46OPENSSL_MSVC_PRAGMA(warning(pop))
47#else
48#include <sys/time.h>
49#endif
50
David Benjamin1d77e562015-03-22 17:22:08 -040051
Martin Kreichgauer72912d22017-08-04 12:06:43 -070052namespace bssl {
53
54namespace {
55
Martin Kreichgauer1a663262017-08-16 14:54:04 -070056#define TRACED_CALL(code) \
57 do { \
58 SCOPED_TRACE("<- called from here"); \
59 code; \
60 if (::testing::Test::HasFatalFailure()) { \
61 return; \
62 } \
63 } while (false)
64
Martin Kreichgauer72912d22017-08-04 12:06:43 -070065struct VersionParam {
66 uint16_t version;
67 enum { is_tls, is_dtls } ssl_method;
68 const char name[8];
69};
70
71static const size_t kTicketKeyLen = 48;
72
73static const VersionParam kAllVersions[] = {
Martin Kreichgauer72912d22017-08-04 12:06:43 -070074 {TLS1_VERSION, VersionParam::is_tls, "TLS1"},
75 {TLS1_1_VERSION, VersionParam::is_tls, "TLS1_1"},
76 {TLS1_2_VERSION, VersionParam::is_tls, "TLS1_2"},
Martin Kreichgauer72912d22017-08-04 12:06:43 -070077 {TLS1_3_VERSION, VersionParam::is_tls, "TLS1_3"},
Martin Kreichgauer72912d22017-08-04 12:06:43 -070078 {DTLS1_VERSION, VersionParam::is_dtls, "DTLS1"},
79 {DTLS1_2_VERSION, VersionParam::is_dtls, "DTLS1_2"},
80};
81
David Benjamin1d77e562015-03-22 17:22:08 -040082struct ExpectedCipher {
83 unsigned long id;
David Benjaminbb0a17c2014-09-20 15:35:39 -040084 int in_group_flag;
David Benjamin1d77e562015-03-22 17:22:08 -040085};
David Benjaminbb0a17c2014-09-20 15:35:39 -040086
David Benjamin1d77e562015-03-22 17:22:08 -040087struct CipherTest {
88 // The rule string to apply.
David Benjaminbb0a17c2014-09-20 15:35:39 -040089 const char *rule;
David Benjaminfb974e62015-12-16 19:34:22 -050090 // The list of expected ciphers, in order.
91 std::vector<ExpectedCipher> expected;
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -080092 // True if this cipher list should fail in strict mode.
93 bool strict_fail;
David Benjamin1d77e562015-03-22 17:22:08 -040094};
David Benjaminbb0a17c2014-09-20 15:35:39 -040095
Alessandro Ghedini5fd18072016-09-28 21:04:25 +010096struct CurveTest {
97 // The rule string to apply.
98 const char *rule;
99 // The list of expected curves, in order.
100 std::vector<uint16_t> expected;
101};
102
David Benjaminfb974e62015-12-16 19:34:22 -0500103static const CipherTest kCipherTests[] = {
104 // Selecting individual ciphers should work.
105 {
106 "ECDHE-ECDSA-CHACHA20-POLY1305:"
107 "ECDHE-RSA-CHACHA20-POLY1305:"
108 "ECDHE-ECDSA-AES128-GCM-SHA256:"
109 "ECDHE-RSA-AES128-GCM-SHA256",
110 {
111 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500112 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500113 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
114 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
115 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800116 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500117 },
118 // + reorders selected ciphers to the end, keeping their relative order.
119 {
120 "ECDHE-ECDSA-CHACHA20-POLY1305:"
121 "ECDHE-RSA-CHACHA20-POLY1305:"
122 "ECDHE-ECDSA-AES128-GCM-SHA256:"
123 "ECDHE-RSA-AES128-GCM-SHA256:"
124 "+aRSA",
125 {
126 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500127 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
128 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500129 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
130 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800131 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500132 },
133 // ! banishes ciphers from future selections.
134 {
135 "!aRSA:"
136 "ECDHE-ECDSA-CHACHA20-POLY1305:"
137 "ECDHE-RSA-CHACHA20-POLY1305:"
138 "ECDHE-ECDSA-AES128-GCM-SHA256:"
139 "ECDHE-RSA-AES128-GCM-SHA256",
140 {
141 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500142 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
143 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800144 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500145 },
146 // Multiple masks can be ANDed in a single rule.
147 {
148 "kRSA+AESGCM+AES128",
149 {
150 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
151 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800152 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500153 },
154 // - removes selected ciphers, but preserves their order for future
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700155 // selections. Select AES_128_GCM, but order the key exchanges RSA,
David Benjaminfb974e62015-12-16 19:34:22 -0500156 // ECDHE_RSA.
157 {
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700158 "ALL:-kECDHE:"
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700159 "-kRSA:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500160 "AESGCM+AES128+aRSA",
161 {
162 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500163 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
164 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800165 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500166 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800167 // Unknown selectors are no-ops, except in strict mode.
David Benjaminfb974e62015-12-16 19:34:22 -0500168 {
169 "ECDHE-ECDSA-CHACHA20-POLY1305:"
170 "ECDHE-RSA-CHACHA20-POLY1305:"
171 "ECDHE-ECDSA-AES128-GCM-SHA256:"
172 "ECDHE-RSA-AES128-GCM-SHA256:"
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800173 "BOGUS1",
David Benjaminfb974e62015-12-16 19:34:22 -0500174 {
175 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500176 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500177 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
178 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
179 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800180 true,
181 },
182 // Unknown selectors are no-ops, except in strict mode.
183 {
184 "ECDHE-ECDSA-CHACHA20-POLY1305:"
185 "ECDHE-RSA-CHACHA20-POLY1305:"
186 "ECDHE-ECDSA-AES128-GCM-SHA256:"
187 "ECDHE-RSA-AES128-GCM-SHA256:"
188 "-BOGUS2:+BOGUS3:!BOGUS4",
189 {
190 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
191 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
192 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
193 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
194 },
195 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500196 },
197 // Square brackets specify equi-preference groups.
198 {
199 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
200 "[ECDHE-RSA-CHACHA20-POLY1305]:"
201 "ECDHE-RSA-AES128-GCM-SHA256",
202 {
203 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
David Benjaminfb974e62015-12-16 19:34:22 -0500204 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley2e839242017-01-19 15:12:44 -0800205 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500206 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
207 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800208 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500209 },
David Benjamin6fff3862017-06-21 21:07:04 -0400210 // Standard names may be used instead of OpenSSL names.
211 {
212 "[TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256|"
David Benjaminbf5f1922017-07-01 11:13:53 -0400213 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256]:"
David Benjamin6fff3862017-06-21 21:07:04 -0400214 "[TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256]:"
215 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
216 {
217 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
218 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
219 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
220 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
221 },
222 false,
223 },
David Benjaminfb974e62015-12-16 19:34:22 -0500224 // @STRENGTH performs a stable strength-sort of the selected ciphers and
225 // only the selected ciphers.
226 {
227 // To simplify things, banish all but {ECDHE_RSA,RSA} x
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700228 // {CHACHA20,AES_256_CBC,AES_128_CBC} x SHA1.
David Benjamin6e678ee2018-04-16 19:54:42 -0400229 "!AESGCM:!3DES:"
David Benjaminfb974e62015-12-16 19:34:22 -0500230 // Order some ciphers backwards by strength.
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700231 "ALL:-CHACHA20:-AES256:-AES128:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500232 // Select ECDHE ones and sort them by strength. Ties should resolve
233 // based on the order above.
234 "kECDHE:@STRENGTH:-ALL:"
235 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
236 // by strength. Then RSA, backwards by strength.
237 "aRSA",
238 {
239 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
240 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500241 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500242 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
243 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
244 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800245 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500246 },
David Benjaminbf5f1922017-07-01 11:13:53 -0400247 // Additional masks after @STRENGTH get silently discarded.
248 //
249 // TODO(davidben): Make this an error. If not silently discarded, they get
250 // interpreted as + opcodes which are very different.
251 {
252 "ECDHE-RSA-AES128-GCM-SHA256:"
253 "ECDHE-RSA-AES256-GCM-SHA384:"
254 "@STRENGTH+AES256",
255 {
256 {TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
257 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
258 },
259 false,
260 },
261 {
262 "ECDHE-RSA-AES128-GCM-SHA256:"
263 "ECDHE-RSA-AES256-GCM-SHA384:"
264 "@STRENGTH+AES256:"
265 "ECDHE-RSA-CHACHA20-POLY1305",
266 {
267 {TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
268 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
269 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
270 },
271 false,
272 },
David Benjaminfb974e62015-12-16 19:34:22 -0500273 // Exact ciphers may not be used in multi-part rules; they are treated
274 // as unknown aliases.
275 {
276 "ECDHE-ECDSA-AES128-GCM-SHA256:"
277 "ECDHE-RSA-AES128-GCM-SHA256:"
278 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
279 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
280 {
281 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
282 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
283 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800284 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500285 },
286 // SSLv3 matches everything that existed before TLS 1.2.
287 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400288 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!SSLv3",
David Benjaminfb974e62015-12-16 19:34:22 -0500289 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400290 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500291 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800292 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500293 },
294 // TLSv1.2 matches everything added in TLS 1.2.
295 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400296 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!TLSv1.2",
David Benjaminfb974e62015-12-16 19:34:22 -0500297 {
298 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
299 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800300 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500301 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800302 // The two directives have no intersection. But each component is valid, so
303 // even in strict mode it is accepted.
David Benjaminfb974e62015-12-16 19:34:22 -0500304 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400305 "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!TLSv1.2+SSLv3",
David Benjaminfb974e62015-12-16 19:34:22 -0500306 {
307 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400308 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500309 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800310 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500311 },
Adam Langley22df6912017-07-25 12:27:37 -0700312 // Spaces, semi-colons and commas are separators.
313 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400314 "AES128-SHA: ECDHE-RSA-AES128-GCM-SHA256 AES256-SHA ,ECDHE-ECDSA-AES128-GCM-SHA256 ; AES128-GCM-SHA256",
Adam Langley22df6912017-07-25 12:27:37 -0700315 {
316 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400317 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley22df6912017-07-25 12:27:37 -0700318 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
David Benjamin6e678ee2018-04-16 19:54:42 -0400319 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley22df6912017-07-25 12:27:37 -0700320 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
321 },
322 // …but not in strict mode.
323 true,
324 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400325};
326
327static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400328 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400329 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
330 "RSA]",
331 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400332 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400333 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400334 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400335 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400336 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400337 "",
338 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400339 // COMPLEMENTOFDEFAULT is empty.
340 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400341 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400342 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400343 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400344 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
345 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
346 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
347 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
Adam Langleyf99f2442016-10-02 09:53:38 -0700348 // Opcode supplied, but missing selector.
349 "+",
Adam Langley22df6912017-07-25 12:27:37 -0700350 // Spaces are forbidden in equal-preference groups.
351 "[AES128-SHA | AES128-SHA256]",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400352};
353
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700354static const char *kMustNotIncludeNull[] = {
355 "ALL",
356 "DEFAULT",
David Benjamind6e9eec2015-11-18 09:48:55 -0500357 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700358 "FIPS",
359 "SHA",
360 "SHA1",
361 "RSA",
362 "SSLv3",
363 "TLSv1",
364 "TLSv1.2",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700365};
366
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100367static const CurveTest kCurveTests[] = {
368 {
369 "P-256",
370 { SSL_CURVE_SECP256R1 },
371 },
372 {
373 "P-256:P-384:P-521:X25519",
374 {
375 SSL_CURVE_SECP256R1,
376 SSL_CURVE_SECP384R1,
377 SSL_CURVE_SECP521R1,
378 SSL_CURVE_X25519,
379 },
380 },
David Benjamin6dda1662017-11-02 20:44:26 -0400381 {
382 "prime256v1:secp384r1:secp521r1:x25519",
383 {
384 SSL_CURVE_SECP256R1,
385 SSL_CURVE_SECP384R1,
386 SSL_CURVE_SECP521R1,
387 SSL_CURVE_X25519,
388 },
389 },
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100390};
391
392static const char *kBadCurvesLists[] = {
393 "",
394 ":",
395 "::",
396 "P-256::X25519",
397 "RSA:P-256",
398 "P-256:RSA",
399 "X25519:P-256:",
400 ":X25519:P-256",
401};
402
David Benjamin70dbf042017-08-08 18:51:37 -0400403static std::string CipherListToString(SSL_CTX *ctx) {
David Benjamin1d77e562015-03-22 17:22:08 -0400404 bool in_group = false;
David Benjamine11726a2017-04-23 12:14:28 -0400405 std::string ret;
David Benjamin70dbf042017-08-08 18:51:37 -0400406 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
407 for (size_t i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
408 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
409 if (!in_group && SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400410 ret += "\t[\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400411 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400412 }
David Benjamine11726a2017-04-23 12:14:28 -0400413 ret += "\t";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400414 if (in_group) {
David Benjamine11726a2017-04-23 12:14:28 -0400415 ret += " ";
David Benjaminbb0a17c2014-09-20 15:35:39 -0400416 }
David Benjamine11726a2017-04-23 12:14:28 -0400417 ret += SSL_CIPHER_get_name(cipher);
418 ret += "\n";
David Benjamin70dbf042017-08-08 18:51:37 -0400419 if (in_group && !SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamine11726a2017-04-23 12:14:28 -0400420 ret += "\t]\n";
David Benjamin1d77e562015-03-22 17:22:08 -0400421 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400422 }
423 }
David Benjamine11726a2017-04-23 12:14:28 -0400424 return ret;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400425}
426
David Benjamin70dbf042017-08-08 18:51:37 -0400427static bool CipherListsEqual(SSL_CTX *ctx,
David Benjamine11726a2017-04-23 12:14:28 -0400428 const std::vector<ExpectedCipher> &expected) {
David Benjamin70dbf042017-08-08 18:51:37 -0400429 const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
430 if (sk_SSL_CIPHER_num(ciphers) != expected.size()) {
David Benjamin1d77e562015-03-22 17:22:08 -0400431 return false;
David Benjamin65226252015-02-05 16:49:47 -0500432 }
433
David Benjamine11726a2017-04-23 12:14:28 -0400434 for (size_t i = 0; i < expected.size(); i++) {
David Benjamin70dbf042017-08-08 18:51:37 -0400435 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
David Benjamine11726a2017-04-23 12:14:28 -0400436 if (expected[i].id != SSL_CIPHER_get_id(cipher) ||
David Benjamin70dbf042017-08-08 18:51:37 -0400437 expected[i].in_group_flag != !!SSL_CTX_cipher_in_group(ctx, i)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400438 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400439 }
440 }
441
David Benjamin1d77e562015-03-22 17:22:08 -0400442 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400443}
444
David Benjamine11726a2017-04-23 12:14:28 -0400445TEST(SSLTest, CipherRules) {
446 for (const CipherTest &t : kCipherTests) {
447 SCOPED_TRACE(t.rule);
448 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
449 ASSERT_TRUE(ctx);
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700450
David Benjamine11726a2017-04-23 12:14:28 -0400451 // Test lax mode.
452 ASSERT_TRUE(SSL_CTX_set_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400453 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400454 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400455 << CipherListToString(ctx.get());
David Benjamine11726a2017-04-23 12:14:28 -0400456
457 // Test strict mode.
458 if (t.strict_fail) {
459 EXPECT_FALSE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
460 } else {
461 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400462 EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
David Benjamine11726a2017-04-23 12:14:28 -0400463 << "Cipher rule evaluated to:\n"
David Benjamin70dbf042017-08-08 18:51:37 -0400464 << CipherListToString(ctx.get());
David Benjaminbb0a17c2014-09-20 15:35:39 -0400465 }
466 }
467
David Benjaminfb974e62015-12-16 19:34:22 -0500468 for (const char *rule : kBadRules) {
David Benjamine11726a2017-04-23 12:14:28 -0400469 SCOPED_TRACE(rule);
470 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
471 ASSERT_TRUE(ctx);
472
473 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), rule));
David Benjaminbb0a17c2014-09-20 15:35:39 -0400474 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400475 }
476
David Benjaminfb974e62015-12-16 19:34:22 -0500477 for (const char *rule : kMustNotIncludeNull) {
David Benjamine11726a2017-04-23 12:14:28 -0400478 SCOPED_TRACE(rule);
479 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
480 ASSERT_TRUE(ctx);
481
482 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), rule));
David Benjamin70dbf042017-08-08 18:51:37 -0400483 for (const SSL_CIPHER *cipher : SSL_CTX_get_ciphers(ctx.get())) {
David Benjamine3bb51c2017-08-22 23:16:02 -0700484 EXPECT_NE(NID_undef, SSL_CIPHER_get_cipher_nid(cipher));
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700485 }
486 }
David Benjaminbb0a17c2014-09-20 15:35:39 -0400487}
David Benjamin2e521212014-07-16 14:37:51 -0400488
David Benjamine11726a2017-04-23 12:14:28 -0400489TEST(SSLTest, CurveRules) {
490 for (const CurveTest &t : kCurveTests) {
491 SCOPED_TRACE(t.rule);
492 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
493 ASSERT_TRUE(ctx);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100494
David Benjamine11726a2017-04-23 12:14:28 -0400495 ASSERT_TRUE(SSL_CTX_set1_curves_list(ctx.get(), t.rule));
496 ASSERT_EQ(t.expected.size(), ctx->supported_group_list_len);
497 for (size_t i = 0; i < t.expected.size(); i++) {
498 EXPECT_EQ(t.expected[i], ctx->supported_group_list[i]);
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100499 }
500 }
501
502 for (const char *rule : kBadCurvesLists) {
David Benjamine11726a2017-04-23 12:14:28 -0400503 SCOPED_TRACE(rule);
504 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
505 ASSERT_TRUE(ctx);
506
507 EXPECT_FALSE(SSL_CTX_set1_curves_list(ctx.get(), rule));
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100508 ERR_clear_error();
509 }
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100510}
511
Adam Langley364f7a62016-12-12 10:51:00 -0800512// kOpenSSLSession is a serialized SSL_SESSION.
Adam Langley10f97f32016-07-12 08:09:33 -0700513static const char kOpenSSLSession[] =
Adam Langley364f7a62016-12-12 10:51:00 -0800514 "MIIFqgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700515 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
516 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
517 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
518 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
519 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
520 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
521 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
522 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
523 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
524 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
525 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
526 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
527 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
528 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
529 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
530 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
531 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
532 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
533 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
534 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
535 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
536 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
537 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
538 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
539 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
540 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
541 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
542 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
543 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
Adam Langley364f7a62016-12-12 10:51:00 -0800544 "i4gv7Y5oliyntgMBAQA=";
Adam Langley10f97f32016-07-12 08:09:33 -0700545
546// kCustomSession is a custom serialized SSL_SESSION generated by
547// filling in missing fields from |kOpenSSLSession|. This includes
548// providing |peer_sha256|, so |peer| is not serialized.
549static const char kCustomSession[] =
David Benjamina8614602017-09-06 15:40:19 -0400550 "MIIBZAIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700551 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
David Benjamina8614602017-09-06 15:40:19 -0400552 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUqAcEBXdvcmxkqQUCAwGJwKqBpwSB"
553 "pBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38"
554 "VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd"
555 "3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hg"
556 "b+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYGBgYGBgYGBgYGBgYGBgYGBgYG"
557 "BgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
Adam Langley10f97f32016-07-12 08:09:33 -0700558
559// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
560static const char kBoringSSLSession[] =
561 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
562 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
563 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
564 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
565 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
566 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
567 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
568 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
569 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
570 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
571 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
572 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
573 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
574 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
575 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
576 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
577 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
578 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
579 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
580 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
581 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
582 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
583 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
584 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
585 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
586 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
587 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
588 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
589 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
590 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
591 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
592 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
593 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
594 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
595 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
596 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
597 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
598 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
599 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
600 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
601 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
602 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
603 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
604 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
605 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
606 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
607 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
608 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
609 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
610 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
611 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
612 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
613 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
614 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
615 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
616 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
617 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
618 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
619 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
620 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
621 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
622 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
623 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
624 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
625 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
626 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
627 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
628 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
629 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
630 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
631 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
632 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
633 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
634 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
635 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
636 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
637 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
638 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
639 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
640 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
641 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
642 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
643 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
644 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
645 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
646 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
647 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
648 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
649 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
650 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
651 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
652 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
653 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
654 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
655 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
656
657// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
658// the final (optional) element of |kCustomSession| with tag number 30.
659static const char kBadSessionExtraField[] =
660 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
661 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
662 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
663 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
664 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
665 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
666 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
667 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
668
669// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
670// the version of |kCustomSession| with 2.
671static const char kBadSessionVersion[] =
672 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
673 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
674 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
675 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
676 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
677 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
678 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
679 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
680
681// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
682// appended.
683static const char kBadSessionTrailingData[] =
684 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
685 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
686 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
687 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
688 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
689 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
690 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
691 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
692
David Benjamin1d77e562015-03-22 17:22:08 -0400693static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400694 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400695 if (!EVP_DecodedLength(&len, strlen(in))) {
696 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400697 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400698 }
699
David Benjamin1d77e562015-03-22 17:22:08 -0400700 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800701 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400702 strlen(in))) {
703 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400704 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400705 }
David Benjamin1d77e562015-03-22 17:22:08 -0400706 out->resize(len);
707 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400708}
709
David Benjamin1d77e562015-03-22 17:22:08 -0400710static bool TestSSL_SESSIONEncoding(const char *input_b64) {
David Benjamin751e8892014-10-19 00:59:36 -0400711 const uint8_t *cptr;
712 uint8_t *ptr;
David Benjamin751e8892014-10-19 00:59:36 -0400713
David Benjamin1d77e562015-03-22 17:22:08 -0400714 // Decode the input.
715 std::vector<uint8_t> input;
716 if (!DecodeBase64(&input, input_b64)) {
717 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400718 }
719
David Benjamin1d77e562015-03-22 17:22:08 -0400720 // Verify the SSL_SESSION decodes.
Adam Langley46db7af2017-02-01 15:49:37 -0800721 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
722 if (!ssl_ctx) {
723 return false;
724 }
725 bssl::UniquePtr<SSL_SESSION> session(
726 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
David Benjaminfd67aa82015-06-15 19:41:48 -0400727 if (!session) {
728 fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400729 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400730 }
731
David Benjamin1d77e562015-03-22 17:22:08 -0400732 // Verify the SSL_SESSION encoding round-trips.
733 size_t encoded_len;
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700734 bssl::UniquePtr<uint8_t> encoded;
David Benjamin1d77e562015-03-22 17:22:08 -0400735 uint8_t *encoded_raw;
736 if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
David Benjamin3cac4502014-10-21 01:46:30 -0400737 fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400738 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400739 }
David Benjamin1d77e562015-03-22 17:22:08 -0400740 encoded.reset(encoded_raw);
741 if (encoded_len != input.size() ||
David Benjamin17cf2cb2016-12-13 01:07:13 -0500742 OPENSSL_memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin3cac4502014-10-21 01:46:30 -0400743 fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
Sigbjorn Vik2b23d242015-06-29 15:07:26 +0200744 hexdump(stderr, "Before: ", input.data(), input.size());
745 hexdump(stderr, "After: ", encoded_raw, encoded_len);
David Benjamin1d77e562015-03-22 17:22:08 -0400746 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400747 }
David Benjamin3cac4502014-10-21 01:46:30 -0400748
David Benjaminfd67aa82015-06-15 19:41:48 -0400749 // Verify the SSL_SESSION also decodes with the legacy API.
David Benjaminef14b2d2015-11-11 14:01:27 -0800750 cptr = input.data();
David Benjaminfd67aa82015-06-15 19:41:48 -0400751 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
David Benjaminef14b2d2015-11-11 14:01:27 -0800752 if (!session || cptr != input.data() + input.size()) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400753 fprintf(stderr, "d2i_SSL_SESSION failed\n");
754 return false;
755 }
756
David Benjamin1d77e562015-03-22 17:22:08 -0400757 // Verify the SSL_SESSION encoding round-trips via the legacy API.
758 int len = i2d_SSL_SESSION(session.get(), NULL);
759 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400760 fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400761 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400762 }
763
David Benjamin1d77e562015-03-22 17:22:08 -0400764 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
765 if (!encoded) {
David Benjamin751e8892014-10-19 00:59:36 -0400766 fprintf(stderr, "malloc failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400767 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400768 }
David Benjamin1d77e562015-03-22 17:22:08 -0400769
770 ptr = encoded.get();
771 len = i2d_SSL_SESSION(session.get(), &ptr);
772 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400773 fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400774 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400775 }
David Benjamin1d77e562015-03-22 17:22:08 -0400776 if (ptr != encoded.get() + input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400777 fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400778 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400779 }
David Benjamin17cf2cb2016-12-13 01:07:13 -0500780 if (OPENSSL_memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin751e8892014-10-19 00:59:36 -0400781 fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400782 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400783 }
784
David Benjamin1d77e562015-03-22 17:22:08 -0400785 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400786}
787
David Benjaminf297e022015-05-28 19:55:29 -0400788static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
789 std::vector<uint8_t> input;
790 if (!DecodeBase64(&input, input_b64)) {
791 return false;
792 }
793
794 // Verify that the SSL_SESSION fails to decode.
Adam Langley46db7af2017-02-01 15:49:37 -0800795 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
796 if (!ssl_ctx) {
797 return false;
798 }
799 bssl::UniquePtr<SSL_SESSION> session(
800 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
David Benjaminf297e022015-05-28 19:55:29 -0400801 if (session) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400802 fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
David Benjaminf297e022015-05-28 19:55:29 -0400803 return false;
804 }
805 ERR_clear_error();
806 return true;
807}
808
David Benjamin321fcdc2017-04-24 11:42:42 -0400809static void ExpectDefaultVersion(uint16_t min_version, uint16_t max_version,
810 const SSL_METHOD *(*method)(void)) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700811 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
David Benjamin321fcdc2017-04-24 11:42:42 -0400812 ASSERT_TRUE(ctx);
David Benjaminfc08dfc2017-06-20 14:39:32 -0400813 EXPECT_EQ(min_version, ctx->conf_min_version);
814 EXPECT_EQ(max_version, ctx->conf_max_version);
David Benjamin321fcdc2017-04-24 11:42:42 -0400815}
816
817TEST(SSLTest, DefaultVersion) {
818 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
819 ExpectDefaultVersion(TLS1_VERSION, TLS1_2_VERSION, &TLS_method);
820 ExpectDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method);
821 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method);
822 ExpectDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method);
823 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method);
824 ExpectDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method);
825 ExpectDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method);
David Benjamin82c9e902014-12-12 15:55:27 -0500826}
827
David Benjamin348f0d82017-08-10 16:06:27 -0400828TEST(SSLTest, CipherProperties) {
David Benjamin6fff3862017-06-21 21:07:04 -0400829 static const struct {
830 int id;
831 const char *standard_name;
David Benjamin348f0d82017-08-10 16:06:27 -0400832 int cipher_nid;
833 int digest_nid;
834 int kx_nid;
835 int auth_nid;
David Benjaminb1b76ae2017-09-21 17:03:34 -0400836 int prf_nid;
David Benjamin6fff3862017-06-21 21:07:04 -0400837 } kTests[] = {
David Benjamin348f0d82017-08-10 16:06:27 -0400838 {
839 SSL3_CK_RSA_DES_192_CBC3_SHA,
840 "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
841 NID_des_ede3_cbc,
842 NID_sha1,
843 NID_kx_rsa,
844 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400845 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400846 },
847 {
848 TLS1_CK_RSA_WITH_AES_128_SHA,
849 "TLS_RSA_WITH_AES_128_CBC_SHA",
850 NID_aes_128_cbc,
851 NID_sha1,
852 NID_kx_rsa,
853 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400854 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400855 },
856 {
857 TLS1_CK_PSK_WITH_AES_256_CBC_SHA,
858 "TLS_PSK_WITH_AES_256_CBC_SHA",
859 NID_aes_256_cbc,
860 NID_sha1,
861 NID_kx_psk,
862 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400863 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400864 },
865 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400866 TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA,
867 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
David Benjamin348f0d82017-08-10 16:06:27 -0400868 NID_aes_128_cbc,
David Benjamin6e678ee2018-04-16 19:54:42 -0400869 NID_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400870 NID_kx_ecdhe,
871 NID_auth_rsa,
David Benjamin6e678ee2018-04-16 19:54:42 -0400872 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400873 },
874 {
David Benjamin6e678ee2018-04-16 19:54:42 -0400875 TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA,
876 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
David Benjamin348f0d82017-08-10 16:06:27 -0400877 NID_aes_256_cbc,
David Benjamin6e678ee2018-04-16 19:54:42 -0400878 NID_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400879 NID_kx_ecdhe,
880 NID_auth_rsa,
David Benjamin6e678ee2018-04-16 19:54:42 -0400881 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400882 },
883 {
884 TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
885 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
886 NID_aes_128_gcm,
887 NID_undef,
888 NID_kx_ecdhe,
889 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400890 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400891 },
892 {
893 TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
894 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
895 NID_aes_128_gcm,
896 NID_undef,
897 NID_kx_ecdhe,
898 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400899 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400900 },
901 {
902 TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
903 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
904 NID_aes_256_gcm,
905 NID_undef,
906 NID_kx_ecdhe,
907 NID_auth_ecdsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400908 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -0400909 },
910 {
911 TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
912 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
913 NID_aes_128_cbc,
914 NID_sha1,
915 NID_kx_ecdhe,
916 NID_auth_psk,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400917 NID_md5_sha1,
David Benjamin348f0d82017-08-10 16:06:27 -0400918 },
919 {
920 TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
921 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
922 NID_chacha20_poly1305,
923 NID_undef,
924 NID_kx_ecdhe,
925 NID_auth_rsa,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400926 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400927 },
928 {
929 TLS1_CK_AES_256_GCM_SHA384,
930 "TLS_AES_256_GCM_SHA384",
931 NID_aes_256_gcm,
932 NID_undef,
933 NID_kx_any,
934 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400935 NID_sha384,
David Benjamin348f0d82017-08-10 16:06:27 -0400936 },
937 {
938 TLS1_CK_AES_128_GCM_SHA256,
939 "TLS_AES_128_GCM_SHA256",
940 NID_aes_128_gcm,
941 NID_undef,
942 NID_kx_any,
943 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400944 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400945 },
946 {
947 TLS1_CK_CHACHA20_POLY1305_SHA256,
948 "TLS_CHACHA20_POLY1305_SHA256",
949 NID_chacha20_poly1305,
950 NID_undef,
951 NID_kx_any,
952 NID_auth_any,
David Benjaminb1b76ae2017-09-21 17:03:34 -0400953 NID_sha256,
David Benjamin348f0d82017-08-10 16:06:27 -0400954 },
David Benjamin6fff3862017-06-21 21:07:04 -0400955 };
David Benjamin65226252015-02-05 16:49:47 -0500956
David Benjamin6fff3862017-06-21 21:07:04 -0400957 for (const auto &t : kTests) {
958 SCOPED_TRACE(t.standard_name);
David Benjamine11726a2017-04-23 12:14:28 -0400959
960 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(t.id & 0xffff);
961 ASSERT_TRUE(cipher);
David Benjamin6fff3862017-06-21 21:07:04 -0400962 EXPECT_STREQ(t.standard_name, SSL_CIPHER_standard_name(cipher));
963
David Benjamine11726a2017-04-23 12:14:28 -0400964 bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
965 ASSERT_TRUE(rfc_name);
David Benjamin6fff3862017-06-21 21:07:04 -0400966 EXPECT_STREQ(t.standard_name, rfc_name.get());
David Benjamin348f0d82017-08-10 16:06:27 -0400967
968 EXPECT_EQ(t.cipher_nid, SSL_CIPHER_get_cipher_nid(cipher));
969 EXPECT_EQ(t.digest_nid, SSL_CIPHER_get_digest_nid(cipher));
970 EXPECT_EQ(t.kx_nid, SSL_CIPHER_get_kx_nid(cipher));
971 EXPECT_EQ(t.auth_nid, SSL_CIPHER_get_auth_nid(cipher));
David Benjaminb1b76ae2017-09-21 17:03:34 -0400972 EXPECT_EQ(t.prf_nid, SSL_CIPHER_get_prf_nid(cipher));
David Benjamin65226252015-02-05 16:49:47 -0500973 }
David Benjamin65226252015-02-05 16:49:47 -0500974}
975
Steven Valdeza833c352016-11-01 13:39:36 -0400976// CreateSessionWithTicket returns a sample |SSL_SESSION| with the specified
977// version and ticket length or nullptr on failure.
978static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(uint16_t version,
979 size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -0400980 std::vector<uint8_t> der;
981 if (!DecodeBase64(&der, kOpenSSLSession)) {
982 return nullptr;
983 }
Adam Langley46db7af2017-02-01 15:49:37 -0800984
985 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
986 if (!ssl_ctx) {
987 return nullptr;
988 }
Steven Valdeza833c352016-11-01 13:39:36 -0400989 bssl::UniquePtr<SSL_SESSION> session(
Adam Langley46db7af2017-02-01 15:49:37 -0800990 SSL_SESSION_from_bytes(der.data(), der.size(), ssl_ctx.get()));
David Benjamin422fe082015-07-21 22:03:43 -0400991 if (!session) {
992 return nullptr;
993 }
994
Steven Valdeza833c352016-11-01 13:39:36 -0400995 session->ssl_version = version;
996
David Benjamin422fe082015-07-21 22:03:43 -0400997 // Swap out the ticket for a garbage one.
998 OPENSSL_free(session->tlsext_tick);
999 session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len));
1000 if (session->tlsext_tick == nullptr) {
1001 return nullptr;
1002 }
David Benjamin17cf2cb2016-12-13 01:07:13 -05001003 OPENSSL_memset(session->tlsext_tick, 'a', ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -04001004 session->tlsext_ticklen = ticket_len;
David Benjamin1269ddd2015-10-18 15:18:55 -04001005
1006 // Fix up the timeout.
David Benjamin9b63f292016-11-15 00:44:05 -05001007#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
1008 session->time = 1234;
1009#else
David Benjamin1269ddd2015-10-18 15:18:55 -04001010 session->time = time(NULL);
David Benjamin9b63f292016-11-15 00:44:05 -05001011#endif
David Benjamin422fe082015-07-21 22:03:43 -04001012 return session;
1013}
1014
David Benjaminafc64de2016-07-19 17:12:41 +02001015static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001016 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +02001017 if (!bio) {
1018 return false;
1019 }
1020 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -04001021 BIO_up_ref(bio.get());
1022 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +02001023 int ret = SSL_connect(ssl);
1024 if (ret > 0) {
1025 // SSL_connect should fail without a BIO to write to.
1026 return false;
1027 }
1028 ERR_clear_error();
1029
1030 const uint8_t *client_hello;
1031 size_t client_hello_len;
1032 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
1033 return false;
1034 }
1035 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
1036 return true;
1037}
1038
Steven Valdeza833c352016-11-01 13:39:36 -04001039// GetClientHelloLen creates a client SSL connection with the specified version
1040// and ticket length. It returns the length of the ClientHello, not including
1041// the record header, on success and zero on error.
1042static size_t GetClientHelloLen(uint16_t max_version, uint16_t session_version,
1043 size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001044 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Steven Valdeza833c352016-11-01 13:39:36 -04001045 bssl::UniquePtr<SSL_SESSION> session =
1046 CreateSessionWithTicket(session_version, ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -04001047 if (!ctx || !session) {
1048 return 0;
1049 }
Steven Valdeza833c352016-11-01 13:39:36 -04001050
1051 // Set a one-element cipher list so the baseline ClientHello is unpadded.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001052 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
Steven Valdez2c62fe92016-10-14 12:08:12 -04001053 if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -08001054 !SSL_set_strict_cipher_list(ssl.get(), "ECDHE-RSA-AES128-GCM-SHA256") ||
Steven Valdeza833c352016-11-01 13:39:36 -04001055 !SSL_set_max_proto_version(ssl.get(), max_version)) {
David Benjamin422fe082015-07-21 22:03:43 -04001056 return 0;
1057 }
Steven Valdeza833c352016-11-01 13:39:36 -04001058
David Benjaminafc64de2016-07-19 17:12:41 +02001059 std::vector<uint8_t> client_hello;
1060 if (!GetClientHello(ssl.get(), &client_hello) ||
1061 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -04001062 return 0;
1063 }
Steven Valdeza833c352016-11-01 13:39:36 -04001064
David Benjaminafc64de2016-07-19 17:12:41 +02001065 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -04001066}
1067
1068struct PaddingTest {
1069 size_t input_len, padded_len;
1070};
1071
1072static const PaddingTest kPaddingTests[] = {
1073 // ClientHellos of length below 0x100 do not require padding.
1074 {0xfe, 0xfe},
1075 {0xff, 0xff},
1076 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
1077 {0x100, 0x200},
1078 {0x123, 0x200},
1079 {0x1fb, 0x200},
1080 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
1081 // padding extension takes a minimum of four bytes plus one required content
1082 // byte. (To work around yet more server bugs, we avoid empty final
1083 // extensions.)
1084 {0x1fc, 0x201},
1085 {0x1fd, 0x202},
1086 {0x1fe, 0x203},
1087 {0x1ff, 0x204},
1088 // Finally, larger ClientHellos need no padding.
1089 {0x200, 0x200},
1090 {0x201, 0x201},
1091};
1092
Steven Valdeza833c352016-11-01 13:39:36 -04001093static bool TestPaddingExtension(uint16_t max_version,
1094 uint16_t session_version) {
David Benjamin422fe082015-07-21 22:03:43 -04001095 // Sample a baseline length.
Steven Valdeza833c352016-11-01 13:39:36 -04001096 size_t base_len = GetClientHelloLen(max_version, session_version, 1);
David Benjamin422fe082015-07-21 22:03:43 -04001097 if (base_len == 0) {
1098 return false;
1099 }
1100
1101 for (const PaddingTest &test : kPaddingTests) {
1102 if (base_len > test.input_len) {
Steven Valdeza833c352016-11-01 13:39:36 -04001103 fprintf(stderr,
1104 "Baseline ClientHello too long (max_version = %04x, "
1105 "session_version = %04x).\n",
1106 max_version, session_version);
David Benjamin422fe082015-07-21 22:03:43 -04001107 return false;
1108 }
1109
Steven Valdeza833c352016-11-01 13:39:36 -04001110 size_t padded_len = GetClientHelloLen(max_version, session_version,
1111 1 + test.input_len - base_len);
David Benjamin422fe082015-07-21 22:03:43 -04001112 if (padded_len != test.padded_len) {
Steven Valdeza833c352016-11-01 13:39:36 -04001113 fprintf(stderr,
1114 "%u-byte ClientHello padded to %u bytes, not %u (max_version = "
1115 "%04x, session_version = %04x).\n",
David Benjamin422fe082015-07-21 22:03:43 -04001116 static_cast<unsigned>(test.input_len),
1117 static_cast<unsigned>(padded_len),
Steven Valdeza833c352016-11-01 13:39:36 -04001118 static_cast<unsigned>(test.padded_len), max_version,
1119 session_version);
David Benjamin422fe082015-07-21 22:03:43 -04001120 return false;
1121 }
1122 }
Steven Valdeza833c352016-11-01 13:39:36 -04001123
David Benjamin422fe082015-07-21 22:03:43 -04001124 return true;
1125}
1126
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001127static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001128 static const char kCertPEM[] =
1129 "-----BEGIN CERTIFICATE-----\n"
1130 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1131 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1132 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1133 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1134 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1135 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1136 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1137 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1138 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1139 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1140 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1141 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1142 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1143 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001144 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
David Benjamin1444c3a2016-12-20 17:23:11 -05001145 return bssl::UniquePtr<X509>(
1146 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjaminde942382016-02-11 12:02:01 -05001147}
1148
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001149static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001150 static const char kKeyPEM[] =
1151 "-----BEGIN RSA PRIVATE KEY-----\n"
1152 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1153 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1154 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1155 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1156 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1157 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1158 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1159 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1160 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1161 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1162 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1163 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1164 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1165 "-----END RSA PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001166 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1167 return bssl::UniquePtr<EVP_PKEY>(
David Benjaminde942382016-02-11 12:02:01 -05001168 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1169}
1170
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001171static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001172 static const char kCertPEM[] =
1173 "-----BEGIN CERTIFICATE-----\n"
1174 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1175 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1176 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1177 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1178 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1179 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1180 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1181 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1182 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1183 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1184 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001185 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1186 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjamin0fc37ef2016-08-17 15:29:46 -04001187}
1188
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001189static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001190 static const char kKeyPEM[] =
1191 "-----BEGIN PRIVATE KEY-----\n"
1192 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1193 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1194 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1195 "-----END PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001196 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1197 return bssl::UniquePtr<EVP_PKEY>(
David Benjamin0fc37ef2016-08-17 15:29:46 -04001198 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1199}
1200
Adam Langleyd04ca952017-02-28 11:26:51 -08001201static bssl::UniquePtr<CRYPTO_BUFFER> BufferFromPEM(const char *pem) {
1202 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1203 char *name, *header;
1204 uint8_t *data;
1205 long data_len;
1206 if (!PEM_read_bio(bio.get(), &name, &header, &data,
1207 &data_len)) {
1208 return nullptr;
1209 }
1210 OPENSSL_free(name);
1211 OPENSSL_free(header);
1212
1213 auto ret = bssl::UniquePtr<CRYPTO_BUFFER>(
1214 CRYPTO_BUFFER_new(data, data_len, nullptr));
1215 OPENSSL_free(data);
1216 return ret;
1217}
1218
1219static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestCertificateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001220 static const char kCertPEM[] =
1221 "-----BEGIN CERTIFICATE-----\n"
1222 "MIIC0jCCAbqgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQiBD\n"
1223 "QTAeFw0xNjAyMjgyMDI3MDNaFw0yNjAyMjUyMDI3MDNaMBgxFjAUBgNVBAMMDUNs\n"
1224 "aWVudCBDZXJ0IEEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRvaz8\n"
1225 "CC/cshpCafJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/\n"
1226 "kLRcH89M/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3\n"
1227 "tHb+xs2PSs8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+c\n"
1228 "IDs2rQ+lP7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1\n"
1229 "z7C8jU50Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9V\n"
1230 "iLeXANgZi+Xx9KgfAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI\n"
1231 "KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBFEVbmYl+2RtNw\n"
1232 "rDftRDF1v2QUbcN2ouSnQDHxeDQdSgasLzT3ui8iYu0Rw2WWcZ0DV5e0ztGPhWq7\n"
1233 "AO0B120aFRMOY+4+bzu9Q2FFkQqc7/fKTvTDzIJI5wrMnFvUfzzvxh3OHWMYSs/w\n"
1234 "giq33hTKeHEq6Jyk3btCny0Ycecyc3yGXH10sizUfiHlhviCkDuESk8mFDwDDzqW\n"
1235 "ZF0IipzFbEDHoIxLlm3GQxpiLoEV4k8KYJp3R5KBLFyxM6UGPz8h72mIPCJp2RuK\n"
1236 "MYgF91UDvVzvnYm6TfseM2+ewKirC00GOrZ7rEcFvtxnKSqYf4ckqfNdSU1Y+RRC\n"
1237 "1ngWZ7Ih\n"
1238 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001239 return BufferFromPEM(kCertPEM);
David Benjamin1444c3a2016-12-20 17:23:11 -05001240}
1241
Adam Langleyd04ca952017-02-28 11:26:51 -08001242static bssl::UniquePtr<X509> X509FromBuffer(
1243 bssl::UniquePtr<CRYPTO_BUFFER> buffer) {
1244 if (!buffer) {
1245 return nullptr;
1246 }
1247 const uint8_t *derp = CRYPTO_BUFFER_data(buffer.get());
1248 return bssl::UniquePtr<X509>(
1249 d2i_X509(NULL, &derp, CRYPTO_BUFFER_len(buffer.get())));
1250}
1251
1252static bssl::UniquePtr<X509> GetChainTestCertificate() {
1253 return X509FromBuffer(GetChainTestCertificateBuffer());
1254}
1255
1256static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestIntermediateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001257 static const char kCertPEM[] =
1258 "-----BEGIN CERTIFICATE-----\n"
1259 "MIICwjCCAaqgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS\n"
1260 "b290IENBMB4XDTE2MDIyODIwMjcwM1oXDTI2MDIyNTIwMjcwM1owDzENMAsGA1UE\n"
1261 "AwwEQiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALsSCYmDip2D\n"
1262 "GkjFxw7ykz26JSjELkl6ArlYjFJ3aT/SCh8qbS4gln7RH8CPBd78oFdfhIKQrwtZ\n"
1263 "3/q21ykD9BAS3qHe2YdcJfm8/kWAy5DvXk6NXU4qX334KofBAEpgdA/igEFq1P1l\n"
1264 "HAuIfZCpMRfT+i5WohVsGi8f/NgpRvVaMONLNfgw57mz1lbtFeBEISmX0kbsuJxF\n"
1265 "Qj/Bwhi5/0HAEXG8e7zN4cEx0yPRvmOATRdVb/8dW2pwOHRJq9R5M0NUkIsTSnL7\n"
1266 "6N/z8hRAHMsV3IudC5Yd7GXW1AGu9a+iKU+Q4xcZCoj0DC99tL4VKujrV1kAeqsM\n"
1267 "cz5/dKzi6+cCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
1268 "AQYwDQYJKoZIhvcNAQELBQADggEBAIIeZiEeNhWWQ8Y4D+AGDwqUUeG8NjCbKrXQ\n"
1269 "BlHg5wZ8xftFaiP1Dp/UAezmx2LNazdmuwrYB8lm3FVTyaPDTKEGIPS4wJKHgqH1\n"
1270 "QPDhqNm85ey7TEtI9oYjsNim/Rb+iGkIAMXaxt58SzxbjvP0kMr1JfJIZbic9vye\n"
1271 "NwIspMFIpP3FB8ywyu0T0hWtCQgL4J47nigCHpOu58deP88fS/Nyz/fyGVWOZ76b\n"
1272 "WhWwgM3P3X95fQ3d7oFPR/bVh0YV+Cf861INwplokXgXQ3/TCQ+HNXeAMWn3JLWv\n"
1273 "XFwk8owk9dq/kQGdndGgy3KTEW4ctPX5GNhf3LJ9Q7dLji4ReQ4=\n"
1274 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001275 return BufferFromPEM(kCertPEM);
1276}
1277
1278static bssl::UniquePtr<X509> GetChainTestIntermediate() {
1279 return X509FromBuffer(GetChainTestIntermediateBuffer());
David Benjamin1444c3a2016-12-20 17:23:11 -05001280}
1281
1282static bssl::UniquePtr<EVP_PKEY> GetChainTestKey() {
1283 static const char kKeyPEM[] =
1284 "-----BEGIN PRIVATE KEY-----\n"
1285 "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRvaz8CC/cshpC\n"
1286 "afJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/kLRcH89M\n"
1287 "/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3tHb+xs2P\n"
1288 "Ss8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+cIDs2rQ+l\n"
1289 "P7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1z7C8jU50\n"
1290 "Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9ViLeXANgZ\n"
1291 "i+Xx9KgfAgMBAAECggEBAK0VjSJzkyPaamcyTVSWjo7GdaBGcK60lk657RjR+lK0\n"
1292 "YJ7pkej4oM2hdsVZFsP8Cs4E33nXLa/0pDsRov/qrp0WQm2skwqGMC1I/bZ0WRPk\n"
1293 "wHaDrBBfESWnJDX/AGpVtlyOjPmgmK6J2usMPihQUDkKdAYrVWJePrMIxt1q6BMe\n"
1294 "iczs3qriMmtY3bUc4UyUwJ5fhDLjshHvfuIpYQyI6EXZM6dZksn9LylXJnigY6QJ\n"
1295 "HxOYO0BDwOsZ8yQ8J8afLk88i0GizEkgE1z3REtQUwgWfxr1WV/ud+T6/ZhSAgH9\n"
1296 "042mQvSFZnIUSEsmCvjhWuAunfxHKCTcAoYISWfzWpkCgYEA7gpf3HHU5Tn+CgUn\n"
1297 "1X5uGpG3DmcMgfeGgs2r2f/IIg/5Ac1dfYILiybL1tN9zbyLCJfcbFpWBc9hJL6f\n"
1298 "CPc5hUiwWFJqBJewxQkC1Ae/HakHbip+IZ+Jr0842O4BAArvixk4Lb7/N2Ct9sTE\n"
1299 "NJO6RtK9lbEZ5uK61DglHy8CS2UCgYEA4ZC1o36kPAMQBggajgnucb2yuUEelk0f\n"
1300 "AEr+GI32MGE+93xMr7rAhBoqLg4AITyIfEnOSQ5HwagnIHonBbv1LV/Gf9ursx8Z\n"
1301 "YOGbvT8zzzC+SU1bkDzdjAYnFQVGIjMtKOBJ3K07++ypwX1fr4QsQ8uKL8WSOWwt\n"
1302 "Z3Bym6XiZzMCgYADnhy+2OwHX85AkLt+PyGlPbmuelpyTzS4IDAQbBa6jcuW/2wA\n"
1303 "UE2km75VUXmD+u2R/9zVuLm99NzhFhSMqlUxdV1YukfqMfP5yp1EY6m/5aW7QuIP\n"
1304 "2MDa7TVL9rIFMiVZ09RKvbBbQxjhuzPQKL6X/PPspnhiTefQ+dl2k9xREQKBgHDS\n"
1305 "fMfGNEeAEKezrfSVqxphE9/tXms3L+ZpnCaT+yu/uEr5dTIAawKoQ6i9f/sf1/Sy\n"
1306 "xedsqR+IB+oKrzIDDWMgoJybN4pkZ8E5lzhVQIjFjKgFdWLzzqyW9z1gYfABQPlN\n"
1307 "FiS20WX0vgP1vcKAjdNrHzc9zyHBpgQzDmAj3NZZAoGBAI8vKCKdH7w3aL5CNkZQ\n"
1308 "2buIeWNA2HZazVwAGG5F2TU/LmXfRKnG6dX5bkU+AkBZh56jNZy//hfFSewJB4Kk\n"
1309 "buB7ERSdaNbO21zXt9FEA3+z0RfMd/Zv2vlIWOSB5nzl/7UKti3sribK6s9ZVLfi\n"
1310 "SxpiPQ8d/hmSGwn4ksrWUsJD\n"
1311 "-----END PRIVATE KEY-----\n";
1312 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1313 return bssl::UniquePtr<EVP_PKEY>(
1314 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1315}
1316
David Benjaminc79ae7a2017-08-29 16:09:44 -04001317// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
1318// before configuring as a server.
1319TEST(SSLTest, ClientCAList) {
1320 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1321 ASSERT_TRUE(ctx);
1322 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1323 ASSERT_TRUE(ssl);
1324
1325 bssl::UniquePtr<X509_NAME> name(X509_NAME_new());
1326 ASSERT_TRUE(name);
1327
1328 bssl::UniquePtr<X509_NAME> name_dup(X509_NAME_dup(name.get()));
1329 ASSERT_TRUE(name_dup);
1330
1331 bssl::UniquePtr<STACK_OF(X509_NAME)> stack(sk_X509_NAME_new_null());
1332 ASSERT_TRUE(stack);
1333
1334 ASSERT_TRUE(sk_X509_NAME_push(stack.get(), name_dup.get()));
1335 name_dup.release();
1336
1337 // |SSL_set_client_CA_list| takes ownership.
1338 SSL_set_client_CA_list(ssl.get(), stack.release());
1339
1340 STACK_OF(X509_NAME) *result = SSL_get_client_CA_list(ssl.get());
1341 ASSERT_TRUE(result);
1342 ASSERT_EQ(1u, sk_X509_NAME_num(result));
1343 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(result, 0), name.get()));
1344}
1345
1346TEST(SSLTest, AddClientCA) {
1347 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1348 ASSERT_TRUE(ctx);
1349 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1350 ASSERT_TRUE(ssl);
1351
1352 bssl::UniquePtr<X509> cert1 = GetTestCertificate();
1353 bssl::UniquePtr<X509> cert2 = GetChainTestCertificate();
1354 ASSERT_TRUE(cert1 && cert2);
1355 X509_NAME *name1 = X509_get_subject_name(cert1.get());
1356 X509_NAME *name2 = X509_get_subject_name(cert2.get());
1357
1358 EXPECT_EQ(0u, sk_X509_NAME_num(SSL_get_client_CA_list(ssl.get())));
1359
1360 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1361 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert2.get()));
1362
1363 STACK_OF(X509_NAME) *list = SSL_get_client_CA_list(ssl.get());
1364 ASSERT_EQ(2u, sk_X509_NAME_num(list));
1365 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1366 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1367
1368 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1369
1370 list = SSL_get_client_CA_list(ssl.get());
1371 ASSERT_EQ(3u, sk_X509_NAME_num(list));
1372 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1373 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1374 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 2), name1));
1375}
1376
1377static void AppendSession(SSL_SESSION *session, void *arg) {
1378 std::vector<SSL_SESSION*> *out =
1379 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
1380 out->push_back(session);
1381}
1382
1383// CacheEquals returns true if |ctx|'s session cache consists of |expected|, in
1384// order.
1385static bool CacheEquals(SSL_CTX *ctx,
1386 const std::vector<SSL_SESSION*> &expected) {
1387 // Check the linked list.
1388 SSL_SESSION *ptr = ctx->session_cache_head;
1389 for (SSL_SESSION *session : expected) {
1390 if (ptr != session) {
1391 return false;
1392 }
1393 // TODO(davidben): This is an absurd way to denote the end of the list.
1394 if (ptr->next ==
1395 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
1396 ptr = nullptr;
1397 } else {
1398 ptr = ptr->next;
1399 }
1400 }
1401 if (ptr != nullptr) {
1402 return false;
1403 }
1404
1405 // Check the hash table.
1406 std::vector<SSL_SESSION*> actual, expected_copy;
David Benjamin9eaa3bd2017-09-27 17:03:54 -04001407 lh_SSL_SESSION_doall_arg(ctx->sessions, AppendSession, &actual);
David Benjaminc79ae7a2017-08-29 16:09:44 -04001408 expected_copy = expected;
1409
1410 std::sort(actual.begin(), actual.end());
1411 std::sort(expected_copy.begin(), expected_copy.end());
1412
1413 return actual == expected_copy;
1414}
1415
1416static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
1417 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
1418 if (!ssl_ctx) {
1419 return nullptr;
1420 }
1421 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new(ssl_ctx.get()));
1422 if (!ret) {
1423 return nullptr;
1424 }
1425
1426 ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
1427 OPENSSL_memset(ret->session_id, 0, ret->session_id_length);
1428 OPENSSL_memcpy(ret->session_id, &number, sizeof(number));
1429 return ret;
1430}
1431
1432// Test that the internal session cache behaves as expected.
1433TEST(SSLTest, InternalSessionCache) {
1434 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1435 ASSERT_TRUE(ctx);
1436
1437 // Prepare 10 test sessions.
1438 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
1439 for (int i = 0; i < 10; i++) {
1440 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
1441 ASSERT_TRUE(session);
1442 sessions.push_back(std::move(session));
1443 }
1444
1445 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1446
1447 // Insert all the test sessions.
1448 for (const auto &session : sessions) {
1449 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), session.get()));
1450 }
1451
1452 // Only the last five should be in the list.
1453 ASSERT_TRUE(CacheEquals(
1454 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
1455 sessions[6].get(), sessions[5].get()}));
1456
1457 // Inserting an element already in the cache should fail and leave the cache
1458 // unchanged.
1459 ASSERT_FALSE(SSL_CTX_add_session(ctx.get(), sessions[7].get()));
1460 ASSERT_TRUE(CacheEquals(
1461 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
1462 sessions[6].get(), sessions[5].get()}));
1463
1464 // Although collisions should be impossible (256-bit session IDs), the cache
1465 // must handle them gracefully.
1466 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
1467 ASSERT_TRUE(collision);
1468 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), collision.get()));
1469 ASSERT_TRUE(CacheEquals(
1470 ctx.get(), {collision.get(), sessions[9].get(), sessions[8].get(),
1471 sessions[6].get(), sessions[5].get()}));
1472
1473 // Removing sessions behaves correctly.
1474 ASSERT_TRUE(SSL_CTX_remove_session(ctx.get(), sessions[6].get()));
1475 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
1476 sessions[8].get(), sessions[5].get()}));
1477
1478 // Removing sessions requires an exact match.
1479 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[0].get()));
1480 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[7].get()));
1481
1482 // The cache remains unchanged.
1483 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
1484 sessions[8].get(), sessions[5].get()}));
1485}
1486
1487static uint16_t EpochFromSequence(uint64_t seq) {
1488 return static_cast<uint16_t>(seq >> 48);
1489}
1490
David Benjamin71dfad42017-07-16 17:27:39 -04001491static const uint8_t kTestName[] = {
1492 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
1493 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
1494 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
1495 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
1496 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
1497 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64,
1498};
1499
David Benjaminb79cc842016-12-07 15:57:14 -05001500static bool CompleteHandshakes(SSL *client, SSL *server) {
1501 // Drive both their handshakes to completion.
1502 for (;;) {
1503 int client_ret = SSL_do_handshake(client);
1504 int client_err = SSL_get_error(client, client_ret);
1505 if (client_err != SSL_ERROR_NONE &&
1506 client_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001507 client_err != SSL_ERROR_WANT_WRITE &&
1508 client_err != SSL_ERROR_PENDING_TICKET) {
David Benjaminb79cc842016-12-07 15:57:14 -05001509 fprintf(stderr, "Client error: %d\n", client_err);
1510 return false;
1511 }
1512
1513 int server_ret = SSL_do_handshake(server);
1514 int server_err = SSL_get_error(server, server_ret);
1515 if (server_err != SSL_ERROR_NONE &&
1516 server_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001517 server_err != SSL_ERROR_WANT_WRITE &&
1518 server_err != SSL_ERROR_PENDING_TICKET) {
David Benjaminb79cc842016-12-07 15:57:14 -05001519 fprintf(stderr, "Server error: %d\n", server_err);
1520 return false;
1521 }
1522
1523 if (client_ret == 1 && server_ret == 1) {
1524 break;
1525 }
1526 }
1527
1528 return true;
1529}
1530
David Benjamina8614602017-09-06 15:40:19 -04001531struct ClientConfig {
1532 SSL_SESSION *session = nullptr;
1533 std::string servername;
1534};
1535
David Benjaminb79cc842016-12-07 15:57:14 -05001536static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client,
1537 bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001538 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
Adam Langleyddb57cf2018-01-26 09:17:53 -08001539 const ClientConfig &config = ClientConfig(),
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001540 bool do_handshake = true,
1541 bool shed_handshake_config = true) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001542 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001543 if (!client || !server) {
1544 return false;
1545 }
1546 SSL_set_connect_state(client.get());
1547 SSL_set_accept_state(server.get());
1548
David Benjamina8614602017-09-06 15:40:19 -04001549 if (config.session) {
1550 SSL_set_session(client.get(), config.session);
1551 }
1552 if (!config.servername.empty() &&
1553 !SSL_set_tlsext_host_name(client.get(), config.servername.c_str())) {
1554 return false;
1555 }
David Benjamina20e5352016-08-02 19:09:41 -04001556
David Benjaminde942382016-02-11 12:02:01 -05001557 BIO *bio1, *bio2;
1558 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1559 return false;
1560 }
1561 // SSL_set_bio takes ownership.
1562 SSL_set_bio(client.get(), bio1, bio1);
1563 SSL_set_bio(server.get(), bio2, bio2);
1564
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001565 SSL_set_shed_handshake_config(client.get(), shed_handshake_config);
1566 SSL_set_shed_handshake_config(server.get(), shed_handshake_config);
1567
Adam Langleyddb57cf2018-01-26 09:17:53 -08001568 if (do_handshake && !CompleteHandshakes(client.get(), server.get())) {
David Benjaminb79cc842016-12-07 15:57:14 -05001569 return false;
David Benjaminde942382016-02-11 12:02:01 -05001570 }
1571
David Benjamin686bb192016-05-10 15:15:41 -04001572 *out_client = std::move(client);
1573 *out_server = std::move(server);
1574 return true;
1575}
1576
David Benjaminc11ea9422017-08-29 16:33:21 -04001577// SSLVersionTest executes its test cases under all available protocol versions.
1578// Test cases call |Connect| to create a connection using context objects with
1579// the protocol version fixed to the current version under test.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001580class SSLVersionTest : public ::testing::TestWithParam<VersionParam> {
1581 protected:
1582 SSLVersionTest() : cert_(GetTestCertificate()), key_(GetTestKey()) {}
1583
1584 void SetUp() { ResetContexts(); }
1585
1586 bssl::UniquePtr<SSL_CTX> CreateContext() const {
1587 const SSL_METHOD *method = is_dtls() ? DTLS_method() : TLS_method();
1588 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
1589 if (!ctx || !SSL_CTX_set_min_proto_version(ctx.get(), version()) ||
1590 !SSL_CTX_set_max_proto_version(ctx.get(), version())) {
1591 return nullptr;
1592 }
1593 return ctx;
David Benjamin0fef3052016-11-18 15:11:10 +09001594 }
David Benjamin686bb192016-05-10 15:15:41 -04001595
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001596 void ResetContexts() {
1597 ASSERT_TRUE(cert_);
1598 ASSERT_TRUE(key_);
1599 client_ctx_ = CreateContext();
1600 ASSERT_TRUE(client_ctx_);
1601 server_ctx_ = CreateContext();
1602 ASSERT_TRUE(server_ctx_);
1603 // Set up a server cert. Client certs can be set up explicitly.
1604 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09001605 }
David Benjamin686bb192016-05-10 15:15:41 -04001606
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001607 bool UseCertAndKey(SSL_CTX *ctx) const {
1608 return SSL_CTX_use_certificate(ctx, cert_.get()) &&
1609 SSL_CTX_use_PrivateKey(ctx, key_.get());
David Benjamin0fef3052016-11-18 15:11:10 +09001610 }
David Benjamin686bb192016-05-10 15:15:41 -04001611
David Benjamina8614602017-09-06 15:40:19 -04001612 bool Connect(const ClientConfig &config = ClientConfig()) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001613 return ConnectClientAndServer(&client_, &server_, client_ctx_.get(),
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001614 server_ctx_.get(), config, true,
1615 shed_handshake_config_);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001616 }
1617
1618 uint16_t version() const { return GetParam().version; }
1619
1620 bool is_dtls() const {
1621 return GetParam().ssl_method == VersionParam::is_dtls;
1622 }
1623
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001624 bool shed_handshake_config_ = true;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001625 bssl::UniquePtr<SSL> client_, server_;
1626 bssl::UniquePtr<SSL_CTX> server_ctx_, client_ctx_;
1627 bssl::UniquePtr<X509> cert_;
1628 bssl::UniquePtr<EVP_PKEY> key_;
1629};
1630
1631INSTANTIATE_TEST_CASE_P(WithVersion, SSLVersionTest,
1632 testing::ValuesIn(kAllVersions),
1633 [](const testing::TestParamInfo<VersionParam> &i) {
1634 return i.param.name;
1635 });
1636
1637TEST_P(SSLVersionTest, SequenceNumber) {
1638 ASSERT_TRUE(Connect());
1639
David Benjamin0fef3052016-11-18 15:11:10 +09001640 // Drain any post-handshake messages to ensure there are no unread records
1641 // on either end.
1642 uint8_t byte = 0;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001643 ASSERT_LE(SSL_read(client_.get(), &byte, 1), 0);
1644 ASSERT_LE(SSL_read(server_.get(), &byte, 1), 0);
David Benjaminde942382016-02-11 12:02:01 -05001645
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001646 uint64_t client_read_seq = SSL_get_read_sequence(client_.get());
1647 uint64_t client_write_seq = SSL_get_write_sequence(client_.get());
1648 uint64_t server_read_seq = SSL_get_read_sequence(server_.get());
1649 uint64_t server_write_seq = SSL_get_write_sequence(server_.get());
Steven Valdez2c62fe92016-10-14 12:08:12 -04001650
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001651 if (is_dtls()) {
David Benjamin0fef3052016-11-18 15:11:10 +09001652 // Both client and server must be at epoch 1.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001653 EXPECT_EQ(EpochFromSequence(client_read_seq), 1);
1654 EXPECT_EQ(EpochFromSequence(client_write_seq), 1);
1655 EXPECT_EQ(EpochFromSequence(server_read_seq), 1);
1656 EXPECT_EQ(EpochFromSequence(server_write_seq), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09001657
1658 // The next record to be written should exceed the largest received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001659 EXPECT_GT(client_write_seq, server_read_seq);
1660 EXPECT_GT(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09001661 } else {
1662 // The next record to be written should equal the next to be received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001663 EXPECT_EQ(client_write_seq, server_read_seq);
1664 EXPECT_EQ(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09001665 }
1666
1667 // Send a record from client to server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001668 EXPECT_EQ(SSL_write(client_.get(), &byte, 1), 1);
1669 EXPECT_EQ(SSL_read(server_.get(), &byte, 1), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09001670
1671 // The client write and server read sequence numbers should have
1672 // incremented.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001673 EXPECT_EQ(client_write_seq + 1, SSL_get_write_sequence(client_.get()));
1674 EXPECT_EQ(server_read_seq + 1, SSL_get_read_sequence(server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05001675}
1676
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001677TEST_P(SSLVersionTest, OneSidedShutdown) {
David Benjamin68f37b72016-11-18 15:14:42 +09001678 // SSL_shutdown is a no-op in DTLS.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001679 if (is_dtls()) {
1680 return;
David Benjamin686bb192016-05-10 15:15:41 -04001681 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001682 ASSERT_TRUE(Connect());
David Benjamin686bb192016-05-10 15:15:41 -04001683
1684 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1685 // one side has shut down.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001686 ASSERT_EQ(SSL_shutdown(client_.get()), 0);
David Benjamin686bb192016-05-10 15:15:41 -04001687
1688 // Reading from the server should consume the EOF.
1689 uint8_t byte;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001690 ASSERT_EQ(SSL_read(server_.get(), &byte, 1), 0);
1691 ASSERT_EQ(SSL_get_error(server_.get(), 0), SSL_ERROR_ZERO_RETURN);
David Benjamin686bb192016-05-10 15:15:41 -04001692
1693 // However, the server may continue to write data and then shut down the
1694 // connection.
1695 byte = 42;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001696 ASSERT_EQ(SSL_write(server_.get(), &byte, 1), 1);
1697 ASSERT_EQ(SSL_read(client_.get(), &byte, 1), 1);
1698 ASSERT_EQ(byte, 42);
David Benjamin686bb192016-05-10 15:15:41 -04001699
1700 // The server may then shutdown the connection.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001701 EXPECT_EQ(SSL_shutdown(server_.get()), 1);
1702 EXPECT_EQ(SSL_shutdown(client_.get()), 1);
David Benjamin686bb192016-05-10 15:15:41 -04001703}
David Benjamin68f37b72016-11-18 15:14:42 +09001704
David Benjaminf0d8e222017-02-04 10:58:26 -05001705TEST(SSLTest, SessionDuplication) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001706 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1707 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001708 ASSERT_TRUE(client_ctx);
1709 ASSERT_TRUE(server_ctx);
Steven Valdez87eab492016-06-27 16:34:59 -04001710
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001711 bssl::UniquePtr<X509> cert = GetTestCertificate();
1712 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminf0d8e222017-02-04 10:58:26 -05001713 ASSERT_TRUE(cert);
1714 ASSERT_TRUE(key);
1715 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
1716 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04001717
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001718 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05001719 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04001720 server_ctx.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04001721
1722 SSL_SESSION *session0 = SSL_get_session(client.get());
David Benjamin31b0c9b2017-07-20 14:49:15 -04001723 bssl::UniquePtr<SSL_SESSION> session1 =
1724 bssl::SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL);
David Benjaminf0d8e222017-02-04 10:58:26 -05001725 ASSERT_TRUE(session1);
David Benjamin4501bd52016-08-01 13:39:41 -04001726
David Benjamina3a71e92018-06-29 13:24:45 -04001727 session1->not_resumable = false;
Steven Valdez84b5c002016-08-25 16:30:58 -04001728
Steven Valdez87eab492016-06-27 16:34:59 -04001729 uint8_t *s0_bytes, *s1_bytes;
1730 size_t s0_len, s1_len;
1731
David Benjaminf0d8e222017-02-04 10:58:26 -05001732 ASSERT_TRUE(SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001733 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001734
David Benjaminf0d8e222017-02-04 10:58:26 -05001735 ASSERT_TRUE(SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001736 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001737
David Benjamin7d7554b2017-02-04 11:48:59 -05001738 EXPECT_EQ(Bytes(s0_bytes, s0_len), Bytes(s1_bytes, s1_len));
Steven Valdez87eab492016-06-27 16:34:59 -04001739}
David Benjamin686bb192016-05-10 15:15:41 -04001740
David Benjaminf0d8e222017-02-04 10:58:26 -05001741static void ExpectFDs(const SSL *ssl, int rfd, int wfd) {
David Benjaminca743582017-06-15 17:51:35 -04001742 EXPECT_EQ(rfd, SSL_get_fd(ssl));
David Benjaminf0d8e222017-02-04 10:58:26 -05001743 EXPECT_EQ(rfd, SSL_get_rfd(ssl));
1744 EXPECT_EQ(wfd, SSL_get_wfd(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04001745
1746 // The wrapper BIOs are always equal when fds are equal, even if set
1747 // individually.
David Benjaminf0d8e222017-02-04 10:58:26 -05001748 if (rfd == wfd) {
1749 EXPECT_EQ(SSL_get_rbio(ssl), SSL_get_wbio(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04001750 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001751}
1752
David Benjaminf0d8e222017-02-04 10:58:26 -05001753TEST(SSLTest, SetFD) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001754 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001755 ASSERT_TRUE(ctx);
David Benjamin5c0fb882016-06-14 14:03:51 -04001756
1757 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001758 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001759 ASSERT_TRUE(ssl);
1760 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1761 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
1762 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04001763
1764 // Test setting the same FD.
1765 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001766 ASSERT_TRUE(ssl);
1767 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1768 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001769
1770 // Test setting the same FD one side at a time.
1771 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001772 ASSERT_TRUE(ssl);
1773 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1774 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1775 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001776
1777 // Test setting the same FD in the other order.
1778 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001779 ASSERT_TRUE(ssl);
1780 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1781 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1782 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001783
David Benjamin5c0fb882016-06-14 14:03:51 -04001784 // Test changing the read FD partway through.
1785 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001786 ASSERT_TRUE(ssl);
1787 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1788 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 2));
1789 ExpectFDs(ssl.get(), 2, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001790
1791 // Test changing the write FD partway through.
1792 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001793 ASSERT_TRUE(ssl);
1794 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1795 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
1796 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04001797
1798 // Test a no-op change to the read FD partway through.
1799 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001800 ASSERT_TRUE(ssl);
1801 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1802 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1803 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001804
1805 // Test a no-op change to the write FD partway through.
1806 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001807 ASSERT_TRUE(ssl);
1808 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1809 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1810 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001811
1812 // ASan builds will implicitly test that the internal |BIO| reference-counting
1813 // is correct.
David Benjamin5c0fb882016-06-14 14:03:51 -04001814}
1815
David Benjaminf0d8e222017-02-04 10:58:26 -05001816TEST(SSLTest, SetBIO) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001817 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001818 ASSERT_TRUE(ctx);
David Benjamin4501bd52016-08-01 13:39:41 -04001819
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001820 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1821 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04001822 bio3(BIO_new(BIO_s_mem()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001823 ASSERT_TRUE(ssl);
1824 ASSERT_TRUE(bio1);
1825 ASSERT_TRUE(bio2);
1826 ASSERT_TRUE(bio3);
David Benjamin4501bd52016-08-01 13:39:41 -04001827
1828 // SSL_set_bio takes one reference when the parameters are the same.
1829 BIO_up_ref(bio1.get());
1830 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1831
1832 // Repeating the call does nothing.
1833 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1834
1835 // It takes one reference each when the parameters are different.
1836 BIO_up_ref(bio2.get());
1837 BIO_up_ref(bio3.get());
1838 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1839
1840 // Repeating the call does nothing.
1841 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1842
1843 // It takes one reference when changing only wbio.
1844 BIO_up_ref(bio1.get());
1845 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1846
1847 // It takes one reference when changing only rbio and the two are different.
1848 BIO_up_ref(bio3.get());
1849 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1850
1851 // If setting wbio to rbio, it takes no additional references.
1852 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1853
1854 // From there, wbio may be switched to something else.
1855 BIO_up_ref(bio1.get());
1856 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1857
1858 // If setting rbio to wbio, it takes no additional references.
1859 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1860
1861 // From there, rbio may be switched to something else, but, for historical
1862 // reasons, it takes a reference to both parameters.
1863 BIO_up_ref(bio1.get());
1864 BIO_up_ref(bio2.get());
1865 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1866
1867 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1868 // is correct.
David Benjamin4501bd52016-08-01 13:39:41 -04001869}
1870
David Benjamin25490f22016-07-14 00:22:54 -04001871static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1872
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001873TEST_P(SSLVersionTest, GetPeerCertificate) {
1874 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04001875
David Benjamin0fef3052016-11-18 15:11:10 +09001876 // Configure both client and server to accept any certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001877 SSL_CTX_set_verify(client_ctx_.get(),
1878 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1879 nullptr);
1880 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
1881 SSL_CTX_set_verify(server_ctx_.get(),
1882 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1883 nullptr);
1884 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjaminadd5e522016-07-14 00:33:24 -04001885
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001886 ASSERT_TRUE(Connect());
David Benjaminadd5e522016-07-14 00:33:24 -04001887
David Benjamin0fef3052016-11-18 15:11:10 +09001888 // Client and server should both see the leaf certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001889 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1890 ASSERT_TRUE(peer);
1891 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04001892
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001893 peer.reset(SSL_get_peer_certificate(client_.get()));
1894 ASSERT_TRUE(peer);
1895 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04001896
David Benjamine664a532017-07-20 20:19:36 -04001897 // However, for historical reasons, the X509 chain includes the leaf on the
David Benjamin0fef3052016-11-18 15:11:10 +09001898 // client, but does not on the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001899 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(client_.get())), 1u);
1900 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(client_.get())),
1901 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04001902
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001903 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(server_.get())), 0u);
1904 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(server_.get())),
1905 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04001906}
1907
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001908TEST_P(SSLVersionTest, NoPeerCertificate) {
1909 SSL_CTX_set_verify(server_ctx_.get(), SSL_VERIFY_PEER, nullptr);
1910 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
1911 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
David Benjamine664a532017-07-20 20:19:36 -04001912
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001913 ASSERT_TRUE(Connect());
David Benjamine664a532017-07-20 20:19:36 -04001914
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001915 // Server should not see a peer certificate.
1916 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1917 ASSERT_FALSE(peer);
1918 ASSERT_FALSE(SSL_get0_peer_certificates(server_.get()));
David Benjamine664a532017-07-20 20:19:36 -04001919}
1920
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001921TEST_P(SSLVersionTest, RetainOnlySHA256OfCerts) {
David Benjamin25490f22016-07-14 00:22:54 -04001922 uint8_t *cert_der = NULL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001923 int cert_der_len = i2d_X509(cert_.get(), &cert_der);
1924 ASSERT_GE(cert_der_len, 0);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001925 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04001926
1927 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1928 SHA256(cert_der, cert_der_len, cert_sha256);
1929
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001930 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
1931
David Benjamin0fef3052016-11-18 15:11:10 +09001932 // Configure both client and server to accept any certificate, but the
1933 // server must retain only the SHA-256 of the peer.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001934 SSL_CTX_set_verify(client_ctx_.get(),
1935 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1936 nullptr);
1937 SSL_CTX_set_verify(server_ctx_.get(),
1938 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1939 nullptr);
1940 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
1941 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
1942 SSL_CTX_set_retain_only_sha256_of_client_certs(server_ctx_.get(), 1);
David Benjamin25490f22016-07-14 00:22:54 -04001943
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001944 ASSERT_TRUE(Connect());
David Benjamin25490f22016-07-14 00:22:54 -04001945
David Benjamin0fef3052016-11-18 15:11:10 +09001946 // The peer certificate has been dropped.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001947 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1948 EXPECT_FALSE(peer);
David Benjamin25490f22016-07-14 00:22:54 -04001949
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001950 SSL_SESSION *session = SSL_get_session(server_.get());
David Benjamin02de7bd2018-05-08 18:13:54 -04001951 EXPECT_TRUE(SSL_SESSION_has_peer_sha256(session));
David Benjamin25490f22016-07-14 00:22:54 -04001952
David Benjamin02de7bd2018-05-08 18:13:54 -04001953 const uint8_t *peer_sha256;
1954 size_t peer_sha256_len;
1955 SSL_SESSION_get0_peer_sha256(session, &peer_sha256, &peer_sha256_len);
1956 EXPECT_EQ(Bytes(cert_sha256), Bytes(peer_sha256, peer_sha256_len));
David Benjamin25490f22016-07-14 00:22:54 -04001957}
1958
David Benjamin737d2df2017-09-25 15:05:19 -04001959// Tests that our ClientHellos do not change unexpectedly. These are purely
1960// change detection tests. If they fail as part of an intentional ClientHello
1961// change, update the test vector.
1962TEST(SSLTest, ClientHello) {
1963 struct {
1964 uint16_t max_version;
1965 std::vector<uint8_t> expected;
1966 } kTests[] = {
David Benjamin737d2df2017-09-25 15:05:19 -04001967 {TLS1_VERSION,
1968 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x01, 0x00,
1969 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1970 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1971 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
1972 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001973 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1974 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
David Benjamin737d2df2017-09-25 15:05:19 -04001975 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18}},
1976 {TLS1_1_VERSION,
1977 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x02, 0x00,
1978 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1979 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1980 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
1981 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001982 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1983 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
David Benjamin737d2df2017-09-25 15:05:19 -04001984 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18}},
David Benjamin737d2df2017-09-25 15:05:19 -04001985 {TLS1_2_VERSION,
David Benjamin6e678ee2018-04-16 19:54:42 -04001986 {0x16, 0x03, 0x01, 0x00, 0x82, 0x01, 0x00, 0x00, 0x7e, 0x03, 0x03, 0x00,
David Benjamin737d2df2017-09-25 15:05:19 -04001987 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1988 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
David Benjamin6e678ee2018-04-16 19:54:42 -04001989 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xcc, 0xa9,
David Benjamin737d2df2017-09-25 15:05:19 -04001990 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xc0, 0x09,
David Benjamin6e678ee2018-04-16 19:54:42 -04001991 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
1992 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37, 0xff, 0x01, 0x00, 0x01,
David Benjamin737d2df2017-09-25 15:05:19 -04001993 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
1994 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
1995 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x00, 0x0b, 0x00,
1996 0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00,
1997 0x17, 0x00, 0x18}},
David Benjamin737d2df2017-09-25 15:05:19 -04001998 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
1999 // implementation has settled enough that it won't change.
David Benjaminafc64de2016-07-19 17:12:41 +02002000 };
David Benjamin737d2df2017-09-25 15:05:19 -04002001
2002 for (const auto &t : kTests) {
2003 SCOPED_TRACE(t.max_version);
2004
2005 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2006 ASSERT_TRUE(ctx);
2007 // Our default cipher list varies by CPU capabilities, so manually place the
2008 // ChaCha20 ciphers in front.
2009 const char *cipher_list = "CHACHA20:ALL";
David Benjamin737d2df2017-09-25 15:05:19 -04002010 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), t.max_version));
2011 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list));
2012
2013 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
2014 ASSERT_TRUE(ssl);
2015 std::vector<uint8_t> client_hello;
2016 ASSERT_TRUE(GetClientHello(ssl.get(), &client_hello));
2017
2018 // Zero the client_random.
2019 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
2020 1 + 3 + // handshake message header
2021 2; // client_version
2022 ASSERT_GE(client_hello.size(), kRandomOffset + SSL3_RANDOM_SIZE);
2023 OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
2024
2025 if (client_hello != t.expected) {
2026 ADD_FAILURE() << "ClientHellos did not match.";
2027 // Print the value manually so it is easier to update the test vector.
2028 for (size_t i = 0; i < client_hello.size(); i += 12) {
2029 printf(" %c", i == 0 ? '{' : ' ');
2030 for (size_t j = i; j < client_hello.size() && j < i + 12; j++) {
2031 if (j > i) {
2032 printf(" ");
2033 }
2034 printf("0x%02x", client_hello[j]);
2035 if (j < client_hello.size() - 1) {
2036 printf(",");
2037 }
2038 }
2039 if (i + 12 >= client_hello.size()) {
2040 printf("}}");
2041 }
2042 printf("\n");
2043 }
2044 }
David Benjaminafc64de2016-07-19 17:12:41 +02002045 }
David Benjaminafc64de2016-07-19 17:12:41 +02002046}
2047
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002048static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04002049
2050static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
2051 // Save the most recent session.
2052 g_last_session.reset(session);
2053 return 1;
2054}
2055
David Benjamina8614602017-09-06 15:40:19 -04002056static bssl::UniquePtr<SSL_SESSION> CreateClientSession(
2057 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2058 const ClientConfig &config = ClientConfig()) {
David Benjamina20e5352016-08-02 19:09:41 -04002059 g_last_session = nullptr;
2060 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2061
2062 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002063 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04002064 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
David Benjamina8614602017-09-06 15:40:19 -04002065 config)) {
David Benjamina20e5352016-08-02 19:09:41 -04002066 fprintf(stderr, "Failed to connect client and server.\n");
2067 return nullptr;
2068 }
2069
2070 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2071 SSL_read(client.get(), nullptr, 0);
2072
2073 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2074
2075 if (!g_last_session) {
2076 fprintf(stderr, "Client did not receive a session.\n");
2077 return nullptr;
2078 }
2079 return std::move(g_last_session);
2080}
2081
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002082static void ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2083 SSL_SESSION *session, bool want_reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002084 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002085 ClientConfig config;
2086 config.session = session;
2087 EXPECT_TRUE(
2088 ConnectClientAndServer(&client, &server, client_ctx, server_ctx, config));
David Benjamina20e5352016-08-02 19:09:41 -04002089
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002090 EXPECT_EQ(SSL_session_reused(client.get()), SSL_session_reused(server.get()));
David Benjamina20e5352016-08-02 19:09:41 -04002091
2092 bool was_reused = !!SSL_session_reused(client.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002093 EXPECT_EQ(was_reused, want_reused);
David Benjamina20e5352016-08-02 19:09:41 -04002094}
2095
David Benjamin3c51d9b2016-11-01 17:50:42 -04002096static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
2097 SSL_CTX *server_ctx,
2098 SSL_SESSION *session) {
2099 g_last_session = nullptr;
2100 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2101
2102 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002103 ClientConfig config;
2104 config.session = session;
2105 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
2106 config)) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002107 fprintf(stderr, "Failed to connect client and server.\n");
2108 return nullptr;
2109 }
2110
2111 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2112 fprintf(stderr, "Client and server were inconsistent.\n");
2113 return nullptr;
2114 }
2115
2116 if (!SSL_session_reused(client.get())) {
2117 fprintf(stderr, "Session was not reused.\n");
2118 return nullptr;
2119 }
2120
2121 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2122 SSL_read(client.get(), nullptr, 0);
2123
2124 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2125
2126 if (!g_last_session) {
2127 fprintf(stderr, "Client did not receive a renewed session.\n");
2128 return nullptr;
2129 }
2130 return std::move(g_last_session);
2131}
2132
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002133static void ExpectTicketKeyChanged(SSL_CTX *ctx, uint8_t *inout_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002134 bool changed) {
2135 uint8_t new_key[kTicketKeyLen];
David Benjaminc11ea9422017-08-29 16:33:21 -04002136 // May return 0, 1 or 48.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002137 ASSERT_EQ(SSL_CTX_get_tlsext_ticket_keys(ctx, new_key, kTicketKeyLen), 1);
2138 if (changed) {
2139 ASSERT_NE(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
2140 } else {
2141 ASSERT_EQ(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002142 }
2143 OPENSSL_memcpy(inout_key, new_key, kTicketKeyLen);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002144}
2145
David Benjamina933c382016-10-28 00:10:03 -04002146static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
2147 static const uint8_t kContext[] = {3};
2148
2149 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
2150 return SSL_TLSEXT_ERR_ALERT_FATAL;
2151 }
2152
2153 return SSL_TLSEXT_ERR_OK;
2154}
2155
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002156TEST_P(SSLVersionTest, SessionIDContext) {
David Benjamina20e5352016-08-02 19:09:41 -04002157 static const uint8_t kContext1[] = {1};
2158 static const uint8_t kContext2[] = {2};
2159
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002160 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2161 sizeof(kContext1)));
David Benjamina20e5352016-08-02 19:09:41 -04002162
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002163 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2164 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002165
David Benjamin0fef3052016-11-18 15:11:10 +09002166 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002167 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2168 ASSERT_TRUE(session);
David Benjamina20e5352016-08-02 19:09:41 -04002169
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002170 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2171 session.get(),
2172 true /* expect session reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002173
David Benjamin0fef3052016-11-18 15:11:10 +09002174 // Change the session ID context.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002175 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext2,
2176 sizeof(kContext2)));
David Benjamina20e5352016-08-02 19:09:41 -04002177
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002178 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2179 session.get(),
2180 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002181
David Benjamin0fef3052016-11-18 15:11:10 +09002182 // Change the session ID context back and install an SNI callback to switch
2183 // it.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002184 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2185 sizeof(kContext1)));
David Benjamina933c382016-10-28 00:10:03 -04002186
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002187 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09002188 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04002189
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002190 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2191 session.get(),
2192 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002193
David Benjamin0fef3052016-11-18 15:11:10 +09002194 // Switch the session ID context with the early callback instead.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002195 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), nullptr);
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002196 SSL_CTX_set_select_certificate_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002197 server_ctx_.get(),
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002198 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
2199 static const uint8_t kContext[] = {3};
2200
2201 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
2202 sizeof(kContext))) {
2203 return ssl_select_cert_error;
2204 }
2205
2206 return ssl_select_cert_success;
2207 });
David Benjamina933c382016-10-28 00:10:03 -04002208
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002209 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2210 session.get(),
2211 false /* expect session not reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002212}
2213
David Benjamin721e8b72016-08-03 13:13:17 -04002214static timeval g_current_time;
2215
2216static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2217 *out_clock = g_current_time;
2218}
2219
David Benjamin17b30832017-01-28 14:00:32 -05002220static void FrozenTimeCallback(const SSL *ssl, timeval *out_clock) {
2221 out_clock->tv_sec = 1000;
2222 out_clock->tv_usec = 0;
2223}
2224
David Benjamin3c51d9b2016-11-01 17:50:42 -04002225static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
2226 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
2227 int encrypt) {
2228 static const uint8_t kZeros[16] = {0};
2229
2230 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -05002231 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamin3c51d9b2016-11-01 17:50:42 -04002232 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -05002233 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002234 return 0;
2235 }
2236
2237 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
2238 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
2239 return -1;
2240 }
2241
2242 // Returning two from the callback in decrypt mode renews the
2243 // session in TLS 1.2 and below.
2244 return encrypt ? 1 : 2;
2245}
2246
David Benjamin123db572016-11-03 16:59:25 -04002247static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjamin123db572016-11-03 16:59:25 -04002248 if (session->tlsext_ticklen < 16 + 16 + SHA256_DIGEST_LENGTH) {
2249 return false;
2250 }
2251
David Benjamin123db572016-11-03 16:59:25 -04002252 const uint8_t *ciphertext = session->tlsext_tick + 16 + 16;
2253 size_t len = session->tlsext_ticklen - 16 - 16 - SHA256_DIGEST_LENGTH;
2254 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
2255
David Benjamin9b63f292016-11-15 00:44:05 -05002256#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
2257 // Fuzzer-mode tickets are unencrypted.
David Benjamin17cf2cb2016-12-13 01:07:13 -05002258 OPENSSL_memcpy(plaintext.get(), ciphertext, len);
David Benjamin9b63f292016-11-15 00:44:05 -05002259#else
2260 static const uint8_t kZeros[16] = {0};
2261 const uint8_t *iv = session->tlsext_tick + 16;
David Benjamin123db572016-11-03 16:59:25 -04002262 bssl::ScopedEVP_CIPHER_CTX ctx;
2263 int len1, len2;
2264 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
2265 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
2266 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
2267 return false;
2268 }
2269
2270 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05002271#endif
David Benjamin123db572016-11-03 16:59:25 -04002272
Adam Langley46db7af2017-02-01 15:49:37 -08002273 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
2274 if (!ssl_ctx) {
2275 return false;
2276 }
David Benjamin123db572016-11-03 16:59:25 -04002277 bssl::UniquePtr<SSL_SESSION> server_session(
Adam Langley46db7af2017-02-01 15:49:37 -08002278 SSL_SESSION_from_bytes(plaintext.get(), len, ssl_ctx.get()));
David Benjamin123db572016-11-03 16:59:25 -04002279 if (!server_session) {
2280 return false;
2281 }
2282
2283 *out = server_session->time;
2284 return true;
2285}
2286
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002287TEST_P(SSLVersionTest, SessionTimeout) {
2288 for (bool server_test : {false, true}) {
2289 SCOPED_TRACE(server_test);
David Benjamin721e8b72016-08-03 13:13:17 -04002290
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002291 ResetContexts();
2292 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2293 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
2294
David Benjamin17b30832017-01-28 14:00:32 -05002295 static const time_t kStartTime = 1000;
David Benjamin0fef3052016-11-18 15:11:10 +09002296 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002297
David Benjamin17b30832017-01-28 14:00:32 -05002298 // We are willing to use a longer lifetime for TLS 1.3 sessions as
2299 // resumptions still perform ECDHE.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002300 const time_t timeout = version() == TLS1_3_VERSION
David Benjamin17b30832017-01-28 14:00:32 -05002301 ? SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT
2302 : SSL_DEFAULT_SESSION_TIMEOUT;
2303
David Benjamin17b30832017-01-28 14:00:32 -05002304 // Both client and server must enforce session timeouts. We configure the
2305 // other side with a frozen clock so it never expires tickets.
David Benjamin0fef3052016-11-18 15:11:10 +09002306 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002307 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2308 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002309 } else {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002310 SSL_CTX_set_current_time_cb(client_ctx_.get(), CurrentTimeCallback);
2311 SSL_CTX_set_current_time_cb(server_ctx_.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002312 }
2313
2314 // Configure a ticket callback which renews tickets.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002315 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002316
2317 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002318 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2319 ASSERT_TRUE(session);
David Benjamin0fef3052016-11-18 15:11:10 +09002320
2321 // Advance the clock just behind the timeout.
David Benjamin17b30832017-01-28 14:00:32 -05002322 g_current_time.tv_sec += timeout - 1;
David Benjamin0fef3052016-11-18 15:11:10 +09002323
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002324 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2325 session.get(),
2326 true /* expect session reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002327
2328 // Advance the clock one more second.
2329 g_current_time.tv_sec++;
2330
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002331 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2332 session.get(),
2333 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002334
2335 // Rewind the clock to before the session was minted.
2336 g_current_time.tv_sec = kStartTime - 1;
2337
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002338 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2339 session.get(),
2340 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002341
David Benjamin0fef3052016-11-18 15:11:10 +09002342 // Renew the session 10 seconds before expiration.
David Benjamin17b30832017-01-28 14:00:32 -05002343 time_t new_start_time = kStartTime + timeout - 10;
2344 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002345 bssl::UniquePtr<SSL_SESSION> new_session = ExpectSessionRenewed(
2346 client_ctx_.get(), server_ctx_.get(), session.get());
2347 ASSERT_TRUE(new_session);
David Benjamin0fef3052016-11-18 15:11:10 +09002348
2349 // This new session is not the same object as before.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002350 EXPECT_NE(session.get(), new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002351
2352 // Check the sessions have timestamps measured from issuance.
2353 long session_time = 0;
2354 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002355 ASSERT_TRUE(GetServerTicketTime(&session_time, new_session.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09002356 } else {
2357 session_time = new_session->time;
2358 }
David Benjamin721e8b72016-08-03 13:13:17 -04002359
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002360 ASSERT_EQ(session_time, g_current_time.tv_sec);
David Benjamin721e8b72016-08-03 13:13:17 -04002361
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002362 if (version() == TLS1_3_VERSION) {
David Benjamin17b30832017-01-28 14:00:32 -05002363 // Renewal incorporates fresh key material in TLS 1.3, so we extend the
2364 // lifetime TLS 1.3.
2365 g_current_time.tv_sec = new_start_time + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002366 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2367 new_session.get(),
2368 true /* expect session reused */));
David Benjamin721e8b72016-08-03 13:13:17 -04002369
David Benjamin17b30832017-01-28 14:00:32 -05002370 // The new session expires after the new timeout.
2371 g_current_time.tv_sec = new_start_time + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002372 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2373 new_session.get(),
2374 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002375
2376 // Renew the session until it begins just past the auth timeout.
2377 time_t auth_end_time = kStartTime + SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
2378 while (new_start_time < auth_end_time - 1000) {
2379 // Get as close as possible to target start time.
2380 new_start_time =
2381 std::min(auth_end_time - 1000, new_start_time + timeout - 1);
2382 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002383 new_session = ExpectSessionRenewed(client_ctx_.get(), server_ctx_.get(),
David Benjamin17b30832017-01-28 14:00:32 -05002384 new_session.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002385 ASSERT_TRUE(new_session);
David Benjamin17b30832017-01-28 14:00:32 -05002386 }
2387
2388 // Now the session's lifetime is bound by the auth timeout.
2389 g_current_time.tv_sec = auth_end_time - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002390 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2391 new_session.get(),
2392 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002393
2394 g_current_time.tv_sec = auth_end_time + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002395 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2396 new_session.get(),
2397 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002398 } else {
2399 // The new session is usable just before the old expiration.
2400 g_current_time.tv_sec = kStartTime + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002401 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2402 new_session.get(),
2403 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002404
2405 // Renewal does not extend the lifetime, so it is not usable beyond the
2406 // old expiration.
2407 g_current_time.tv_sec = kStartTime + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002408 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2409 new_session.get(),
2410 false /* expect session not reused */));
David Benjamin1b22f852016-10-27 16:36:32 -04002411 }
David Benjamin721e8b72016-08-03 13:13:17 -04002412 }
David Benjamin721e8b72016-08-03 13:13:17 -04002413}
2414
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002415TEST_P(SSLVersionTest, DefaultTicketKeyInitialization) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002416 static const uint8_t kZeroKey[kTicketKeyLen] = {};
2417 uint8_t ticket_key[kTicketKeyLen];
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002418 ASSERT_EQ(1, SSL_CTX_get_tlsext_ticket_keys(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002419 kTicketKeyLen));
2420 ASSERT_NE(0, OPENSSL_memcmp(ticket_key, kZeroKey, kTicketKeyLen));
2421}
2422
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002423TEST_P(SSLVersionTest, DefaultTicketKeyRotation) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002424 static const time_t kStartTime = 1001;
2425 g_current_time.tv_sec = kStartTime;
2426 uint8_t ticket_key[kTicketKeyLen];
2427
David Benjaminc11ea9422017-08-29 16:33:21 -04002428 // We use session reuse as a proxy for ticket decryption success, hence
2429 // disable session timeouts.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002430 SSL_CTX_set_timeout(server_ctx_.get(), std::numeric_limits<uint32_t>::max());
2431 SSL_CTX_set_session_psk_dhe_timeout(server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002432 std::numeric_limits<uint32_t>::max());
2433
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002434 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2435 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002436
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002437 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2438 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_OFF);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002439
David Benjaminc11ea9422017-08-29 16:33:21 -04002440 // Initialize ticket_key with the current key.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002441 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2442 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002443
David Benjaminc11ea9422017-08-29 16:33:21 -04002444 // Verify ticket resumption actually works.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002445 bssl::UniquePtr<SSL> client, server;
2446 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002447 CreateClientSession(client_ctx_.get(), server_ctx_.get());
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002448 ASSERT_TRUE(session);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002449 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002450 session.get(), true /* reused */));
2451
David Benjaminc11ea9422017-08-29 16:33:21 -04002452 // Advance time to just before key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002453 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002454 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002455 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002456 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002457 false /* NOT changed */));
2458
David Benjaminc11ea9422017-08-29 16:33:21 -04002459 // Force key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002460 g_current_time.tv_sec += 1;
2461 bssl::UniquePtr<SSL_SESSION> new_session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002462 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2463 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2464 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002465
David Benjaminc11ea9422017-08-29 16:33:21 -04002466 // Resumption with both old and new ticket should work.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002467 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002468 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002469 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002470 new_session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002471 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002472 false /* NOT changed */));
2473
David Benjaminc11ea9422017-08-29 16:33:21 -04002474 // Force key rotation again. Resumption with the old ticket now fails.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002475 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002476 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002477 session.get(), false /* NOT reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002478 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2479 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002480
David Benjaminc11ea9422017-08-29 16:33:21 -04002481 // But resumption with the newer session still works.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002482 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002483 new_session.get(), true /* reused */));
2484}
2485
David Benjamin0fc37ef2016-08-17 15:29:46 -04002486static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002487 SSL_CTX *ctx = reinterpret_cast<SSL_CTX *>(arg);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002488 SSL_set_SSL_CTX(ssl, ctx);
2489 return SSL_TLSEXT_ERR_OK;
2490}
2491
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002492TEST_P(SSLVersionTest, SNICallback) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002493 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002494 ASSERT_TRUE(cert2);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002495 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002496 ASSERT_TRUE(key2);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002497
David Benjamin0fef3052016-11-18 15:11:10 +09002498 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
2499 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002500
David Benjamin83a32122017-02-14 18:34:54 -05002501 static const uint8_t kSCTList[] = {0, 6, 0, 4, 5, 6, 7, 8};
2502 static const uint8_t kOCSPResponse[] = {1, 2, 3, 4};
2503
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002504 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
2505 ASSERT_TRUE(server_ctx2);
2506 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()));
2507 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()));
2508 ASSERT_TRUE(SSL_CTX_set_signed_cert_timestamp_list(
2509 server_ctx2.get(), kSCTList, sizeof(kSCTList)));
2510 ASSERT_TRUE(SSL_CTX_set_ocsp_response(server_ctx2.get(), kOCSPResponse,
2511 sizeof(kOCSPResponse)));
2512 // Historically signing preferences would be lost in some cases with the
2513 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2514 // this doesn't happen when |version| is TLS 1.2, configure the private
2515 // key to only sign SHA-256.
2516 ASSERT_TRUE(SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
2517 &kECDSAWithSHA256, 1));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002518
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002519 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), SwitchContext);
2520 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002521
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002522 SSL_CTX_enable_signed_cert_timestamps(client_ctx_.get());
2523 SSL_CTX_enable_ocsp_stapling(client_ctx_.get());
David Benjamin83a32122017-02-14 18:34:54 -05002524
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002525 ASSERT_TRUE(Connect());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002526
David Benjamin0fef3052016-11-18 15:11:10 +09002527 // The client should have received |cert2|.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002528 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client_.get()));
2529 ASSERT_TRUE(peer);
2530 EXPECT_EQ(X509_cmp(peer.get(), cert2.get()), 0);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002531
David Benjamin83a32122017-02-14 18:34:54 -05002532 // The client should have received |server_ctx2|'s SCT list.
2533 const uint8_t *data;
2534 size_t len;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002535 SSL_get0_signed_cert_timestamp_list(client_.get(), &data, &len);
2536 EXPECT_EQ(Bytes(kSCTList), Bytes(data, len));
David Benjamin83a32122017-02-14 18:34:54 -05002537
2538 // The client should have received |server_ctx2|'s OCSP response.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002539 SSL_get0_ocsp_response(client_.get(), &data, &len);
2540 EXPECT_EQ(Bytes(kOCSPResponse), Bytes(data, len));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002541}
2542
David Benjaminf0d8e222017-02-04 10:58:26 -05002543// Test that the early callback can swap the maximum version.
2544TEST(SSLTest, EarlyCallbackVersionSwitch) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002545 bssl::UniquePtr<X509> cert = GetTestCertificate();
2546 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2547 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2548 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002549 ASSERT_TRUE(cert);
2550 ASSERT_TRUE(key);
2551 ASSERT_TRUE(server_ctx);
2552 ASSERT_TRUE(client_ctx);
2553 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
2554 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
2555 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
2556 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
David Benjamin99620572016-08-30 00:35:36 -04002557
David Benjaminf0d8e222017-02-04 10:58:26 -05002558 SSL_CTX_set_select_certificate_cb(
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002559 server_ctx.get(),
2560 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
David Benjaminf0d8e222017-02-04 10:58:26 -05002561 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002562 return ssl_select_cert_error;
David Benjaminf0d8e222017-02-04 10:58:26 -05002563 }
2564
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002565 return ssl_select_cert_success;
David Benjaminf0d8e222017-02-04 10:58:26 -05002566 });
David Benjamin99620572016-08-30 00:35:36 -04002567
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002568 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05002569 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04002570 server_ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002571 EXPECT_EQ(TLS1_2_VERSION, SSL_version(client.get()));
David Benjamin99620572016-08-30 00:35:36 -04002572}
2573
David Benjaminf0d8e222017-02-04 10:58:26 -05002574TEST(SSLTest, SetVersion) {
David Benjamin2dc02042016-09-19 19:57:37 -04002575 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002576 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002577
David Benjaminf0d8e222017-02-04 10:58:26 -05002578 // Set valid TLS versions.
2579 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2580 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
2581 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2582 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002583
David Benjaminf0d8e222017-02-04 10:58:26 -05002584 // Invalid TLS versions are rejected.
2585 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2586 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x0200));
2587 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2588 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2589 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x0200));
2590 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002591
David Benjaminf0d8e222017-02-04 10:58:26 -05002592 // Zero is the default version.
2593 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002594 EXPECT_EQ(TLS1_2_VERSION, ctx->conf_max_version);
David Benjaminf0d8e222017-02-04 10:58:26 -05002595 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002596 EXPECT_EQ(TLS1_VERSION, ctx->conf_min_version);
David Benjamin3cfeb952017-03-01 16:48:38 -05002597
David Benjamin9bb15f52018-06-26 00:07:40 -04002598 // TLS 1.3 is available, but not by default.
David Benjamin3cfeb952017-03-01 16:48:38 -05002599 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002600 EXPECT_EQ(TLS1_3_VERSION, ctx->conf_max_version);
David Benjamine34bcc92016-09-21 16:53:09 -04002601
David Benjamin9bb15f52018-06-26 00:07:40 -04002602 // SSL 3.0 is not available.
2603 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION));
2604
David Benjamin353577c2017-06-29 15:54:58 -04002605 // TLS1_3_DRAFT_VERSION is not an API-level version.
Steven Valdez64cc1212017-12-04 11:15:37 -05002606 EXPECT_FALSE(
Steven Valdez7e5dd252018-01-22 15:20:31 -05002607 SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_DRAFT23_VERSION));
David Benjamin353577c2017-06-29 15:54:58 -04002608 ERR_clear_error();
2609
David Benjamin2dc02042016-09-19 19:57:37 -04002610 ctx.reset(SSL_CTX_new(DTLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002611 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002612
David Benjaminf0d8e222017-02-04 10:58:26 -05002613 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2614 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION));
2615 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2616 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002617
David Benjaminf0d8e222017-02-04 10:58:26 -05002618 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2619 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2620 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2621 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2622 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2623 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2624 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2625 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002626
David Benjaminf0d8e222017-02-04 10:58:26 -05002627 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002628 EXPECT_EQ(TLS1_2_VERSION, ctx->conf_max_version);
David Benjaminf0d8e222017-02-04 10:58:26 -05002629 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002630 EXPECT_EQ(TLS1_1_VERSION, ctx->conf_min_version);
David Benjamin2dc02042016-09-19 19:57:37 -04002631}
2632
David Benjamin458334a2016-12-15 13:53:25 -05002633static const char *GetVersionName(uint16_t version) {
2634 switch (version) {
David Benjamin458334a2016-12-15 13:53:25 -05002635 case TLS1_VERSION:
2636 return "TLSv1";
2637 case TLS1_1_VERSION:
2638 return "TLSv1.1";
2639 case TLS1_2_VERSION:
2640 return "TLSv1.2";
2641 case TLS1_3_VERSION:
2642 return "TLSv1.3";
2643 case DTLS1_VERSION:
2644 return "DTLSv1";
2645 case DTLS1_2_VERSION:
2646 return "DTLSv1.2";
2647 default:
2648 return "???";
2649 }
2650}
2651
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002652TEST_P(SSLVersionTest, Version) {
2653 ASSERT_TRUE(Connect());
David Benjamincb18ac22016-09-27 14:09:15 -04002654
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002655 EXPECT_EQ(SSL_version(client_.get()), version());
2656 EXPECT_EQ(SSL_version(server_.get()), version());
David Benjamincb18ac22016-09-27 14:09:15 -04002657
David Benjamin458334a2016-12-15 13:53:25 -05002658 // Test the version name is reported as expected.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002659 const char *version_name = GetVersionName(version());
2660 EXPECT_EQ(strcmp(version_name, SSL_get_version(client_.get())), 0);
2661 EXPECT_EQ(strcmp(version_name, SSL_get_version(server_.get())), 0);
David Benjamin458334a2016-12-15 13:53:25 -05002662
2663 // Test SSL_SESSION reports the same name.
2664 const char *client_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002665 SSL_SESSION_get_version(SSL_get_session(client_.get()));
David Benjamin458334a2016-12-15 13:53:25 -05002666 const char *server_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002667 SSL_SESSION_get_version(SSL_get_session(server_.get()));
2668 EXPECT_EQ(strcmp(version_name, client_name), 0);
2669 EXPECT_EQ(strcmp(version_name, server_name), 0);
David Benjamincb18ac22016-09-27 14:09:15 -04002670}
2671
David Benjamin9ef31f02016-10-31 18:01:13 -04002672// Tests that that |SSL_get_pending_cipher| is available during the ALPN
2673// selection callback.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002674TEST_P(SSLVersionTest, ALPNCipherAvailable) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002675 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2676
David Benjamin9ef31f02016-10-31 18:01:13 -04002677 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002678 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
2679 sizeof(kALPNProtos)),
2680 0);
David Benjamin0fef3052016-11-18 15:11:10 +09002681
2682 // The ALPN callback does not fail the handshake on error, so have the
2683 // callback write a boolean.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002684 std::pair<uint16_t, bool> callback_state(version(), false);
David Benjamin0fef3052016-11-18 15:11:10 +09002685 SSL_CTX_set_alpn_select_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002686 server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09002687 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
2688 unsigned in_len, void *arg) -> int {
2689 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
2690 if (SSL_get_pending_cipher(ssl) != nullptr &&
2691 SSL_version(ssl) == state->first) {
2692 state->second = true;
2693 }
2694 return SSL_TLSEXT_ERR_NOACK;
2695 },
2696 &callback_state);
2697
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002698 ASSERT_TRUE(Connect());
David Benjamin0fef3052016-11-18 15:11:10 +09002699
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002700 ASSERT_TRUE(callback_state.second);
David Benjamin0fef3052016-11-18 15:11:10 +09002701}
2702
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002703TEST_P(SSLVersionTest, SSLClearSessionResumption) {
David Benjaminb79cc842016-12-07 15:57:14 -05002704 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
2705 // API pattern.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002706 if (version() == TLS1_3_VERSION) {
2707 return;
David Benjaminb79cc842016-12-07 15:57:14 -05002708 }
2709
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07002710 shed_handshake_config_ = false;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002711 ASSERT_TRUE(Connect());
David Benjaminb79cc842016-12-07 15:57:14 -05002712
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002713 EXPECT_FALSE(SSL_session_reused(client_.get()));
2714 EXPECT_FALSE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002715
2716 // Reset everything.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002717 ASSERT_TRUE(SSL_clear(client_.get()));
2718 ASSERT_TRUE(SSL_clear(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002719
2720 // Attempt to connect a second time.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002721 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002722
2723 // |SSL_clear| should implicitly offer the previous session to the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002724 EXPECT_TRUE(SSL_session_reused(client_.get()));
2725 EXPECT_TRUE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002726}
2727
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07002728TEST_P(SSLVersionTest, SSLClearFailsWithShedding) {
2729 shed_handshake_config_ = false;
2730 ASSERT_TRUE(Connect());
2731 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
2732
2733 // Reset everything.
2734 ASSERT_TRUE(SSL_clear(client_.get()));
2735 ASSERT_TRUE(SSL_clear(server_.get()));
2736
2737 // Now enable shedding, and connect a second time.
2738 shed_handshake_config_ = true;
2739 ASSERT_TRUE(Connect());
2740 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
2741
2742 // |SSL_clear| should now fail.
2743 ASSERT_FALSE(SSL_clear(client_.get()));
2744 ASSERT_FALSE(SSL_clear(server_.get()));
2745}
2746
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002747static bool ChainsEqual(STACK_OF(X509) * chain,
2748 const std::vector<X509 *> &expected) {
David Benjamin1444c3a2016-12-20 17:23:11 -05002749 if (sk_X509_num(chain) != expected.size()) {
2750 return false;
2751 }
2752
2753 for (size_t i = 0; i < expected.size(); i++) {
2754 if (X509_cmp(sk_X509_value(chain, i), expected[i]) != 0) {
2755 return false;
2756 }
2757 }
2758
2759 return true;
2760}
2761
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002762TEST_P(SSLVersionTest, AutoChain) {
2763 cert_ = GetChainTestCertificate();
2764 ASSERT_TRUE(cert_);
2765 key_ = GetChainTestKey();
2766 ASSERT_TRUE(key_);
David Benjamin1444c3a2016-12-20 17:23:11 -05002767 bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002768 ASSERT_TRUE(intermediate);
2769
2770 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2771 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin1444c3a2016-12-20 17:23:11 -05002772
2773 // Configure both client and server to accept any certificate. Add
2774 // |intermediate| to the cert store.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002775 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx_.get()),
2776 intermediate.get()));
2777 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(server_ctx_.get()),
2778 intermediate.get()));
2779 SSL_CTX_set_verify(client_ctx_.get(),
2780 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2781 nullptr);
2782 SSL_CTX_set_verify(server_ctx_.get(),
2783 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2784 nullptr);
2785 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
2786 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjamin1444c3a2016-12-20 17:23:11 -05002787
2788 // By default, the client and server should each only send the leaf.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002789 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002790
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002791 EXPECT_TRUE(
2792 ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()), {cert_.get()}));
2793 EXPECT_TRUE(
2794 ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()), {cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002795
2796 // If auto-chaining is enabled, then the intermediate is sent.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002797 SSL_CTX_clear_mode(client_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
2798 SSL_CTX_clear_mode(server_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
2799 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002800
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002801 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
2802 {cert_.get(), intermediate.get()}));
2803 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
2804 {cert_.get(), intermediate.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002805
2806 // Auto-chaining does not override explicitly-configured intermediates.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002807 ASSERT_TRUE(SSL_CTX_add1_chain_cert(client_ctx_.get(), cert_.get()));
2808 ASSERT_TRUE(SSL_CTX_add1_chain_cert(server_ctx_.get(), cert_.get()));
2809 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002810
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002811 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
2812 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002813
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002814 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
2815 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002816}
2817
David Benjamin48063c22017-01-01 23:56:36 -05002818static bool ExpectBadWriteRetry() {
2819 int err = ERR_get_error();
2820 if (ERR_GET_LIB(err) != ERR_LIB_SSL ||
2821 ERR_GET_REASON(err) != SSL_R_BAD_WRITE_RETRY) {
2822 char buf[ERR_ERROR_STRING_BUF_LEN];
2823 ERR_error_string_n(err, buf, sizeof(buf));
2824 fprintf(stderr, "Wanted SSL_R_BAD_WRITE_RETRY, got: %s.\n", buf);
2825 return false;
2826 }
2827
2828 if (ERR_peek_error() != 0) {
2829 fprintf(stderr, "Unexpected error following SSL_R_BAD_WRITE_RETRY.\n");
2830 return false;
2831 }
2832
2833 return true;
2834}
2835
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002836TEST_P(SSLVersionTest, SSLWriteRetry) {
2837 if (is_dtls()) {
2838 return;
David Benjamin48063c22017-01-01 23:56:36 -05002839 }
2840
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002841 for (bool enable_partial_write : {false, true}) {
2842 SCOPED_TRACE(enable_partial_write);
2843
David Benjamin48063c22017-01-01 23:56:36 -05002844 // Connect a client and server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002845 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2846
2847 ASSERT_TRUE(Connect());
David Benjamin48063c22017-01-01 23:56:36 -05002848
2849 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002850 SSL_set_mode(client_.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002851 }
2852
2853 // Write without reading until the buffer is full and we have an unfinished
2854 // write. Keep a count so we may reread it again later. "hello!" will be
2855 // written in two chunks, "hello" and "!".
2856 char data[] = "hello!";
2857 static const int kChunkLen = 5; // The length of "hello".
2858 unsigned count = 0;
2859 for (;;) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002860 int ret = SSL_write(client_.get(), data, kChunkLen);
David Benjamin48063c22017-01-01 23:56:36 -05002861 if (ret <= 0) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002862 ASSERT_EQ(SSL_get_error(client_.get(), ret), SSL_ERROR_WANT_WRITE);
2863 break;
David Benjamin48063c22017-01-01 23:56:36 -05002864 }
2865
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002866 ASSERT_EQ(ret, 5);
David Benjamin48063c22017-01-01 23:56:36 -05002867
2868 count++;
2869 }
2870
2871 // Retrying with the same parameters is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002872 ASSERT_EQ(
2873 SSL_get_error(client_.get(), SSL_write(client_.get(), data, kChunkLen)),
2874 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002875
2876 // Retrying with the same buffer but shorter length is not legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002877 ASSERT_EQ(SSL_get_error(client_.get(),
2878 SSL_write(client_.get(), data, kChunkLen - 1)),
2879 SSL_ERROR_SSL);
2880 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002881
2882 // Retrying with a different buffer pointer is not legal.
2883 char data2[] = "hello";
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002884 ASSERT_EQ(SSL_get_error(client_.get(),
2885 SSL_write(client_.get(), data2, kChunkLen)),
2886 SSL_ERROR_SSL);
2887 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002888
2889 // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002890 SSL_set_mode(client_.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
2891 ASSERT_EQ(SSL_get_error(client_.get(),
2892 SSL_write(client_.get(), data2, kChunkLen)),
2893 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002894
2895 // |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| does not disable length checks.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002896 ASSERT_EQ(SSL_get_error(client_.get(),
2897 SSL_write(client_.get(), data2, kChunkLen - 1)),
2898 SSL_ERROR_SSL);
2899 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002900
2901 // Retrying with a larger buffer is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002902 ASSERT_EQ(SSL_get_error(client_.get(),
2903 SSL_write(client_.get(), data, kChunkLen + 1)),
2904 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002905
2906 // Drain the buffer.
2907 char buf[20];
2908 for (unsigned i = 0; i < count; i++) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002909 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
2910 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
David Benjamin48063c22017-01-01 23:56:36 -05002911 }
2912
2913 // Now that there is space, a retry with a larger buffer should flush the
2914 // pending record, skip over that many bytes of input (on assumption they
2915 // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE
2916 // is set, this will complete in two steps.
2917 char data3[] = "_____!";
2918 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002919 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen);
2920 ASSERT_EQ(SSL_write(client_.get(), data3 + kChunkLen, 1), 1);
2921 } else {
2922 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen + 1);
David Benjamin48063c22017-01-01 23:56:36 -05002923 }
2924
2925 // Check the last write was correct. The data will be spread over two
2926 // records, so SSL_read returns twice.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002927 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
2928 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
2929 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), 1);
2930 ASSERT_EQ(buf[0], '!');
David Benjamin48063c22017-01-01 23:56:36 -05002931 }
David Benjamin48063c22017-01-01 23:56:36 -05002932}
2933
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002934TEST_P(SSLVersionTest, RecordCallback) {
2935 for (bool test_server : {true, false}) {
2936 SCOPED_TRACE(test_server);
2937 ResetContexts();
David Benjamin5df5be12017-06-22 19:43:11 -04002938
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002939 bool read_seen = false;
2940 bool write_seen = false;
2941 auto cb = [&](int is_write, int cb_version, int cb_type, const void *buf,
2942 size_t len, SSL *ssl) {
2943 if (cb_type != SSL3_RT_HEADER) {
2944 return;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002945 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002946
2947 // The callback does not report a version for records.
2948 EXPECT_EQ(0, cb_version);
2949
2950 if (is_write) {
2951 write_seen = true;
2952 } else {
2953 read_seen = true;
2954 }
2955
2956 // Sanity-check that the record header is plausible.
2957 CBS cbs;
2958 CBS_init(&cbs, reinterpret_cast<const uint8_t *>(buf), len);
2959 uint8_t type;
2960 uint16_t record_version, length;
2961 ASSERT_TRUE(CBS_get_u8(&cbs, &type));
2962 ASSERT_TRUE(CBS_get_u16(&cbs, &record_version));
Steven Valdez64cc1212017-12-04 11:15:37 -05002963 EXPECT_EQ(record_version & 0xff00, version() & 0xff00);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002964 if (is_dtls()) {
2965 uint16_t epoch;
2966 ASSERT_TRUE(CBS_get_u16(&cbs, &epoch));
2967 EXPECT_TRUE(epoch == 0 || epoch == 1) << "Invalid epoch: " << epoch;
2968 ASSERT_TRUE(CBS_skip(&cbs, 6));
2969 }
2970 ASSERT_TRUE(CBS_get_u16(&cbs, &length));
2971 EXPECT_EQ(0u, CBS_len(&cbs));
2972 };
2973 using CallbackType = decltype(cb);
2974 SSL_CTX *ctx = test_server ? server_ctx_.get() : client_ctx_.get();
2975 SSL_CTX_set_msg_callback(
2976 ctx, [](int is_write, int cb_version, int cb_type, const void *buf,
2977 size_t len, SSL *ssl, void *arg) {
2978 CallbackType *cb_ptr = reinterpret_cast<CallbackType *>(arg);
2979 (*cb_ptr)(is_write, cb_version, cb_type, buf, len, ssl);
2980 });
2981 SSL_CTX_set_msg_callback_arg(ctx, &cb);
2982
2983 ASSERT_TRUE(Connect());
2984
2985 EXPECT_TRUE(read_seen);
2986 EXPECT_TRUE(write_seen);
David Benjamin0fef3052016-11-18 15:11:10 +09002987 }
David Benjamin9ef31f02016-10-31 18:01:13 -04002988}
2989
David Benjamina8614602017-09-06 15:40:19 -04002990TEST_P(SSLVersionTest, GetServerName) {
David Benjamina8614602017-09-06 15:40:19 -04002991 ClientConfig config;
2992 config.servername = "host1";
2993
2994 SSL_CTX_set_tlsext_servername_callback(
2995 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
2996 // During the handshake, |SSL_get_servername| must match |config|.
2997 ClientConfig *config_p = reinterpret_cast<ClientConfig *>(arg);
2998 EXPECT_STREQ(config_p->servername.c_str(),
2999 SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name));
3000 return SSL_TLSEXT_ERR_OK;
3001 });
3002 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), &config);
3003
3004 ASSERT_TRUE(Connect(config));
3005 // After the handshake, it must also be available.
3006 EXPECT_STREQ(config.servername.c_str(),
3007 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3008
3009 // Establish a session under host1.
3010 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3011 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3012 bssl::UniquePtr<SSL_SESSION> session =
3013 CreateClientSession(client_ctx_.get(), server_ctx_.get(), config);
3014
3015 // If the client resumes a session with a different name, |SSL_get_servername|
3016 // must return the new name.
3017 ASSERT_TRUE(session);
3018 config.session = session.get();
3019 config.servername = "host2";
3020 ASSERT_TRUE(Connect(config));
3021 EXPECT_STREQ(config.servername.c_str(),
3022 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3023}
3024
David Benjamin3d8f0802017-09-06 16:12:52 -04003025// Test that session cache mode bits are honored in the client session callback.
3026TEST_P(SSLVersionTest, ClientSessionCacheMode) {
3027 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_OFF);
3028 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3029
3030 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_CLIENT);
3031 EXPECT_TRUE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3032
3033 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_SERVER);
3034 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3035}
3036
Adam Langleye1e78132017-01-31 15:24:31 -08003037TEST(SSLTest, AddChainCertHack) {
3038 // Ensure that we don't accidently break the hack that we have in place to
3039 // keep curl and serf happy when they use an |X509| even after transfering
3040 // ownership.
3041
3042 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3043 ASSERT_TRUE(ctx);
3044 X509 *cert = GetTestCertificate().release();
3045 ASSERT_TRUE(cert);
3046 SSL_CTX_add0_chain_cert(ctx.get(), cert);
3047
3048 // This should not trigger a use-after-free.
3049 X509_cmp(cert, cert);
3050}
3051
David Benjaminb2ff2622017-02-03 17:06:18 -05003052TEST(SSLTest, GetCertificate) {
3053 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3054 ASSERT_TRUE(ctx);
3055 bssl::UniquePtr<X509> cert = GetTestCertificate();
3056 ASSERT_TRUE(cert);
3057 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
3058 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3059 ASSERT_TRUE(ssl);
3060
3061 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
3062 ASSERT_TRUE(cert2);
3063 X509 *cert3 = SSL_get_certificate(ssl.get());
3064 ASSERT_TRUE(cert3);
3065
3066 // The old and new certificates must be identical.
3067 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
3068 EXPECT_EQ(0, X509_cmp(cert.get(), cert3));
3069
3070 uint8_t *der = nullptr;
3071 long der_len = i2d_X509(cert.get(), &der);
3072 ASSERT_LT(0, der_len);
3073 bssl::UniquePtr<uint8_t> free_der(der);
3074
3075 uint8_t *der2 = nullptr;
3076 long der2_len = i2d_X509(cert2, &der2);
3077 ASSERT_LT(0, der2_len);
3078 bssl::UniquePtr<uint8_t> free_der2(der2);
3079
3080 uint8_t *der3 = nullptr;
3081 long der3_len = i2d_X509(cert3, &der3);
3082 ASSERT_LT(0, der3_len);
3083 bssl::UniquePtr<uint8_t> free_der3(der3);
3084
3085 // They must also encode identically.
David Benjamin7d7554b2017-02-04 11:48:59 -05003086 EXPECT_EQ(Bytes(der, der_len), Bytes(der2, der2_len));
3087 EXPECT_EQ(Bytes(der, der_len), Bytes(der3, der3_len));
David Benjaminb2ff2622017-02-03 17:06:18 -05003088}
3089
Adam Langleyd04ca952017-02-28 11:26:51 -08003090TEST(SSLTest, SetChainAndKeyMismatch) {
3091 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_with_buffers_method()));
3092 ASSERT_TRUE(ctx);
3093
3094 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3095 ASSERT_TRUE(key);
3096 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3097 ASSERT_TRUE(leaf);
3098 std::vector<CRYPTO_BUFFER*> chain = {
3099 leaf.get(),
3100 };
3101
3102 // Should fail because |GetTestKey| doesn't match the chain-test certificate.
3103 ASSERT_FALSE(SSL_CTX_set_chain_and_key(ctx.get(), &chain[0], chain.size(),
3104 key.get(), nullptr));
3105 ERR_clear_error();
3106}
3107
3108TEST(SSLTest, SetChainAndKey) {
3109 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3110 ASSERT_TRUE(client_ctx);
3111 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3112 ASSERT_TRUE(server_ctx);
3113
3114 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3115 ASSERT_TRUE(key);
3116 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3117 ASSERT_TRUE(leaf);
3118 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3119 GetChainTestIntermediateBuffer();
3120 ASSERT_TRUE(intermediate);
3121 std::vector<CRYPTO_BUFFER*> chain = {
3122 leaf.get(), intermediate.get(),
3123 };
3124 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3125 chain.size(), key.get(), nullptr));
3126
David Benjamin3a1dd462017-07-11 16:13:10 -04003127 SSL_CTX_set_custom_verify(
3128 client_ctx.get(), SSL_VERIFY_PEER,
3129 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3130 return ssl_verify_ok;
3131 });
Adam Langleyd04ca952017-02-28 11:26:51 -08003132
3133 bssl::UniquePtr<SSL> client, server;
3134 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003135 server_ctx.get()));
Adam Langleyd04ca952017-02-28 11:26:51 -08003136}
3137
Matthew Braithwaite5301c102018-01-23 12:08:55 -08003138TEST(SSLTest, BuffersFailWithoutCustomVerify) {
3139 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3140 ASSERT_TRUE(client_ctx);
3141 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3142 ASSERT_TRUE(server_ctx);
3143
3144 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3145 ASSERT_TRUE(key);
3146 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3147 ASSERT_TRUE(leaf);
3148 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
3149 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3150 chain.size(), key.get(), nullptr));
3151
3152 // Without SSL_CTX_set_custom_verify(), i.e. with everything in the default
3153 // configuration, certificate verification should fail.
3154 bssl::UniquePtr<SSL> client, server;
3155 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3156 server_ctx.get()));
3157
3158 // Whereas with a verifier, the connection should succeed.
3159 SSL_CTX_set_custom_verify(
3160 client_ctx.get(), SSL_VERIFY_PEER,
3161 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3162 return ssl_verify_ok;
3163 });
3164 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3165 server_ctx.get()));
3166}
3167
3168TEST(SSLTest, CustomVerify) {
3169 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3170 ASSERT_TRUE(client_ctx);
3171 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3172 ASSERT_TRUE(server_ctx);
3173
3174 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3175 ASSERT_TRUE(key);
3176 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3177 ASSERT_TRUE(leaf);
3178 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
3179 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3180 chain.size(), key.get(), nullptr));
3181
3182 SSL_CTX_set_custom_verify(
3183 client_ctx.get(), SSL_VERIFY_PEER,
3184 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3185 return ssl_verify_ok;
3186 });
3187
3188 bssl::UniquePtr<SSL> client, server;
3189 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3190 server_ctx.get()));
3191
3192 // With SSL_VERIFY_PEER, ssl_verify_invalid should result in a dropped
3193 // connection.
3194 SSL_CTX_set_custom_verify(
3195 client_ctx.get(), SSL_VERIFY_PEER,
3196 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3197 return ssl_verify_invalid;
3198 });
3199
3200 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3201 server_ctx.get()));
3202
3203 // But with SSL_VERIFY_NONE, ssl_verify_invalid should not cause a dropped
3204 // connection.
3205 SSL_CTX_set_custom_verify(
3206 client_ctx.get(), SSL_VERIFY_NONE,
3207 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3208 return ssl_verify_invalid;
3209 });
3210
3211 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3212 server_ctx.get()));
3213}
3214
David Benjamin71dfad42017-07-16 17:27:39 -04003215TEST(SSLTest, ClientCABuffers) {
3216 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3217 ASSERT_TRUE(client_ctx);
3218 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3219 ASSERT_TRUE(server_ctx);
3220
3221 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3222 ASSERT_TRUE(key);
3223 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3224 ASSERT_TRUE(leaf);
3225 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3226 GetChainTestIntermediateBuffer();
3227 ASSERT_TRUE(intermediate);
3228 std::vector<CRYPTO_BUFFER *> chain = {
3229 leaf.get(),
3230 intermediate.get(),
3231 };
3232 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3233 chain.size(), key.get(), nullptr));
3234
3235 bssl::UniquePtr<CRYPTO_BUFFER> ca_name(
3236 CRYPTO_BUFFER_new(kTestName, sizeof(kTestName), nullptr));
3237 ASSERT_TRUE(ca_name);
3238 bssl::UniquePtr<STACK_OF(CRYPTO_BUFFER)> ca_names(
3239 sk_CRYPTO_BUFFER_new_null());
3240 ASSERT_TRUE(ca_names);
3241 ASSERT_TRUE(sk_CRYPTO_BUFFER_push(ca_names.get(), ca_name.get()));
3242 ca_name.release();
3243 SSL_CTX_set0_client_CAs(server_ctx.get(), ca_names.release());
3244
3245 // Configure client and server to accept all certificates.
3246 SSL_CTX_set_custom_verify(
3247 client_ctx.get(), SSL_VERIFY_PEER,
3248 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3249 return ssl_verify_ok;
3250 });
3251 SSL_CTX_set_custom_verify(
3252 server_ctx.get(), SSL_VERIFY_PEER,
3253 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3254 return ssl_verify_ok;
3255 });
3256
3257 bool cert_cb_called = false;
3258 SSL_CTX_set_cert_cb(
3259 client_ctx.get(),
3260 [](SSL *ssl, void *arg) -> int {
David Benjamin5f001d12018-05-08 16:46:48 -04003261 const STACK_OF(CRYPTO_BUFFER) *peer_names =
David Benjamin71dfad42017-07-16 17:27:39 -04003262 SSL_get0_server_requested_CAs(ssl);
3263 EXPECT_EQ(1u, sk_CRYPTO_BUFFER_num(peer_names));
3264 CRYPTO_BUFFER *peer_name = sk_CRYPTO_BUFFER_value(peer_names, 0);
3265 EXPECT_EQ(Bytes(kTestName), Bytes(CRYPTO_BUFFER_data(peer_name),
3266 CRYPTO_BUFFER_len(peer_name)));
3267 *reinterpret_cast<bool *>(arg) = true;
3268 return 1;
3269 },
3270 &cert_cb_called);
3271
3272 bssl::UniquePtr<SSL> client, server;
3273 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003274 server_ctx.get()));
David Benjamin71dfad42017-07-16 17:27:39 -04003275 EXPECT_TRUE(cert_cb_called);
3276}
3277
David Benjamin91222b82017-03-09 20:10:56 -05003278// Configuring the empty cipher list, though an error, should still modify the
3279// configuration.
3280TEST(SSLTest, EmptyCipherList) {
3281 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3282 ASSERT_TRUE(ctx);
3283
3284 // Initially, the cipher list is not empty.
3285 EXPECT_NE(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3286
3287 // Configuring the empty cipher list fails.
3288 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), ""));
3289 ERR_clear_error();
3290
3291 // But the cipher list is still updated to empty.
3292 EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3293}
3294
Adam Langley4c341d02017-03-08 19:33:21 -08003295// ssl_test_ticket_aead_failure_mode enumerates the possible ways in which the
3296// test |SSL_TICKET_AEAD_METHOD| can fail.
3297enum ssl_test_ticket_aead_failure_mode {
3298 ssl_test_ticket_aead_ok = 0,
3299 ssl_test_ticket_aead_seal_fail,
3300 ssl_test_ticket_aead_open_soft_fail,
3301 ssl_test_ticket_aead_open_hard_fail,
3302};
3303
3304struct ssl_test_ticket_aead_state {
3305 unsigned retry_count;
3306 ssl_test_ticket_aead_failure_mode failure_mode;
3307};
3308
3309static int ssl_test_ticket_aead_ex_index_dup(CRYPTO_EX_DATA *to,
3310 const CRYPTO_EX_DATA *from,
3311 void **from_d, int index,
3312 long argl, void *argp) {
3313 abort();
3314}
3315
3316static void ssl_test_ticket_aead_ex_index_free(void *parent, void *ptr,
3317 CRYPTO_EX_DATA *ad, int index,
3318 long argl, void *argp) {
3319 auto state = reinterpret_cast<ssl_test_ticket_aead_state*>(ptr);
3320 if (state == nullptr) {
3321 return;
3322 }
3323
3324 OPENSSL_free(state);
3325}
3326
3327static CRYPTO_once_t g_ssl_test_ticket_aead_ex_index_once = CRYPTO_ONCE_INIT;
3328static int g_ssl_test_ticket_aead_ex_index;
3329
3330static int ssl_test_ticket_aead_get_ex_index() {
3331 CRYPTO_once(&g_ssl_test_ticket_aead_ex_index_once, [] {
3332 g_ssl_test_ticket_aead_ex_index = SSL_get_ex_new_index(
3333 0, nullptr, nullptr, ssl_test_ticket_aead_ex_index_dup,
3334 ssl_test_ticket_aead_ex_index_free);
3335 });
3336 return g_ssl_test_ticket_aead_ex_index;
3337}
3338
3339static size_t ssl_test_ticket_aead_max_overhead(SSL *ssl) {
3340 return 1;
3341}
3342
3343static int ssl_test_ticket_aead_seal(SSL *ssl, uint8_t *out, size_t *out_len,
3344 size_t max_out_len, const uint8_t *in,
3345 size_t in_len) {
3346 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3347 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3348
3349 if (state->failure_mode == ssl_test_ticket_aead_seal_fail ||
3350 max_out_len < in_len + 1) {
3351 return 0;
3352 }
3353
3354 OPENSSL_memmove(out, in, in_len);
3355 out[in_len] = 0xff;
3356 *out_len = in_len + 1;
3357
3358 return 1;
3359}
3360
3361static ssl_ticket_aead_result_t ssl_test_ticket_aead_open(
3362 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len,
3363 const uint8_t *in, size_t in_len) {
3364 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3365 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3366
3367 if (state->retry_count > 0) {
3368 state->retry_count--;
3369 return ssl_ticket_aead_retry;
3370 }
3371
3372 switch (state->failure_mode) {
3373 case ssl_test_ticket_aead_ok:
3374 break;
3375 case ssl_test_ticket_aead_seal_fail:
3376 // If |seal| failed then there shouldn't be any ticket to try and
3377 // decrypt.
3378 abort();
3379 break;
3380 case ssl_test_ticket_aead_open_soft_fail:
3381 return ssl_ticket_aead_ignore_ticket;
3382 case ssl_test_ticket_aead_open_hard_fail:
3383 return ssl_ticket_aead_error;
3384 }
3385
3386 if (in_len == 0 || in[in_len - 1] != 0xff) {
3387 return ssl_ticket_aead_ignore_ticket;
3388 }
3389
3390 if (max_out_len < in_len - 1) {
3391 return ssl_ticket_aead_error;
3392 }
3393
3394 OPENSSL_memmove(out, in, in_len - 1);
3395 *out_len = in_len - 1;
3396 return ssl_ticket_aead_success;
3397}
3398
3399static const SSL_TICKET_AEAD_METHOD kSSLTestTicketMethod = {
3400 ssl_test_ticket_aead_max_overhead,
3401 ssl_test_ticket_aead_seal,
3402 ssl_test_ticket_aead_open,
3403};
3404
3405static void ConnectClientAndServerWithTicketMethod(
3406 bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
3407 SSL_CTX *client_ctx, SSL_CTX *server_ctx, unsigned retry_count,
3408 ssl_test_ticket_aead_failure_mode failure_mode, SSL_SESSION *session) {
3409 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
3410 ASSERT_TRUE(client);
3411 ASSERT_TRUE(server);
3412 SSL_set_connect_state(client.get());
3413 SSL_set_accept_state(server.get());
3414
3415 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3416 OPENSSL_malloc(sizeof(ssl_test_ticket_aead_state)));
3417 ASSERT_TRUE(state);
3418 OPENSSL_memset(state, 0, sizeof(ssl_test_ticket_aead_state));
3419 state->retry_count = retry_count;
3420 state->failure_mode = failure_mode;
3421
3422 ASSERT_TRUE(SSL_set_ex_data(server.get(), ssl_test_ticket_aead_get_ex_index(),
3423 state));
3424
3425 SSL_set_session(client.get(), session);
3426
3427 BIO *bio1, *bio2;
3428 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
3429
3430 // SSL_set_bio takes ownership.
3431 SSL_set_bio(client.get(), bio1, bio1);
3432 SSL_set_bio(server.get(), bio2, bio2);
3433
3434 if (CompleteHandshakes(client.get(), server.get())) {
3435 *out_client = std::move(client);
3436 *out_server = std::move(server);
3437 } else {
3438 out_client->reset();
3439 out_server->reset();
3440 }
3441}
3442
David Benjaminc9775322018-04-13 16:39:12 -04003443using TicketAEADMethodParam =
3444 testing::tuple<uint16_t, unsigned, ssl_test_ticket_aead_failure_mode>;
3445
Adam Langley4c341d02017-03-08 19:33:21 -08003446class TicketAEADMethodTest
David Benjaminc9775322018-04-13 16:39:12 -04003447 : public ::testing::TestWithParam<TicketAEADMethodParam> {};
Adam Langley4c341d02017-03-08 19:33:21 -08003448
3449TEST_P(TicketAEADMethodTest, Resume) {
3450 bssl::UniquePtr<X509> cert = GetTestCertificate();
3451 ASSERT_TRUE(cert);
3452 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3453 ASSERT_TRUE(key);
3454
3455 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
3456 ASSERT_TRUE(server_ctx);
3457 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
3458 ASSERT_TRUE(client_ctx);
3459
3460 const uint16_t version = testing::get<0>(GetParam());
3461 const unsigned retry_count = testing::get<1>(GetParam());
3462 const ssl_test_ticket_aead_failure_mode failure_mode =
3463 testing::get<2>(GetParam());
3464
3465 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3466 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3467 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), version));
3468 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), version));
3469 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), version));
3470 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), version));
3471
3472 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
3473 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
3474 SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
3475 SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
David Benjamin707af292017-03-10 17:47:18 -05003476 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langley4c341d02017-03-08 19:33:21 -08003477
3478 SSL_CTX_set_ticket_aead_method(server_ctx.get(), &kSSLTestTicketMethod);
3479
3480 bssl::UniquePtr<SSL> client, server;
3481 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3482 server_ctx.get(), retry_count,
3483 failure_mode, nullptr);
3484 switch (failure_mode) {
3485 case ssl_test_ticket_aead_ok:
3486 case ssl_test_ticket_aead_open_hard_fail:
3487 case ssl_test_ticket_aead_open_soft_fail:
3488 ASSERT_TRUE(client);
3489 break;
3490 case ssl_test_ticket_aead_seal_fail:
3491 EXPECT_FALSE(client);
3492 return;
3493 }
3494 EXPECT_FALSE(SSL_session_reused(client.get()));
3495 EXPECT_FALSE(SSL_session_reused(server.get()));
3496
David Benjamin707af292017-03-10 17:47:18 -05003497 // Run the read loop to account for post-handshake tickets in TLS 1.3.
3498 SSL_read(client.get(), nullptr, 0);
3499
3500 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
Adam Langley4c341d02017-03-08 19:33:21 -08003501 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3502 server_ctx.get(), retry_count,
David Benjamin707af292017-03-10 17:47:18 -05003503 failure_mode, session.get());
Adam Langley4c341d02017-03-08 19:33:21 -08003504 switch (failure_mode) {
3505 case ssl_test_ticket_aead_ok:
3506 ASSERT_TRUE(client);
3507 EXPECT_TRUE(SSL_session_reused(client.get()));
3508 EXPECT_TRUE(SSL_session_reused(server.get()));
3509 break;
3510 case ssl_test_ticket_aead_seal_fail:
3511 abort();
3512 break;
3513 case ssl_test_ticket_aead_open_hard_fail:
3514 EXPECT_FALSE(client);
3515 break;
3516 case ssl_test_ticket_aead_open_soft_fail:
3517 ASSERT_TRUE(client);
3518 EXPECT_FALSE(SSL_session_reused(client.get()));
3519 EXPECT_FALSE(SSL_session_reused(server.get()));
3520 }
3521}
3522
David Benjaminc9775322018-04-13 16:39:12 -04003523std::string TicketAEADMethodParamToString(
3524 const testing::TestParamInfo<TicketAEADMethodParam> &params) {
3525 std::string ret = GetVersionName(std::get<0>(params.param));
3526 // GTest only allows alphanumeric characters and '_' in the parameter
3527 // string. Additionally filter out the 'v' to get "TLS13" over "TLSv13".
3528 for (auto it = ret.begin(); it != ret.end();) {
3529 if (*it == '.' || *it == 'v') {
3530 it = ret.erase(it);
3531 } else {
3532 ++it;
3533 }
3534 }
3535 char retry_count[256];
3536 snprintf(retry_count, sizeof(retry_count), "%d", std::get<1>(params.param));
3537 ret += "_";
3538 ret += retry_count;
3539 ret += "Retries_";
3540 switch (std::get<2>(params.param)) {
3541 case ssl_test_ticket_aead_ok:
3542 ret += "OK";
3543 break;
3544 case ssl_test_ticket_aead_seal_fail:
3545 ret += "SealFail";
3546 break;
3547 case ssl_test_ticket_aead_open_soft_fail:
3548 ret += "OpenSoftFail";
3549 break;
3550 case ssl_test_ticket_aead_open_hard_fail:
3551 ret += "OpenHardFail";
3552 break;
3553 }
3554 return ret;
3555}
3556
Adam Langley4c341d02017-03-08 19:33:21 -08003557INSTANTIATE_TEST_CASE_P(
3558 TicketAEADMethodTests, TicketAEADMethodTest,
David Benjaminc9775322018-04-13 16:39:12 -04003559 testing::Combine(testing::Values(TLS1_2_VERSION, TLS1_3_VERSION),
3560 testing::Values(0, 1, 2),
3561 testing::Values(ssl_test_ticket_aead_ok,
3562 ssl_test_ticket_aead_seal_fail,
3563 ssl_test_ticket_aead_open_soft_fail,
3564 ssl_test_ticket_aead_open_hard_fail)),
3565 TicketAEADMethodParamToString);
Adam Langley4c341d02017-03-08 19:33:21 -08003566
David Benjaminca743582017-06-15 17:51:35 -04003567TEST(SSLTest, SelectNextProto) {
3568 uint8_t *result;
3569 uint8_t result_len;
3570
3571 // If there is an overlap, it should be returned.
3572 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3573 SSL_select_next_proto(&result, &result_len,
3574 (const uint8_t *)"\1a\2bb\3ccc", 9,
3575 (const uint8_t *)"\1x\1y\1a\1z", 8));
3576 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
3577
3578 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3579 SSL_select_next_proto(&result, &result_len,
3580 (const uint8_t *)"\1a\2bb\3ccc", 9,
3581 (const uint8_t *)"\1x\1y\2bb\1z", 9));
3582 EXPECT_EQ(Bytes("bb"), Bytes(result, result_len));
3583
3584 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3585 SSL_select_next_proto(&result, &result_len,
3586 (const uint8_t *)"\1a\2bb\3ccc", 9,
3587 (const uint8_t *)"\1x\1y\3ccc\1z", 10));
3588 EXPECT_EQ(Bytes("ccc"), Bytes(result, result_len));
3589
3590 // Peer preference order takes precedence over local.
3591 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3592 SSL_select_next_proto(&result, &result_len,
3593 (const uint8_t *)"\1a\2bb\3ccc", 9,
3594 (const uint8_t *)"\3ccc\2bb\1a", 9));
3595 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
3596
3597 // If there is no overlap, return the first local protocol.
3598 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
3599 SSL_select_next_proto(&result, &result_len,
3600 (const uint8_t *)"\1a\2bb\3ccc", 9,
3601 (const uint8_t *)"\1x\2yy\3zzz", 9));
3602 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
3603
3604 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
3605 SSL_select_next_proto(&result, &result_len, nullptr, 0,
3606 (const uint8_t *)"\1x\2yy\3zzz", 9));
3607 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
3608}
3609
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003610TEST(SSLTest, SealRecord) {
3611 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3612 server_ctx(SSL_CTX_new(TLS_method()));
3613 ASSERT_TRUE(client_ctx);
3614 ASSERT_TRUE(server_ctx);
3615
3616 bssl::UniquePtr<X509> cert = GetTestCertificate();
3617 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3618 ASSERT_TRUE(cert);
3619 ASSERT_TRUE(key);
3620 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3621 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3622
3623 bssl::UniquePtr<SSL> client, server;
3624 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003625 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003626
3627 const std::vector<uint8_t> record = {1, 2, 3, 4, 5};
3628 std::vector<uint8_t> prefix(
3629 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003630 body(record.size()),
3631 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003632 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3633 bssl::MakeSpan(body), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003634 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003635
3636 std::vector<uint8_t> sealed;
3637 sealed.insert(sealed.end(), prefix.begin(), prefix.end());
3638 sealed.insert(sealed.end(), body.begin(), body.end());
3639 sealed.insert(sealed.end(), suffix.begin(), suffix.end());
3640 std::vector<uint8_t> sealed_copy = sealed;
3641
3642 bssl::Span<uint8_t> plaintext;
3643 size_t record_len;
3644 uint8_t alert = 255;
3645 EXPECT_EQ(bssl::OpenRecord(server.get(), &plaintext, &record_len, &alert,
3646 bssl::MakeSpan(sealed)),
3647 bssl::OpenRecordResult::kOK);
3648 EXPECT_EQ(record_len, sealed.size());
3649 EXPECT_EQ(plaintext, record);
3650 EXPECT_EQ(255, alert);
3651}
3652
3653TEST(SSLTest, SealRecordInPlace) {
3654 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3655 server_ctx(SSL_CTX_new(TLS_method()));
3656 ASSERT_TRUE(client_ctx);
3657 ASSERT_TRUE(server_ctx);
3658
3659 bssl::UniquePtr<X509> cert = GetTestCertificate();
3660 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3661 ASSERT_TRUE(cert);
3662 ASSERT_TRUE(key);
3663 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3664 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3665
3666 bssl::UniquePtr<SSL> client, server;
3667 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003668 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003669
3670 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
3671 std::vector<uint8_t> record = plaintext;
3672 std::vector<uint8_t> prefix(
3673 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003674 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003675 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3676 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003677 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003678 record.insert(record.begin(), prefix.begin(), prefix.end());
3679 record.insert(record.end(), suffix.begin(), suffix.end());
3680
3681 bssl::Span<uint8_t> result;
3682 size_t record_len;
3683 uint8_t alert;
3684 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
3685 bssl::MakeSpan(record)),
3686 bssl::OpenRecordResult::kOK);
3687 EXPECT_EQ(record_len, record.size());
3688 EXPECT_EQ(plaintext, result);
3689}
3690
3691TEST(SSLTest, SealRecordTrailingData) {
3692 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3693 server_ctx(SSL_CTX_new(TLS_method()));
3694 ASSERT_TRUE(client_ctx);
3695 ASSERT_TRUE(server_ctx);
3696
3697 bssl::UniquePtr<X509> cert = GetTestCertificate();
3698 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3699 ASSERT_TRUE(cert);
3700 ASSERT_TRUE(key);
3701 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3702 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3703
3704 bssl::UniquePtr<SSL> client, server;
3705 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003706 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003707
3708 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
3709 std::vector<uint8_t> record = plaintext;
3710 std::vector<uint8_t> prefix(
3711 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003712 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003713 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3714 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003715 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003716 record.insert(record.begin(), prefix.begin(), prefix.end());
3717 record.insert(record.end(), suffix.begin(), suffix.end());
3718 record.insert(record.end(), {5, 4, 3, 2, 1});
3719
3720 bssl::Span<uint8_t> result;
3721 size_t record_len;
3722 uint8_t alert;
3723 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
3724 bssl::MakeSpan(record)),
3725 bssl::OpenRecordResult::kOK);
3726 EXPECT_EQ(record_len, record.size() - 5);
3727 EXPECT_EQ(plaintext, result);
3728}
3729
3730TEST(SSLTest, SealRecordInvalidSpanSize) {
3731 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3732 server_ctx(SSL_CTX_new(TLS_method()));
3733 ASSERT_TRUE(client_ctx);
3734 ASSERT_TRUE(server_ctx);
3735
3736 bssl::UniquePtr<X509> cert = GetTestCertificate();
3737 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3738 ASSERT_TRUE(cert);
3739 ASSERT_TRUE(key);
3740 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3741 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3742
3743 bssl::UniquePtr<SSL> client, server;
3744 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003745 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003746
3747 std::vector<uint8_t> record = {1, 2, 3, 4, 5};
3748 std::vector<uint8_t> prefix(
3749 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003750 body(record.size()),
3751 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003752
3753 auto expect_err = []() {
3754 int err = ERR_get_error();
3755 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
3756 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_BUFFER_TOO_SMALL);
3757 ERR_clear_error();
3758 };
3759 EXPECT_FALSE(bssl::SealRecord(
3760 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003761 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003762 expect_err();
3763 EXPECT_FALSE(bssl::SealRecord(
3764 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003765 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003766 expect_err();
3767
3768 EXPECT_FALSE(
3769 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3770 bssl::MakeSpan(record.data(), record.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003771 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003772 expect_err();
3773 EXPECT_FALSE(
3774 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3775 bssl::MakeSpan(record.data(), record.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003776 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003777 expect_err();
3778
3779 EXPECT_FALSE(bssl::SealRecord(
3780 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003781 bssl::MakeSpan(suffix.data(), suffix.size() - 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003782 expect_err();
3783 EXPECT_FALSE(bssl::SealRecord(
3784 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003785 bssl::MakeSpan(suffix.data(), suffix.size() + 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003786 expect_err();
3787}
3788
David Benjamin617b8182017-08-29 15:33:10 -04003789// The client should gracefully handle no suitable ciphers being enabled.
3790TEST(SSLTest, NoCiphersAvailable) {
3791 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3792 ASSERT_TRUE(ctx);
3793
3794 // Configure |client_ctx| with a cipher list that does not intersect with its
3795 // version configuration.
3796 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
3797 ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
3798 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
3799
3800 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3801 ASSERT_TRUE(ssl);
3802 SSL_set_connect_state(ssl.get());
3803
3804 UniquePtr<BIO> rbio(BIO_new(BIO_s_mem())), wbio(BIO_new(BIO_s_mem()));
3805 ASSERT_TRUE(rbio);
3806 ASSERT_TRUE(wbio);
3807 SSL_set0_rbio(ssl.get(), rbio.release());
3808 SSL_set0_wbio(ssl.get(), wbio.release());
3809
3810 int ret = SSL_do_handshake(ssl.get());
3811 EXPECT_EQ(-1, ret);
3812 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), ret));
3813 uint32_t err = ERR_get_error();
3814 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
3815 EXPECT_EQ(SSL_R_NO_CIPHERS_AVAILABLE, ERR_GET_REASON(err));
3816}
3817
David Benjamina4bafd32017-10-03 15:06:29 -04003818TEST_P(SSLVersionTest, SessionVersion) {
3819 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3820 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3821
3822 bssl::UniquePtr<SSL_SESSION> session =
3823 CreateClientSession(client_ctx_.get(), server_ctx_.get());
3824 ASSERT_TRUE(session);
3825 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
3826
3827 // Sessions in TLS 1.3 and later should be single-use.
3828 EXPECT_EQ(version() == TLS1_3_VERSION,
3829 !!SSL_SESSION_should_be_single_use(session.get()));
3830
3831 // Making fake sessions for testing works.
3832 session.reset(SSL_SESSION_new(client_ctx_.get()));
3833 ASSERT_TRUE(session);
3834 ASSERT_TRUE(SSL_SESSION_set_protocol_version(session.get(), version()));
3835 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
3836}
3837
David Benjaminfdb7a352017-10-12 17:34:18 -04003838TEST_P(SSLVersionTest, SSLPending) {
3839 UniquePtr<SSL> ssl(SSL_new(client_ctx_.get()));
3840 ASSERT_TRUE(ssl);
3841 EXPECT_EQ(0, SSL_pending(ssl.get()));
3842
3843 ASSERT_TRUE(Connect());
3844 EXPECT_EQ(0, SSL_pending(client_.get()));
3845
3846 ASSERT_EQ(5, SSL_write(server_.get(), "hello", 5));
3847 ASSERT_EQ(5, SSL_write(server_.get(), "world", 5));
3848 EXPECT_EQ(0, SSL_pending(client_.get()));
3849
3850 char buf[10];
3851 ASSERT_EQ(1, SSL_peek(client_.get(), buf, 1));
3852 EXPECT_EQ(5, SSL_pending(client_.get()));
3853
3854 ASSERT_EQ(1, SSL_read(client_.get(), buf, 1));
3855 EXPECT_EQ(4, SSL_pending(client_.get()));
3856
3857 ASSERT_EQ(4, SSL_read(client_.get(), buf, 10));
3858 EXPECT_EQ(0, SSL_pending(client_.get()));
3859
3860 ASSERT_EQ(2, SSL_read(client_.get(), buf, 2));
3861 EXPECT_EQ(3, SSL_pending(client_.get()));
3862}
3863
David Benjamina031b612017-10-11 20:48:25 -04003864// Test that post-handshake tickets consumed by |SSL_shutdown| are ignored.
3865TEST(SSLTest, ShutdownIgnoresTickets) {
3866 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3867 ASSERT_TRUE(ctx);
3868 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_3_VERSION));
3869 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
3870
3871 bssl::UniquePtr<X509> cert = GetTestCertificate();
3872 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3873 ASSERT_TRUE(cert);
3874 ASSERT_TRUE(key);
3875 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
3876 ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
3877
3878 SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_BOTH);
3879
3880 bssl::UniquePtr<SSL> client, server;
3881 ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
3882
3883 SSL_CTX_sess_set_new_cb(ctx.get(), [](SSL *ssl, SSL_SESSION *session) -> int {
3884 ADD_FAILURE() << "New session callback called during SSL_shutdown";
3885 return 0;
3886 });
3887
3888 // Send close_notify.
3889 EXPECT_EQ(0, SSL_shutdown(server.get()));
3890 EXPECT_EQ(0, SSL_shutdown(client.get()));
3891
3892 // Receive close_notify.
3893 EXPECT_EQ(1, SSL_shutdown(server.get()));
3894 EXPECT_EQ(1, SSL_shutdown(client.get()));
3895}
3896
David Benjamin6cc352e2017-11-02 17:21:39 -04003897TEST(SSLTest, SignatureAlgorithmProperties) {
3898 EXPECT_EQ(EVP_PKEY_NONE, SSL_get_signature_algorithm_key_type(0x1234));
3899 EXPECT_EQ(nullptr, SSL_get_signature_algorithm_digest(0x1234));
3900 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(0x1234));
3901
3902 EXPECT_EQ(EVP_PKEY_RSA,
3903 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
3904 EXPECT_EQ(EVP_md5_sha1(),
3905 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
3906 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
3907
3908 EXPECT_EQ(EVP_PKEY_EC, SSL_get_signature_algorithm_key_type(
3909 SSL_SIGN_ECDSA_SECP256R1_SHA256));
3910 EXPECT_EQ(EVP_sha256(), SSL_get_signature_algorithm_digest(
3911 SSL_SIGN_ECDSA_SECP256R1_SHA256));
3912 EXPECT_FALSE(
3913 SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_ECDSA_SECP256R1_SHA256));
3914
3915 EXPECT_EQ(EVP_PKEY_RSA,
David Benjamin6879e192018-04-13 16:01:02 -04003916 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04003917 EXPECT_EQ(EVP_sha384(),
David Benjamin6879e192018-04-13 16:01:02 -04003918 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PSS_RSAE_SHA384));
3919 EXPECT_TRUE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04003920}
3921
Adam Langley0080d832018-06-07 16:39:49 -07003922static bool XORCompressFunc(SSL *ssl, CBB *out, Span<const uint8_t> in) {
3923 for (size_t i = 0; i < in.size(); i++) {
3924 if (!CBB_add_u8(out, in[i] ^ 0x55)) {
3925 return false;
3926 }
3927 }
3928
3929 SSL_set_app_data(ssl, XORCompressFunc);
3930
3931 return true;
3932}
3933
3934static bool XORDecompressFunc(SSL *ssl, bssl::UniquePtr<CRYPTO_BUFFER> *out,
3935 size_t uncompressed_len, Span<const uint8_t> in) {
3936 if (in.size() != uncompressed_len) {
3937 return false;
3938 }
3939
3940 uint8_t *data;
3941 out->reset(CRYPTO_BUFFER_alloc(&data, uncompressed_len));
3942 if (out->get() == nullptr) {
3943 return false;
3944 }
3945
3946 for (size_t i = 0; i < in.size(); i++) {
3947 data[i] = in[i] ^ 0x55;
3948 }
3949
3950 SSL_set_app_data(ssl, XORDecompressFunc);
3951
3952 return true;
3953}
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
David Benjamin96628432017-01-19 19:05:47 -05004121// TODO(davidben): Convert this file to GTest properly.
4122TEST(SSLTest, AllTests) {
David Benjamine11726a2017-04-23 12:14:28 -04004123 if (!TestSSL_SESSIONEncoding(kOpenSSLSession) ||
Adam Langley10f97f32016-07-12 08:09:33 -07004124 !TestSSL_SESSIONEncoding(kCustomSession) ||
4125 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
4126 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
4127 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
4128 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
Steven Valdeza833c352016-11-01 13:39:36 -04004129 // Test the padding extension at TLS 1.2.
4130 !TestPaddingExtension(TLS1_2_VERSION, TLS1_2_VERSION) ||
4131 // Test the padding extension at TLS 1.3 with a TLS 1.2 session, so there
4132 // will be no PSK binder after the padding extension.
4133 !TestPaddingExtension(TLS1_3_VERSION, TLS1_2_VERSION) ||
4134 // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
4135 // will be a PSK binder after the padding extension.
Steven Valdez74666da2018-01-09 06:18:36 -05004136 !TestPaddingExtension(TLS1_3_VERSION, TLS1_3_DRAFT23_VERSION)) {
David Benjamin96628432017-01-19 19:05:47 -05004137 ADD_FAILURE() << "Tests failed";
David Benjaminbb0a17c2014-09-20 15:35:39 -04004138 }
David Benjamin2e521212014-07-16 14:37:51 -04004139}
Martin Kreichgauer72912d22017-08-04 12:06:43 -07004140
4141} // namespace
4142} // namespace bssl