blob: cfcaa73d24310c997e1f3e17778dc28bab6445d0 [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 }
David Benjaminaaef8332018-06-29 16:45:49 -0400989 // Use a garbage ticket.
990 std::vector<uint8_t> ticket(ticket_len, 'a');
Steven Valdeza833c352016-11-01 13:39:36 -0400991 bssl::UniquePtr<SSL_SESSION> session(
Adam Langley46db7af2017-02-01 15:49:37 -0800992 SSL_SESSION_from_bytes(der.data(), der.size(), ssl_ctx.get()));
David Benjaminaaef8332018-06-29 16:45:49 -0400993 if (!session ||
994 !SSL_SESSION_set_protocol_version(session.get(), version) ||
995 !SSL_SESSION_set_ticket(session.get(), ticket.data(), ticket.size())) {
David Benjamin422fe082015-07-21 22:03:43 -0400996 return nullptr;
997 }
David Benjamin1269ddd2015-10-18 15:18:55 -0400998 // Fix up the timeout.
David Benjamin9b63f292016-11-15 00:44:05 -0500999#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
David Benjaminaaef8332018-06-29 16:45:49 -04001000 SSL_SESSION_set_time(session.get(), 1234);
David Benjamin9b63f292016-11-15 00:44:05 -05001001#else
David Benjaminaaef8332018-06-29 16:45:49 -04001002 SSL_SESSION_set_time(session.get(), time(nullptr));
David Benjamin9b63f292016-11-15 00:44:05 -05001003#endif
David Benjamin422fe082015-07-21 22:03:43 -04001004 return session;
1005}
1006
David Benjaminafc64de2016-07-19 17:12:41 +02001007static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001008 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +02001009 if (!bio) {
1010 return false;
1011 }
1012 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -04001013 BIO_up_ref(bio.get());
1014 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +02001015 int ret = SSL_connect(ssl);
1016 if (ret > 0) {
1017 // SSL_connect should fail without a BIO to write to.
1018 return false;
1019 }
1020 ERR_clear_error();
1021
1022 const uint8_t *client_hello;
1023 size_t client_hello_len;
1024 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
1025 return false;
1026 }
1027 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
1028 return true;
1029}
1030
Steven Valdeza833c352016-11-01 13:39:36 -04001031// GetClientHelloLen creates a client SSL connection with the specified version
1032// and ticket length. It returns the length of the ClientHello, not including
1033// the record header, on success and zero on error.
1034static size_t GetClientHelloLen(uint16_t max_version, uint16_t session_version,
1035 size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001036 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Steven Valdeza833c352016-11-01 13:39:36 -04001037 bssl::UniquePtr<SSL_SESSION> session =
1038 CreateSessionWithTicket(session_version, ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -04001039 if (!ctx || !session) {
1040 return 0;
1041 }
Steven Valdeza833c352016-11-01 13:39:36 -04001042
1043 // Set a one-element cipher list so the baseline ClientHello is unpadded.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001044 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
Steven Valdez2c62fe92016-10-14 12:08:12 -04001045 if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -08001046 !SSL_set_strict_cipher_list(ssl.get(), "ECDHE-RSA-AES128-GCM-SHA256") ||
Steven Valdeza833c352016-11-01 13:39:36 -04001047 !SSL_set_max_proto_version(ssl.get(), max_version)) {
David Benjamin422fe082015-07-21 22:03:43 -04001048 return 0;
1049 }
Steven Valdeza833c352016-11-01 13:39:36 -04001050
David Benjaminafc64de2016-07-19 17:12:41 +02001051 std::vector<uint8_t> client_hello;
1052 if (!GetClientHello(ssl.get(), &client_hello) ||
1053 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -04001054 return 0;
1055 }
Steven Valdeza833c352016-11-01 13:39:36 -04001056
David Benjaminafc64de2016-07-19 17:12:41 +02001057 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -04001058}
1059
1060struct PaddingTest {
1061 size_t input_len, padded_len;
1062};
1063
1064static const PaddingTest kPaddingTests[] = {
1065 // ClientHellos of length below 0x100 do not require padding.
1066 {0xfe, 0xfe},
1067 {0xff, 0xff},
1068 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
1069 {0x100, 0x200},
1070 {0x123, 0x200},
1071 {0x1fb, 0x200},
1072 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
1073 // padding extension takes a minimum of four bytes plus one required content
1074 // byte. (To work around yet more server bugs, we avoid empty final
1075 // extensions.)
1076 {0x1fc, 0x201},
1077 {0x1fd, 0x202},
1078 {0x1fe, 0x203},
1079 {0x1ff, 0x204},
1080 // Finally, larger ClientHellos need no padding.
1081 {0x200, 0x200},
1082 {0x201, 0x201},
1083};
1084
Steven Valdeza833c352016-11-01 13:39:36 -04001085static bool TestPaddingExtension(uint16_t max_version,
1086 uint16_t session_version) {
David Benjamin422fe082015-07-21 22:03:43 -04001087 // Sample a baseline length.
Steven Valdeza833c352016-11-01 13:39:36 -04001088 size_t base_len = GetClientHelloLen(max_version, session_version, 1);
David Benjamin422fe082015-07-21 22:03:43 -04001089 if (base_len == 0) {
1090 return false;
1091 }
1092
1093 for (const PaddingTest &test : kPaddingTests) {
1094 if (base_len > test.input_len) {
Steven Valdeza833c352016-11-01 13:39:36 -04001095 fprintf(stderr,
1096 "Baseline ClientHello too long (max_version = %04x, "
1097 "session_version = %04x).\n",
1098 max_version, session_version);
David Benjamin422fe082015-07-21 22:03:43 -04001099 return false;
1100 }
1101
Steven Valdeza833c352016-11-01 13:39:36 -04001102 size_t padded_len = GetClientHelloLen(max_version, session_version,
1103 1 + test.input_len - base_len);
David Benjamin422fe082015-07-21 22:03:43 -04001104 if (padded_len != test.padded_len) {
Steven Valdeza833c352016-11-01 13:39:36 -04001105 fprintf(stderr,
1106 "%u-byte ClientHello padded to %u bytes, not %u (max_version = "
1107 "%04x, session_version = %04x).\n",
David Benjamin422fe082015-07-21 22:03:43 -04001108 static_cast<unsigned>(test.input_len),
1109 static_cast<unsigned>(padded_len),
Steven Valdeza833c352016-11-01 13:39:36 -04001110 static_cast<unsigned>(test.padded_len), max_version,
1111 session_version);
David Benjamin422fe082015-07-21 22:03:43 -04001112 return false;
1113 }
1114 }
Steven Valdeza833c352016-11-01 13:39:36 -04001115
David Benjamin422fe082015-07-21 22:03:43 -04001116 return true;
1117}
1118
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001119static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001120 static const char kCertPEM[] =
1121 "-----BEGIN CERTIFICATE-----\n"
1122 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1123 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1124 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1125 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1126 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1127 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1128 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1129 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1130 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1131 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1132 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1133 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1134 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1135 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001136 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
David Benjamin1444c3a2016-12-20 17:23:11 -05001137 return bssl::UniquePtr<X509>(
1138 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjaminde942382016-02-11 12:02:01 -05001139}
1140
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001141static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001142 static const char kKeyPEM[] =
1143 "-----BEGIN RSA PRIVATE KEY-----\n"
1144 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1145 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1146 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1147 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1148 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1149 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1150 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1151 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1152 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1153 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1154 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1155 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1156 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1157 "-----END RSA PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001158 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1159 return bssl::UniquePtr<EVP_PKEY>(
David Benjaminde942382016-02-11 12:02:01 -05001160 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1161}
1162
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001163static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001164 static const char kCertPEM[] =
1165 "-----BEGIN CERTIFICATE-----\n"
1166 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1167 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1168 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1169 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1170 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1171 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1172 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1173 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1174 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1175 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1176 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001177 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1178 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjamin0fc37ef2016-08-17 15:29:46 -04001179}
1180
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001181static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001182 static const char kKeyPEM[] =
1183 "-----BEGIN PRIVATE KEY-----\n"
1184 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1185 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1186 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1187 "-----END PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001188 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1189 return bssl::UniquePtr<EVP_PKEY>(
David Benjamin0fc37ef2016-08-17 15:29:46 -04001190 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1191}
1192
Adam Langleyd04ca952017-02-28 11:26:51 -08001193static bssl::UniquePtr<CRYPTO_BUFFER> BufferFromPEM(const char *pem) {
1194 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1195 char *name, *header;
1196 uint8_t *data;
1197 long data_len;
1198 if (!PEM_read_bio(bio.get(), &name, &header, &data,
1199 &data_len)) {
1200 return nullptr;
1201 }
1202 OPENSSL_free(name);
1203 OPENSSL_free(header);
1204
1205 auto ret = bssl::UniquePtr<CRYPTO_BUFFER>(
1206 CRYPTO_BUFFER_new(data, data_len, nullptr));
1207 OPENSSL_free(data);
1208 return ret;
1209}
1210
1211static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestCertificateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001212 static const char kCertPEM[] =
1213 "-----BEGIN CERTIFICATE-----\n"
1214 "MIIC0jCCAbqgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQiBD\n"
1215 "QTAeFw0xNjAyMjgyMDI3MDNaFw0yNjAyMjUyMDI3MDNaMBgxFjAUBgNVBAMMDUNs\n"
1216 "aWVudCBDZXJ0IEEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRvaz8\n"
1217 "CC/cshpCafJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/\n"
1218 "kLRcH89M/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3\n"
1219 "tHb+xs2PSs8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+c\n"
1220 "IDs2rQ+lP7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1\n"
1221 "z7C8jU50Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9V\n"
1222 "iLeXANgZi+Xx9KgfAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI\n"
1223 "KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBFEVbmYl+2RtNw\n"
1224 "rDftRDF1v2QUbcN2ouSnQDHxeDQdSgasLzT3ui8iYu0Rw2WWcZ0DV5e0ztGPhWq7\n"
1225 "AO0B120aFRMOY+4+bzu9Q2FFkQqc7/fKTvTDzIJI5wrMnFvUfzzvxh3OHWMYSs/w\n"
1226 "giq33hTKeHEq6Jyk3btCny0Ycecyc3yGXH10sizUfiHlhviCkDuESk8mFDwDDzqW\n"
1227 "ZF0IipzFbEDHoIxLlm3GQxpiLoEV4k8KYJp3R5KBLFyxM6UGPz8h72mIPCJp2RuK\n"
1228 "MYgF91UDvVzvnYm6TfseM2+ewKirC00GOrZ7rEcFvtxnKSqYf4ckqfNdSU1Y+RRC\n"
1229 "1ngWZ7Ih\n"
1230 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001231 return BufferFromPEM(kCertPEM);
David Benjamin1444c3a2016-12-20 17:23:11 -05001232}
1233
Adam Langleyd04ca952017-02-28 11:26:51 -08001234static bssl::UniquePtr<X509> X509FromBuffer(
1235 bssl::UniquePtr<CRYPTO_BUFFER> buffer) {
1236 if (!buffer) {
1237 return nullptr;
1238 }
1239 const uint8_t *derp = CRYPTO_BUFFER_data(buffer.get());
1240 return bssl::UniquePtr<X509>(
1241 d2i_X509(NULL, &derp, CRYPTO_BUFFER_len(buffer.get())));
1242}
1243
1244static bssl::UniquePtr<X509> GetChainTestCertificate() {
1245 return X509FromBuffer(GetChainTestCertificateBuffer());
1246}
1247
1248static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestIntermediateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001249 static const char kCertPEM[] =
1250 "-----BEGIN CERTIFICATE-----\n"
1251 "MIICwjCCAaqgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS\n"
1252 "b290IENBMB4XDTE2MDIyODIwMjcwM1oXDTI2MDIyNTIwMjcwM1owDzENMAsGA1UE\n"
1253 "AwwEQiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALsSCYmDip2D\n"
1254 "GkjFxw7ykz26JSjELkl6ArlYjFJ3aT/SCh8qbS4gln7RH8CPBd78oFdfhIKQrwtZ\n"
1255 "3/q21ykD9BAS3qHe2YdcJfm8/kWAy5DvXk6NXU4qX334KofBAEpgdA/igEFq1P1l\n"
1256 "HAuIfZCpMRfT+i5WohVsGi8f/NgpRvVaMONLNfgw57mz1lbtFeBEISmX0kbsuJxF\n"
1257 "Qj/Bwhi5/0HAEXG8e7zN4cEx0yPRvmOATRdVb/8dW2pwOHRJq9R5M0NUkIsTSnL7\n"
1258 "6N/z8hRAHMsV3IudC5Yd7GXW1AGu9a+iKU+Q4xcZCoj0DC99tL4VKujrV1kAeqsM\n"
1259 "cz5/dKzi6+cCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
1260 "AQYwDQYJKoZIhvcNAQELBQADggEBAIIeZiEeNhWWQ8Y4D+AGDwqUUeG8NjCbKrXQ\n"
1261 "BlHg5wZ8xftFaiP1Dp/UAezmx2LNazdmuwrYB8lm3FVTyaPDTKEGIPS4wJKHgqH1\n"
1262 "QPDhqNm85ey7TEtI9oYjsNim/Rb+iGkIAMXaxt58SzxbjvP0kMr1JfJIZbic9vye\n"
1263 "NwIspMFIpP3FB8ywyu0T0hWtCQgL4J47nigCHpOu58deP88fS/Nyz/fyGVWOZ76b\n"
1264 "WhWwgM3P3X95fQ3d7oFPR/bVh0YV+Cf861INwplokXgXQ3/TCQ+HNXeAMWn3JLWv\n"
1265 "XFwk8owk9dq/kQGdndGgy3KTEW4ctPX5GNhf3LJ9Q7dLji4ReQ4=\n"
1266 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001267 return BufferFromPEM(kCertPEM);
1268}
1269
1270static bssl::UniquePtr<X509> GetChainTestIntermediate() {
1271 return X509FromBuffer(GetChainTestIntermediateBuffer());
David Benjamin1444c3a2016-12-20 17:23:11 -05001272}
1273
1274static bssl::UniquePtr<EVP_PKEY> GetChainTestKey() {
1275 static const char kKeyPEM[] =
1276 "-----BEGIN PRIVATE KEY-----\n"
1277 "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRvaz8CC/cshpC\n"
1278 "afJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/kLRcH89M\n"
1279 "/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3tHb+xs2P\n"
1280 "Ss8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+cIDs2rQ+l\n"
1281 "P7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1z7C8jU50\n"
1282 "Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9ViLeXANgZ\n"
1283 "i+Xx9KgfAgMBAAECggEBAK0VjSJzkyPaamcyTVSWjo7GdaBGcK60lk657RjR+lK0\n"
1284 "YJ7pkej4oM2hdsVZFsP8Cs4E33nXLa/0pDsRov/qrp0WQm2skwqGMC1I/bZ0WRPk\n"
1285 "wHaDrBBfESWnJDX/AGpVtlyOjPmgmK6J2usMPihQUDkKdAYrVWJePrMIxt1q6BMe\n"
1286 "iczs3qriMmtY3bUc4UyUwJ5fhDLjshHvfuIpYQyI6EXZM6dZksn9LylXJnigY6QJ\n"
1287 "HxOYO0BDwOsZ8yQ8J8afLk88i0GizEkgE1z3REtQUwgWfxr1WV/ud+T6/ZhSAgH9\n"
1288 "042mQvSFZnIUSEsmCvjhWuAunfxHKCTcAoYISWfzWpkCgYEA7gpf3HHU5Tn+CgUn\n"
1289 "1X5uGpG3DmcMgfeGgs2r2f/IIg/5Ac1dfYILiybL1tN9zbyLCJfcbFpWBc9hJL6f\n"
1290 "CPc5hUiwWFJqBJewxQkC1Ae/HakHbip+IZ+Jr0842O4BAArvixk4Lb7/N2Ct9sTE\n"
1291 "NJO6RtK9lbEZ5uK61DglHy8CS2UCgYEA4ZC1o36kPAMQBggajgnucb2yuUEelk0f\n"
1292 "AEr+GI32MGE+93xMr7rAhBoqLg4AITyIfEnOSQ5HwagnIHonBbv1LV/Gf9ursx8Z\n"
1293 "YOGbvT8zzzC+SU1bkDzdjAYnFQVGIjMtKOBJ3K07++ypwX1fr4QsQ8uKL8WSOWwt\n"
1294 "Z3Bym6XiZzMCgYADnhy+2OwHX85AkLt+PyGlPbmuelpyTzS4IDAQbBa6jcuW/2wA\n"
1295 "UE2km75VUXmD+u2R/9zVuLm99NzhFhSMqlUxdV1YukfqMfP5yp1EY6m/5aW7QuIP\n"
1296 "2MDa7TVL9rIFMiVZ09RKvbBbQxjhuzPQKL6X/PPspnhiTefQ+dl2k9xREQKBgHDS\n"
1297 "fMfGNEeAEKezrfSVqxphE9/tXms3L+ZpnCaT+yu/uEr5dTIAawKoQ6i9f/sf1/Sy\n"
1298 "xedsqR+IB+oKrzIDDWMgoJybN4pkZ8E5lzhVQIjFjKgFdWLzzqyW9z1gYfABQPlN\n"
1299 "FiS20WX0vgP1vcKAjdNrHzc9zyHBpgQzDmAj3NZZAoGBAI8vKCKdH7w3aL5CNkZQ\n"
1300 "2buIeWNA2HZazVwAGG5F2TU/LmXfRKnG6dX5bkU+AkBZh56jNZy//hfFSewJB4Kk\n"
1301 "buB7ERSdaNbO21zXt9FEA3+z0RfMd/Zv2vlIWOSB5nzl/7UKti3sribK6s9ZVLfi\n"
1302 "SxpiPQ8d/hmSGwn4ksrWUsJD\n"
1303 "-----END PRIVATE KEY-----\n";
1304 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1305 return bssl::UniquePtr<EVP_PKEY>(
1306 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1307}
1308
David Benjaminc79ae7a2017-08-29 16:09:44 -04001309// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
1310// before configuring as a server.
1311TEST(SSLTest, ClientCAList) {
1312 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1313 ASSERT_TRUE(ctx);
1314 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1315 ASSERT_TRUE(ssl);
1316
1317 bssl::UniquePtr<X509_NAME> name(X509_NAME_new());
1318 ASSERT_TRUE(name);
1319
1320 bssl::UniquePtr<X509_NAME> name_dup(X509_NAME_dup(name.get()));
1321 ASSERT_TRUE(name_dup);
1322
1323 bssl::UniquePtr<STACK_OF(X509_NAME)> stack(sk_X509_NAME_new_null());
1324 ASSERT_TRUE(stack);
1325
1326 ASSERT_TRUE(sk_X509_NAME_push(stack.get(), name_dup.get()));
1327 name_dup.release();
1328
1329 // |SSL_set_client_CA_list| takes ownership.
1330 SSL_set_client_CA_list(ssl.get(), stack.release());
1331
1332 STACK_OF(X509_NAME) *result = SSL_get_client_CA_list(ssl.get());
1333 ASSERT_TRUE(result);
1334 ASSERT_EQ(1u, sk_X509_NAME_num(result));
1335 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(result, 0), name.get()));
1336}
1337
1338TEST(SSLTest, AddClientCA) {
1339 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1340 ASSERT_TRUE(ctx);
1341 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1342 ASSERT_TRUE(ssl);
1343
1344 bssl::UniquePtr<X509> cert1 = GetTestCertificate();
1345 bssl::UniquePtr<X509> cert2 = GetChainTestCertificate();
1346 ASSERT_TRUE(cert1 && cert2);
1347 X509_NAME *name1 = X509_get_subject_name(cert1.get());
1348 X509_NAME *name2 = X509_get_subject_name(cert2.get());
1349
1350 EXPECT_EQ(0u, sk_X509_NAME_num(SSL_get_client_CA_list(ssl.get())));
1351
1352 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1353 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert2.get()));
1354
1355 STACK_OF(X509_NAME) *list = SSL_get_client_CA_list(ssl.get());
1356 ASSERT_EQ(2u, sk_X509_NAME_num(list));
1357 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1358 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1359
1360 ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1361
1362 list = SSL_get_client_CA_list(ssl.get());
1363 ASSERT_EQ(3u, sk_X509_NAME_num(list));
1364 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1365 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1366 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 2), name1));
1367}
1368
1369static void AppendSession(SSL_SESSION *session, void *arg) {
1370 std::vector<SSL_SESSION*> *out =
1371 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
1372 out->push_back(session);
1373}
1374
1375// CacheEquals returns true if |ctx|'s session cache consists of |expected|, in
1376// order.
1377static bool CacheEquals(SSL_CTX *ctx,
1378 const std::vector<SSL_SESSION*> &expected) {
1379 // Check the linked list.
1380 SSL_SESSION *ptr = ctx->session_cache_head;
1381 for (SSL_SESSION *session : expected) {
1382 if (ptr != session) {
1383 return false;
1384 }
1385 // TODO(davidben): This is an absurd way to denote the end of the list.
1386 if (ptr->next ==
1387 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
1388 ptr = nullptr;
1389 } else {
1390 ptr = ptr->next;
1391 }
1392 }
1393 if (ptr != nullptr) {
1394 return false;
1395 }
1396
1397 // Check the hash table.
1398 std::vector<SSL_SESSION*> actual, expected_copy;
David Benjamin9eaa3bd2017-09-27 17:03:54 -04001399 lh_SSL_SESSION_doall_arg(ctx->sessions, AppendSession, &actual);
David Benjaminc79ae7a2017-08-29 16:09:44 -04001400 expected_copy = expected;
1401
1402 std::sort(actual.begin(), actual.end());
1403 std::sort(expected_copy.begin(), expected_copy.end());
1404
1405 return actual == expected_copy;
1406}
1407
1408static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
1409 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
1410 if (!ssl_ctx) {
1411 return nullptr;
1412 }
1413 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new(ssl_ctx.get()));
1414 if (!ret) {
1415 return nullptr;
1416 }
1417
David Benjaminaaef8332018-06-29 16:45:49 -04001418 uint8_t id[SSL3_SSL_SESSION_ID_LENGTH] = {0};
1419 OPENSSL_memcpy(id, &number, sizeof(number));
1420 if (!SSL_SESSION_set1_id(ret.get(), id, sizeof(id))) {
1421 return nullptr;
1422 }
David Benjaminc79ae7a2017-08-29 16:09:44 -04001423 return ret;
1424}
1425
1426// Test that the internal session cache behaves as expected.
1427TEST(SSLTest, InternalSessionCache) {
1428 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1429 ASSERT_TRUE(ctx);
1430
1431 // Prepare 10 test sessions.
1432 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
1433 for (int i = 0; i < 10; i++) {
1434 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
1435 ASSERT_TRUE(session);
1436 sessions.push_back(std::move(session));
1437 }
1438
1439 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1440
1441 // Insert all the test sessions.
1442 for (const auto &session : sessions) {
1443 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), session.get()));
1444 }
1445
1446 // Only the last five should be in the list.
1447 ASSERT_TRUE(CacheEquals(
1448 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
1449 sessions[6].get(), sessions[5].get()}));
1450
1451 // Inserting an element already in the cache should fail and leave the cache
1452 // unchanged.
1453 ASSERT_FALSE(SSL_CTX_add_session(ctx.get(), sessions[7].get()));
1454 ASSERT_TRUE(CacheEquals(
1455 ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
1456 sessions[6].get(), sessions[5].get()}));
1457
1458 // Although collisions should be impossible (256-bit session IDs), the cache
1459 // must handle them gracefully.
1460 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
1461 ASSERT_TRUE(collision);
1462 ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), collision.get()));
1463 ASSERT_TRUE(CacheEquals(
1464 ctx.get(), {collision.get(), sessions[9].get(), sessions[8].get(),
1465 sessions[6].get(), sessions[5].get()}));
1466
1467 // Removing sessions behaves correctly.
1468 ASSERT_TRUE(SSL_CTX_remove_session(ctx.get(), sessions[6].get()));
1469 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
1470 sessions[8].get(), sessions[5].get()}));
1471
1472 // Removing sessions requires an exact match.
1473 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[0].get()));
1474 ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[7].get()));
1475
1476 // The cache remains unchanged.
1477 ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
1478 sessions[8].get(), sessions[5].get()}));
1479}
1480
1481static uint16_t EpochFromSequence(uint64_t seq) {
1482 return static_cast<uint16_t>(seq >> 48);
1483}
1484
David Benjamin71dfad42017-07-16 17:27:39 -04001485static const uint8_t kTestName[] = {
1486 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
1487 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
1488 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
1489 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
1490 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
1491 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64,
1492};
1493
David Benjaminb79cc842016-12-07 15:57:14 -05001494static bool CompleteHandshakes(SSL *client, SSL *server) {
1495 // Drive both their handshakes to completion.
1496 for (;;) {
1497 int client_ret = SSL_do_handshake(client);
1498 int client_err = SSL_get_error(client, client_ret);
1499 if (client_err != SSL_ERROR_NONE &&
1500 client_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001501 client_err != SSL_ERROR_WANT_WRITE &&
1502 client_err != SSL_ERROR_PENDING_TICKET) {
David Benjaminb79cc842016-12-07 15:57:14 -05001503 fprintf(stderr, "Client error: %d\n", client_err);
1504 return false;
1505 }
1506
1507 int server_ret = SSL_do_handshake(server);
1508 int server_err = SSL_get_error(server, server_ret);
1509 if (server_err != SSL_ERROR_NONE &&
1510 server_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001511 server_err != SSL_ERROR_WANT_WRITE &&
1512 server_err != SSL_ERROR_PENDING_TICKET) {
David Benjaminb79cc842016-12-07 15:57:14 -05001513 fprintf(stderr, "Server error: %d\n", server_err);
1514 return false;
1515 }
1516
1517 if (client_ret == 1 && server_ret == 1) {
1518 break;
1519 }
1520 }
1521
1522 return true;
1523}
1524
David Benjamina8614602017-09-06 15:40:19 -04001525struct ClientConfig {
1526 SSL_SESSION *session = nullptr;
1527 std::string servername;
1528};
1529
David Benjaminb79cc842016-12-07 15:57:14 -05001530static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client,
1531 bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001532 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
Adam Langleyddb57cf2018-01-26 09:17:53 -08001533 const ClientConfig &config = ClientConfig(),
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001534 bool do_handshake = true,
1535 bool shed_handshake_config = true) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001536 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001537 if (!client || !server) {
1538 return false;
1539 }
1540 SSL_set_connect_state(client.get());
1541 SSL_set_accept_state(server.get());
1542
David Benjamina8614602017-09-06 15:40:19 -04001543 if (config.session) {
1544 SSL_set_session(client.get(), config.session);
1545 }
1546 if (!config.servername.empty() &&
1547 !SSL_set_tlsext_host_name(client.get(), config.servername.c_str())) {
1548 return false;
1549 }
David Benjamina20e5352016-08-02 19:09:41 -04001550
David Benjaminde942382016-02-11 12:02:01 -05001551 BIO *bio1, *bio2;
1552 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1553 return false;
1554 }
1555 // SSL_set_bio takes ownership.
1556 SSL_set_bio(client.get(), bio1, bio1);
1557 SSL_set_bio(server.get(), bio2, bio2);
1558
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001559 SSL_set_shed_handshake_config(client.get(), shed_handshake_config);
1560 SSL_set_shed_handshake_config(server.get(), shed_handshake_config);
1561
Adam Langleyddb57cf2018-01-26 09:17:53 -08001562 if (do_handshake && !CompleteHandshakes(client.get(), server.get())) {
David Benjaminb79cc842016-12-07 15:57:14 -05001563 return false;
David Benjaminde942382016-02-11 12:02:01 -05001564 }
1565
David Benjamin686bb192016-05-10 15:15:41 -04001566 *out_client = std::move(client);
1567 *out_server = std::move(server);
1568 return true;
1569}
1570
David Benjaminc11ea9422017-08-29 16:33:21 -04001571// SSLVersionTest executes its test cases under all available protocol versions.
1572// Test cases call |Connect| to create a connection using context objects with
1573// the protocol version fixed to the current version under test.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001574class SSLVersionTest : public ::testing::TestWithParam<VersionParam> {
1575 protected:
1576 SSLVersionTest() : cert_(GetTestCertificate()), key_(GetTestKey()) {}
1577
1578 void SetUp() { ResetContexts(); }
1579
1580 bssl::UniquePtr<SSL_CTX> CreateContext() const {
1581 const SSL_METHOD *method = is_dtls() ? DTLS_method() : TLS_method();
1582 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
1583 if (!ctx || !SSL_CTX_set_min_proto_version(ctx.get(), version()) ||
1584 !SSL_CTX_set_max_proto_version(ctx.get(), version())) {
1585 return nullptr;
1586 }
1587 return ctx;
David Benjamin0fef3052016-11-18 15:11:10 +09001588 }
David Benjamin686bb192016-05-10 15:15:41 -04001589
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001590 void ResetContexts() {
1591 ASSERT_TRUE(cert_);
1592 ASSERT_TRUE(key_);
1593 client_ctx_ = CreateContext();
1594 ASSERT_TRUE(client_ctx_);
1595 server_ctx_ = CreateContext();
1596 ASSERT_TRUE(server_ctx_);
1597 // Set up a server cert. Client certs can be set up explicitly.
1598 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09001599 }
David Benjamin686bb192016-05-10 15:15:41 -04001600
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001601 bool UseCertAndKey(SSL_CTX *ctx) const {
1602 return SSL_CTX_use_certificate(ctx, cert_.get()) &&
1603 SSL_CTX_use_PrivateKey(ctx, key_.get());
David Benjamin0fef3052016-11-18 15:11:10 +09001604 }
David Benjamin686bb192016-05-10 15:15:41 -04001605
David Benjamina8614602017-09-06 15:40:19 -04001606 bool Connect(const ClientConfig &config = ClientConfig()) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001607 return ConnectClientAndServer(&client_, &server_, client_ctx_.get(),
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001608 server_ctx_.get(), config, true,
1609 shed_handshake_config_);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001610 }
1611
1612 uint16_t version() const { return GetParam().version; }
1613
1614 bool is_dtls() const {
1615 return GetParam().ssl_method == VersionParam::is_dtls;
1616 }
1617
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07001618 bool shed_handshake_config_ = true;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001619 bssl::UniquePtr<SSL> client_, server_;
1620 bssl::UniquePtr<SSL_CTX> server_ctx_, client_ctx_;
1621 bssl::UniquePtr<X509> cert_;
1622 bssl::UniquePtr<EVP_PKEY> key_;
1623};
1624
1625INSTANTIATE_TEST_CASE_P(WithVersion, SSLVersionTest,
1626 testing::ValuesIn(kAllVersions),
1627 [](const testing::TestParamInfo<VersionParam> &i) {
1628 return i.param.name;
1629 });
1630
1631TEST_P(SSLVersionTest, SequenceNumber) {
1632 ASSERT_TRUE(Connect());
1633
David Benjamin0fef3052016-11-18 15:11:10 +09001634 // Drain any post-handshake messages to ensure there are no unread records
1635 // on either end.
1636 uint8_t byte = 0;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001637 ASSERT_LE(SSL_read(client_.get(), &byte, 1), 0);
1638 ASSERT_LE(SSL_read(server_.get(), &byte, 1), 0);
David Benjaminde942382016-02-11 12:02:01 -05001639
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001640 uint64_t client_read_seq = SSL_get_read_sequence(client_.get());
1641 uint64_t client_write_seq = SSL_get_write_sequence(client_.get());
1642 uint64_t server_read_seq = SSL_get_read_sequence(server_.get());
1643 uint64_t server_write_seq = SSL_get_write_sequence(server_.get());
Steven Valdez2c62fe92016-10-14 12:08:12 -04001644
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001645 if (is_dtls()) {
David Benjamin0fef3052016-11-18 15:11:10 +09001646 // Both client and server must be at epoch 1.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001647 EXPECT_EQ(EpochFromSequence(client_read_seq), 1);
1648 EXPECT_EQ(EpochFromSequence(client_write_seq), 1);
1649 EXPECT_EQ(EpochFromSequence(server_read_seq), 1);
1650 EXPECT_EQ(EpochFromSequence(server_write_seq), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09001651
1652 // The next record to be written should exceed the largest received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001653 EXPECT_GT(client_write_seq, server_read_seq);
1654 EXPECT_GT(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09001655 } else {
1656 // The next record to be written should equal the next to be received.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001657 EXPECT_EQ(client_write_seq, server_read_seq);
1658 EXPECT_EQ(server_write_seq, client_read_seq);
David Benjamin0fef3052016-11-18 15:11:10 +09001659 }
1660
1661 // Send a record from client to server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001662 EXPECT_EQ(SSL_write(client_.get(), &byte, 1), 1);
1663 EXPECT_EQ(SSL_read(server_.get(), &byte, 1), 1);
David Benjamin0fef3052016-11-18 15:11:10 +09001664
1665 // The client write and server read sequence numbers should have
1666 // incremented.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001667 EXPECT_EQ(client_write_seq + 1, SSL_get_write_sequence(client_.get()));
1668 EXPECT_EQ(server_read_seq + 1, SSL_get_read_sequence(server_.get()));
David Benjaminde942382016-02-11 12:02:01 -05001669}
1670
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001671TEST_P(SSLVersionTest, OneSidedShutdown) {
David Benjamin68f37b72016-11-18 15:14:42 +09001672 // SSL_shutdown is a no-op in DTLS.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001673 if (is_dtls()) {
1674 return;
David Benjamin686bb192016-05-10 15:15:41 -04001675 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001676 ASSERT_TRUE(Connect());
David Benjamin686bb192016-05-10 15:15:41 -04001677
1678 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1679 // one side has shut down.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001680 ASSERT_EQ(SSL_shutdown(client_.get()), 0);
David Benjamin686bb192016-05-10 15:15:41 -04001681
1682 // Reading from the server should consume the EOF.
1683 uint8_t byte;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001684 ASSERT_EQ(SSL_read(server_.get(), &byte, 1), 0);
1685 ASSERT_EQ(SSL_get_error(server_.get(), 0), SSL_ERROR_ZERO_RETURN);
David Benjamin686bb192016-05-10 15:15:41 -04001686
1687 // However, the server may continue to write data and then shut down the
1688 // connection.
1689 byte = 42;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001690 ASSERT_EQ(SSL_write(server_.get(), &byte, 1), 1);
1691 ASSERT_EQ(SSL_read(client_.get(), &byte, 1), 1);
1692 ASSERT_EQ(byte, 42);
David Benjamin686bb192016-05-10 15:15:41 -04001693
1694 // The server may then shutdown the connection.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001695 EXPECT_EQ(SSL_shutdown(server_.get()), 1);
1696 EXPECT_EQ(SSL_shutdown(client_.get()), 1);
David Benjamin686bb192016-05-10 15:15:41 -04001697}
David Benjamin68f37b72016-11-18 15:14:42 +09001698
David Benjaminf0d8e222017-02-04 10:58:26 -05001699TEST(SSLTest, SessionDuplication) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001700 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1701 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001702 ASSERT_TRUE(client_ctx);
1703 ASSERT_TRUE(server_ctx);
Steven Valdez87eab492016-06-27 16:34:59 -04001704
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001705 bssl::UniquePtr<X509> cert = GetTestCertificate();
1706 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminf0d8e222017-02-04 10:58:26 -05001707 ASSERT_TRUE(cert);
1708 ASSERT_TRUE(key);
1709 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
1710 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04001711
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001712 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05001713 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04001714 server_ctx.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04001715
1716 SSL_SESSION *session0 = SSL_get_session(client.get());
David Benjamin31b0c9b2017-07-20 14:49:15 -04001717 bssl::UniquePtr<SSL_SESSION> session1 =
1718 bssl::SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL);
David Benjaminf0d8e222017-02-04 10:58:26 -05001719 ASSERT_TRUE(session1);
David Benjamin4501bd52016-08-01 13:39:41 -04001720
David Benjamina3a71e92018-06-29 13:24:45 -04001721 session1->not_resumable = false;
Steven Valdez84b5c002016-08-25 16:30:58 -04001722
Steven Valdez87eab492016-06-27 16:34:59 -04001723 uint8_t *s0_bytes, *s1_bytes;
1724 size_t s0_len, s1_len;
1725
David Benjaminf0d8e222017-02-04 10:58:26 -05001726 ASSERT_TRUE(SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001727 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001728
David Benjaminf0d8e222017-02-04 10:58:26 -05001729 ASSERT_TRUE(SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001730 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001731
David Benjamin7d7554b2017-02-04 11:48:59 -05001732 EXPECT_EQ(Bytes(s0_bytes, s0_len), Bytes(s1_bytes, s1_len));
Steven Valdez87eab492016-06-27 16:34:59 -04001733}
David Benjamin686bb192016-05-10 15:15:41 -04001734
David Benjaminf0d8e222017-02-04 10:58:26 -05001735static void ExpectFDs(const SSL *ssl, int rfd, int wfd) {
David Benjaminca743582017-06-15 17:51:35 -04001736 EXPECT_EQ(rfd, SSL_get_fd(ssl));
David Benjaminf0d8e222017-02-04 10:58:26 -05001737 EXPECT_EQ(rfd, SSL_get_rfd(ssl));
1738 EXPECT_EQ(wfd, SSL_get_wfd(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04001739
1740 // The wrapper BIOs are always equal when fds are equal, even if set
1741 // individually.
David Benjaminf0d8e222017-02-04 10:58:26 -05001742 if (rfd == wfd) {
1743 EXPECT_EQ(SSL_get_rbio(ssl), SSL_get_wbio(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04001744 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001745}
1746
David Benjaminf0d8e222017-02-04 10:58:26 -05001747TEST(SSLTest, SetFD) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001748 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001749 ASSERT_TRUE(ctx);
David Benjamin5c0fb882016-06-14 14:03:51 -04001750
1751 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001752 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001753 ASSERT_TRUE(ssl);
1754 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1755 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
1756 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04001757
1758 // Test setting the same FD.
1759 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001760 ASSERT_TRUE(ssl);
1761 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1762 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001763
1764 // Test setting the same FD one side at a time.
1765 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001766 ASSERT_TRUE(ssl);
1767 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1768 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1769 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001770
1771 // Test setting the same FD in the other order.
1772 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001773 ASSERT_TRUE(ssl);
1774 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1775 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1776 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001777
David Benjamin5c0fb882016-06-14 14:03:51 -04001778 // Test changing the read FD partway through.
1779 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001780 ASSERT_TRUE(ssl);
1781 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1782 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 2));
1783 ExpectFDs(ssl.get(), 2, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001784
1785 // Test changing the write FD partway through.
1786 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001787 ASSERT_TRUE(ssl);
1788 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1789 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
1790 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04001791
1792 // Test a no-op change to the read FD partway through.
1793 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001794 ASSERT_TRUE(ssl);
1795 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1796 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1797 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001798
1799 // Test a no-op change to the write FD partway through.
1800 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001801 ASSERT_TRUE(ssl);
1802 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1803 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1804 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001805
1806 // ASan builds will implicitly test that the internal |BIO| reference-counting
1807 // is correct.
David Benjamin5c0fb882016-06-14 14:03:51 -04001808}
1809
David Benjaminf0d8e222017-02-04 10:58:26 -05001810TEST(SSLTest, SetBIO) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001811 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001812 ASSERT_TRUE(ctx);
David Benjamin4501bd52016-08-01 13:39:41 -04001813
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001814 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1815 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04001816 bio3(BIO_new(BIO_s_mem()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001817 ASSERT_TRUE(ssl);
1818 ASSERT_TRUE(bio1);
1819 ASSERT_TRUE(bio2);
1820 ASSERT_TRUE(bio3);
David Benjamin4501bd52016-08-01 13:39:41 -04001821
1822 // SSL_set_bio takes one reference when the parameters are the same.
1823 BIO_up_ref(bio1.get());
1824 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1825
1826 // Repeating the call does nothing.
1827 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1828
1829 // It takes one reference each when the parameters are different.
1830 BIO_up_ref(bio2.get());
1831 BIO_up_ref(bio3.get());
1832 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1833
1834 // Repeating the call does nothing.
1835 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1836
1837 // It takes one reference when changing only wbio.
1838 BIO_up_ref(bio1.get());
1839 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1840
1841 // It takes one reference when changing only rbio and the two are different.
1842 BIO_up_ref(bio3.get());
1843 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1844
1845 // If setting wbio to rbio, it takes no additional references.
1846 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1847
1848 // From there, wbio may be switched to something else.
1849 BIO_up_ref(bio1.get());
1850 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1851
1852 // If setting rbio to wbio, it takes no additional references.
1853 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1854
1855 // From there, rbio may be switched to something else, but, for historical
1856 // reasons, it takes a reference to both parameters.
1857 BIO_up_ref(bio1.get());
1858 BIO_up_ref(bio2.get());
1859 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1860
1861 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1862 // is correct.
David Benjamin4501bd52016-08-01 13:39:41 -04001863}
1864
David Benjamin25490f22016-07-14 00:22:54 -04001865static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1866
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001867TEST_P(SSLVersionTest, GetPeerCertificate) {
1868 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04001869
David Benjamin0fef3052016-11-18 15:11:10 +09001870 // Configure both client and server to accept any certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001871 SSL_CTX_set_verify(client_ctx_.get(),
1872 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1873 nullptr);
1874 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
1875 SSL_CTX_set_verify(server_ctx_.get(),
1876 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1877 nullptr);
1878 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjaminadd5e522016-07-14 00:33:24 -04001879
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001880 ASSERT_TRUE(Connect());
David Benjaminadd5e522016-07-14 00:33:24 -04001881
David Benjamin0fef3052016-11-18 15:11:10 +09001882 // Client and server should both see the leaf certificate.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001883 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1884 ASSERT_TRUE(peer);
1885 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04001886
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001887 peer.reset(SSL_get_peer_certificate(client_.get()));
1888 ASSERT_TRUE(peer);
1889 ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
David Benjaminadd5e522016-07-14 00:33:24 -04001890
David Benjamine664a532017-07-20 20:19:36 -04001891 // However, for historical reasons, the X509 chain includes the leaf on the
David Benjamin0fef3052016-11-18 15:11:10 +09001892 // client, but does not on the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001893 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(client_.get())), 1u);
1894 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(client_.get())),
1895 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04001896
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001897 EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(server_.get())), 0u);
1898 EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(server_.get())),
1899 1u);
David Benjaminadd5e522016-07-14 00:33:24 -04001900}
1901
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001902TEST_P(SSLVersionTest, NoPeerCertificate) {
1903 SSL_CTX_set_verify(server_ctx_.get(), SSL_VERIFY_PEER, nullptr);
1904 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
1905 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
David Benjamine664a532017-07-20 20:19:36 -04001906
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001907 ASSERT_TRUE(Connect());
David Benjamine664a532017-07-20 20:19:36 -04001908
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001909 // Server should not see a peer certificate.
1910 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1911 ASSERT_FALSE(peer);
1912 ASSERT_FALSE(SSL_get0_peer_certificates(server_.get()));
David Benjamine664a532017-07-20 20:19:36 -04001913}
1914
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001915TEST_P(SSLVersionTest, RetainOnlySHA256OfCerts) {
David Benjamin25490f22016-07-14 00:22:54 -04001916 uint8_t *cert_der = NULL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001917 int cert_der_len = i2d_X509(cert_.get(), &cert_der);
1918 ASSERT_GE(cert_der_len, 0);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001919 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04001920
1921 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1922 SHA256(cert_der, cert_der_len, cert_sha256);
1923
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001924 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
1925
David Benjamin0fef3052016-11-18 15:11:10 +09001926 // Configure both client and server to accept any certificate, but the
1927 // server must retain only the SHA-256 of the peer.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001928 SSL_CTX_set_verify(client_ctx_.get(),
1929 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1930 nullptr);
1931 SSL_CTX_set_verify(server_ctx_.get(),
1932 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1933 nullptr);
1934 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
1935 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
1936 SSL_CTX_set_retain_only_sha256_of_client_certs(server_ctx_.get(), 1);
David Benjamin25490f22016-07-14 00:22:54 -04001937
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001938 ASSERT_TRUE(Connect());
David Benjamin25490f22016-07-14 00:22:54 -04001939
David Benjamin0fef3052016-11-18 15:11:10 +09001940 // The peer certificate has been dropped.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001941 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
1942 EXPECT_FALSE(peer);
David Benjamin25490f22016-07-14 00:22:54 -04001943
Martin Kreichgauer1a663262017-08-16 14:54:04 -07001944 SSL_SESSION *session = SSL_get_session(server_.get());
David Benjamin02de7bd2018-05-08 18:13:54 -04001945 EXPECT_TRUE(SSL_SESSION_has_peer_sha256(session));
David Benjamin25490f22016-07-14 00:22:54 -04001946
David Benjamin02de7bd2018-05-08 18:13:54 -04001947 const uint8_t *peer_sha256;
1948 size_t peer_sha256_len;
1949 SSL_SESSION_get0_peer_sha256(session, &peer_sha256, &peer_sha256_len);
1950 EXPECT_EQ(Bytes(cert_sha256), Bytes(peer_sha256, peer_sha256_len));
David Benjamin25490f22016-07-14 00:22:54 -04001951}
1952
David Benjamin737d2df2017-09-25 15:05:19 -04001953// Tests that our ClientHellos do not change unexpectedly. These are purely
1954// change detection tests. If they fail as part of an intentional ClientHello
1955// change, update the test vector.
1956TEST(SSLTest, ClientHello) {
1957 struct {
1958 uint16_t max_version;
1959 std::vector<uint8_t> expected;
1960 } kTests[] = {
David Benjamin737d2df2017-09-25 15:05:19 -04001961 {TLS1_VERSION,
1962 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x01, 0x00,
1963 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1964 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1965 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
1966 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001967 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1968 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
David Benjamin737d2df2017-09-25 15:05:19 -04001969 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18}},
1970 {TLS1_1_VERSION,
1971 {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x02, 0x00,
1972 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1973 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1974 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
1975 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001976 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1977 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
David Benjamin737d2df2017-09-25 15:05:19 -04001978 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18}},
David Benjamin737d2df2017-09-25 15:05:19 -04001979 {TLS1_2_VERSION,
David Benjamin6e678ee2018-04-16 19:54:42 -04001980 {0x16, 0x03, 0x01, 0x00, 0x82, 0x01, 0x00, 0x00, 0x7e, 0x03, 0x03, 0x00,
David Benjamin737d2df2017-09-25 15:05:19 -04001981 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1982 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
David Benjamin6e678ee2018-04-16 19:54:42 -04001983 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xcc, 0xa9,
David Benjamin737d2df2017-09-25 15:05:19 -04001984 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xc0, 0x09,
David Benjamin6e678ee2018-04-16 19:54:42 -04001985 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
1986 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37, 0xff, 0x01, 0x00, 0x01,
David Benjamin737d2df2017-09-25 15:05:19 -04001987 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
1988 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
1989 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x00, 0x0b, 0x00,
1990 0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00,
1991 0x17, 0x00, 0x18}},
David Benjamin737d2df2017-09-25 15:05:19 -04001992 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
1993 // implementation has settled enough that it won't change.
David Benjaminafc64de2016-07-19 17:12:41 +02001994 };
David Benjamin737d2df2017-09-25 15:05:19 -04001995
1996 for (const auto &t : kTests) {
1997 SCOPED_TRACE(t.max_version);
1998
1999 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2000 ASSERT_TRUE(ctx);
2001 // Our default cipher list varies by CPU capabilities, so manually place the
2002 // ChaCha20 ciphers in front.
2003 const char *cipher_list = "CHACHA20:ALL";
David Benjamin737d2df2017-09-25 15:05:19 -04002004 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), t.max_version));
2005 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list));
2006
2007 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
2008 ASSERT_TRUE(ssl);
2009 std::vector<uint8_t> client_hello;
2010 ASSERT_TRUE(GetClientHello(ssl.get(), &client_hello));
2011
2012 // Zero the client_random.
2013 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
2014 1 + 3 + // handshake message header
2015 2; // client_version
2016 ASSERT_GE(client_hello.size(), kRandomOffset + SSL3_RANDOM_SIZE);
2017 OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
2018
2019 if (client_hello != t.expected) {
2020 ADD_FAILURE() << "ClientHellos did not match.";
2021 // Print the value manually so it is easier to update the test vector.
2022 for (size_t i = 0; i < client_hello.size(); i += 12) {
2023 printf(" %c", i == 0 ? '{' : ' ');
2024 for (size_t j = i; j < client_hello.size() && j < i + 12; j++) {
2025 if (j > i) {
2026 printf(" ");
2027 }
2028 printf("0x%02x", client_hello[j]);
2029 if (j < client_hello.size() - 1) {
2030 printf(",");
2031 }
2032 }
2033 if (i + 12 >= client_hello.size()) {
2034 printf("}}");
2035 }
2036 printf("\n");
2037 }
2038 }
David Benjaminafc64de2016-07-19 17:12:41 +02002039 }
David Benjaminafc64de2016-07-19 17:12:41 +02002040}
2041
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002042static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04002043
2044static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
2045 // Save the most recent session.
2046 g_last_session.reset(session);
2047 return 1;
2048}
2049
David Benjamina8614602017-09-06 15:40:19 -04002050static bssl::UniquePtr<SSL_SESSION> CreateClientSession(
2051 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2052 const ClientConfig &config = ClientConfig()) {
David Benjamina20e5352016-08-02 19:09:41 -04002053 g_last_session = nullptr;
2054 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2055
2056 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002057 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04002058 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
David Benjamina8614602017-09-06 15:40:19 -04002059 config)) {
David Benjamina20e5352016-08-02 19:09:41 -04002060 fprintf(stderr, "Failed to connect client and server.\n");
2061 return nullptr;
2062 }
2063
2064 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2065 SSL_read(client.get(), nullptr, 0);
2066
2067 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2068
2069 if (!g_last_session) {
2070 fprintf(stderr, "Client did not receive a session.\n");
2071 return nullptr;
2072 }
2073 return std::move(g_last_session);
2074}
2075
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002076static void ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2077 SSL_SESSION *session, bool want_reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002078 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002079 ClientConfig config;
2080 config.session = session;
2081 EXPECT_TRUE(
2082 ConnectClientAndServer(&client, &server, client_ctx, server_ctx, config));
David Benjamina20e5352016-08-02 19:09:41 -04002083
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002084 EXPECT_EQ(SSL_session_reused(client.get()), SSL_session_reused(server.get()));
David Benjamina20e5352016-08-02 19:09:41 -04002085
2086 bool was_reused = !!SSL_session_reused(client.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002087 EXPECT_EQ(was_reused, want_reused);
David Benjamina20e5352016-08-02 19:09:41 -04002088}
2089
David Benjamin3c51d9b2016-11-01 17:50:42 -04002090static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
2091 SSL_CTX *server_ctx,
2092 SSL_SESSION *session) {
2093 g_last_session = nullptr;
2094 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2095
2096 bssl::UniquePtr<SSL> client, server;
David Benjamina8614602017-09-06 15:40:19 -04002097 ClientConfig config;
2098 config.session = session;
2099 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
2100 config)) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002101 fprintf(stderr, "Failed to connect client and server.\n");
2102 return nullptr;
2103 }
2104
2105 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2106 fprintf(stderr, "Client and server were inconsistent.\n");
2107 return nullptr;
2108 }
2109
2110 if (!SSL_session_reused(client.get())) {
2111 fprintf(stderr, "Session was not reused.\n");
2112 return nullptr;
2113 }
2114
2115 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2116 SSL_read(client.get(), nullptr, 0);
2117
2118 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2119
2120 if (!g_last_session) {
2121 fprintf(stderr, "Client did not receive a renewed session.\n");
2122 return nullptr;
2123 }
2124 return std::move(g_last_session);
2125}
2126
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002127static void ExpectTicketKeyChanged(SSL_CTX *ctx, uint8_t *inout_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002128 bool changed) {
2129 uint8_t new_key[kTicketKeyLen];
David Benjaminc11ea9422017-08-29 16:33:21 -04002130 // May return 0, 1 or 48.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002131 ASSERT_EQ(SSL_CTX_get_tlsext_ticket_keys(ctx, new_key, kTicketKeyLen), 1);
2132 if (changed) {
2133 ASSERT_NE(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
2134 } else {
2135 ASSERT_EQ(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002136 }
2137 OPENSSL_memcpy(inout_key, new_key, kTicketKeyLen);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002138}
2139
David Benjamina933c382016-10-28 00:10:03 -04002140static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
2141 static const uint8_t kContext[] = {3};
2142
2143 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
2144 return SSL_TLSEXT_ERR_ALERT_FATAL;
2145 }
2146
2147 return SSL_TLSEXT_ERR_OK;
2148}
2149
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002150TEST_P(SSLVersionTest, SessionIDContext) {
David Benjamina20e5352016-08-02 19:09:41 -04002151 static const uint8_t kContext1[] = {1};
2152 static const uint8_t kContext2[] = {2};
2153
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002154 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2155 sizeof(kContext1)));
David Benjamina20e5352016-08-02 19:09:41 -04002156
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002157 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2158 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002159
David Benjamin0fef3052016-11-18 15:11:10 +09002160 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002161 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2162 ASSERT_TRUE(session);
David Benjamina20e5352016-08-02 19:09:41 -04002163
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002164 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2165 session.get(),
2166 true /* expect session reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002167
David Benjamin0fef3052016-11-18 15:11:10 +09002168 // Change the session ID context.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002169 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext2,
2170 sizeof(kContext2)));
David Benjamina20e5352016-08-02 19:09:41 -04002171
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002172 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2173 session.get(),
2174 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002175
David Benjamin0fef3052016-11-18 15:11:10 +09002176 // Change the session ID context back and install an SNI callback to switch
2177 // it.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002178 ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
2179 sizeof(kContext1)));
David Benjamina933c382016-10-28 00:10:03 -04002180
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002181 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09002182 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04002183
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002184 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2185 session.get(),
2186 false /* expect session not reused */));
David Benjamina933c382016-10-28 00:10:03 -04002187
David Benjamin0fef3052016-11-18 15:11:10 +09002188 // Switch the session ID context with the early callback instead.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002189 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), nullptr);
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002190 SSL_CTX_set_select_certificate_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002191 server_ctx_.get(),
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002192 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
2193 static const uint8_t kContext[] = {3};
2194
2195 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
2196 sizeof(kContext))) {
2197 return ssl_select_cert_error;
2198 }
2199
2200 return ssl_select_cert_success;
2201 });
David Benjamina933c382016-10-28 00:10:03 -04002202
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002203 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2204 session.get(),
2205 false /* expect session not reused */));
David Benjamina20e5352016-08-02 19:09:41 -04002206}
2207
David Benjamin721e8b72016-08-03 13:13:17 -04002208static timeval g_current_time;
2209
2210static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2211 *out_clock = g_current_time;
2212}
2213
David Benjamin17b30832017-01-28 14:00:32 -05002214static void FrozenTimeCallback(const SSL *ssl, timeval *out_clock) {
2215 out_clock->tv_sec = 1000;
2216 out_clock->tv_usec = 0;
2217}
2218
David Benjamin3c51d9b2016-11-01 17:50:42 -04002219static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
2220 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
2221 int encrypt) {
2222 static const uint8_t kZeros[16] = {0};
2223
2224 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -05002225 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamin3c51d9b2016-11-01 17:50:42 -04002226 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -05002227 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002228 return 0;
2229 }
2230
2231 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
2232 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
2233 return -1;
2234 }
2235
2236 // Returning two from the callback in decrypt mode renews the
2237 // session in TLS 1.2 and below.
2238 return encrypt ? 1 : 2;
2239}
2240
David Benjamin123db572016-11-03 16:59:25 -04002241static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjaminaaef8332018-06-29 16:45:49 -04002242 const uint8_t *ticket;
2243 size_t ticket_len;
2244 SSL_SESSION_get0_ticket(session, &ticket, &ticket_len);
2245 if (ticket_len < 16 + 16 + SHA256_DIGEST_LENGTH) {
David Benjamin123db572016-11-03 16:59:25 -04002246 return false;
2247 }
2248
David Benjaminaaef8332018-06-29 16:45:49 -04002249 const uint8_t *ciphertext = ticket + 16 + 16;
2250 size_t len = ticket_len - 16 - 16 - SHA256_DIGEST_LENGTH;
David Benjamin123db572016-11-03 16:59:25 -04002251 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
2252
David Benjamin9b63f292016-11-15 00:44:05 -05002253#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
2254 // Fuzzer-mode tickets are unencrypted.
David Benjamin17cf2cb2016-12-13 01:07:13 -05002255 OPENSSL_memcpy(plaintext.get(), ciphertext, len);
David Benjamin9b63f292016-11-15 00:44:05 -05002256#else
2257 static const uint8_t kZeros[16] = {0};
David Benjaminaaef8332018-06-29 16:45:49 -04002258 const uint8_t *iv = ticket + 16;
David Benjamin123db572016-11-03 16:59:25 -04002259 bssl::ScopedEVP_CIPHER_CTX ctx;
2260 int len1, len2;
2261 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
2262 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
2263 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
2264 return false;
2265 }
2266
2267 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05002268#endif
David Benjamin123db572016-11-03 16:59:25 -04002269
Adam Langley46db7af2017-02-01 15:49:37 -08002270 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
2271 if (!ssl_ctx) {
2272 return false;
2273 }
David Benjamin123db572016-11-03 16:59:25 -04002274 bssl::UniquePtr<SSL_SESSION> server_session(
Adam Langley46db7af2017-02-01 15:49:37 -08002275 SSL_SESSION_from_bytes(plaintext.get(), len, ssl_ctx.get()));
David Benjamin123db572016-11-03 16:59:25 -04002276 if (!server_session) {
2277 return false;
2278 }
2279
David Benjaminaaef8332018-06-29 16:45:49 -04002280 *out = SSL_SESSION_get_time(server_session.get());
David Benjamin123db572016-11-03 16:59:25 -04002281 return true;
2282}
2283
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002284TEST_P(SSLVersionTest, SessionTimeout) {
2285 for (bool server_test : {false, true}) {
2286 SCOPED_TRACE(server_test);
David Benjamin721e8b72016-08-03 13:13:17 -04002287
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002288 ResetContexts();
2289 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2290 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
2291
David Benjamin17b30832017-01-28 14:00:32 -05002292 static const time_t kStartTime = 1000;
David Benjamin0fef3052016-11-18 15:11:10 +09002293 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002294
David Benjamin17b30832017-01-28 14:00:32 -05002295 // We are willing to use a longer lifetime for TLS 1.3 sessions as
2296 // resumptions still perform ECDHE.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002297 const time_t timeout = version() == TLS1_3_VERSION
David Benjamin17b30832017-01-28 14:00:32 -05002298 ? SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT
2299 : SSL_DEFAULT_SESSION_TIMEOUT;
2300
David Benjamin17b30832017-01-28 14:00:32 -05002301 // Both client and server must enforce session timeouts. We configure the
2302 // other side with a frozen clock so it never expires tickets.
David Benjamin0fef3052016-11-18 15:11:10 +09002303 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002304 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2305 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002306 } else {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002307 SSL_CTX_set_current_time_cb(client_ctx_.get(), CurrentTimeCallback);
2308 SSL_CTX_set_current_time_cb(server_ctx_.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002309 }
2310
2311 // Configure a ticket callback which renews tickets.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002312 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002313
2314 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002315 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2316 ASSERT_TRUE(session);
David Benjamin0fef3052016-11-18 15:11:10 +09002317
2318 // Advance the clock just behind the timeout.
David Benjamin17b30832017-01-28 14:00:32 -05002319 g_current_time.tv_sec += timeout - 1;
David Benjamin0fef3052016-11-18 15:11:10 +09002320
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002321 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2322 session.get(),
2323 true /* expect session reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002324
2325 // Advance the clock one more second.
2326 g_current_time.tv_sec++;
2327
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002328 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2329 session.get(),
2330 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002331
2332 // Rewind the clock to before the session was minted.
2333 g_current_time.tv_sec = kStartTime - 1;
2334
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002335 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2336 session.get(),
2337 false /* expect session not reused */));
David Benjamin0fef3052016-11-18 15:11:10 +09002338
David Benjamin0fef3052016-11-18 15:11:10 +09002339 // Renew the session 10 seconds before expiration.
David Benjamin17b30832017-01-28 14:00:32 -05002340 time_t new_start_time = kStartTime + timeout - 10;
2341 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002342 bssl::UniquePtr<SSL_SESSION> new_session = ExpectSessionRenewed(
2343 client_ctx_.get(), server_ctx_.get(), session.get());
2344 ASSERT_TRUE(new_session);
David Benjamin0fef3052016-11-18 15:11:10 +09002345
2346 // This new session is not the same object as before.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002347 EXPECT_NE(session.get(), new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002348
2349 // Check the sessions have timestamps measured from issuance.
2350 long session_time = 0;
2351 if (server_test) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002352 ASSERT_TRUE(GetServerTicketTime(&session_time, new_session.get()));
David Benjamin0fef3052016-11-18 15:11:10 +09002353 } else {
David Benjaminaaef8332018-06-29 16:45:49 -04002354 session_time = SSL_SESSION_get_time(new_session.get());
David Benjamin0fef3052016-11-18 15:11:10 +09002355 }
David Benjamin721e8b72016-08-03 13:13:17 -04002356
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002357 ASSERT_EQ(session_time, g_current_time.tv_sec);
David Benjamin721e8b72016-08-03 13:13:17 -04002358
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002359 if (version() == TLS1_3_VERSION) {
David Benjamin17b30832017-01-28 14:00:32 -05002360 // Renewal incorporates fresh key material in TLS 1.3, so we extend the
2361 // lifetime TLS 1.3.
2362 g_current_time.tv_sec = new_start_time + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002363 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2364 new_session.get(),
2365 true /* expect session reused */));
David Benjamin721e8b72016-08-03 13:13:17 -04002366
David Benjamin17b30832017-01-28 14:00:32 -05002367 // The new session expires after the new timeout.
2368 g_current_time.tv_sec = new_start_time + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002369 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2370 new_session.get(),
2371 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002372
2373 // Renew the session until it begins just past the auth timeout.
2374 time_t auth_end_time = kStartTime + SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
2375 while (new_start_time < auth_end_time - 1000) {
2376 // Get as close as possible to target start time.
2377 new_start_time =
2378 std::min(auth_end_time - 1000, new_start_time + timeout - 1);
2379 g_current_time.tv_sec = new_start_time;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002380 new_session = ExpectSessionRenewed(client_ctx_.get(), server_ctx_.get(),
David Benjamin17b30832017-01-28 14:00:32 -05002381 new_session.get());
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002382 ASSERT_TRUE(new_session);
David Benjamin17b30832017-01-28 14:00:32 -05002383 }
2384
2385 // Now the session's lifetime is bound by the auth timeout.
2386 g_current_time.tv_sec = auth_end_time - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002387 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2388 new_session.get(),
2389 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002390
2391 g_current_time.tv_sec = auth_end_time + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002392 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2393 new_session.get(),
2394 false /* expect session ot reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002395 } else {
2396 // The new session is usable just before the old expiration.
2397 g_current_time.tv_sec = kStartTime + timeout - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002398 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2399 new_session.get(),
2400 true /* expect session reused */));
David Benjamin17b30832017-01-28 14:00:32 -05002401
2402 // Renewal does not extend the lifetime, so it is not usable beyond the
2403 // old expiration.
2404 g_current_time.tv_sec = kStartTime + timeout + 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002405 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
2406 new_session.get(),
2407 false /* expect session not reused */));
David Benjamin1b22f852016-10-27 16:36:32 -04002408 }
David Benjamin721e8b72016-08-03 13:13:17 -04002409 }
David Benjamin721e8b72016-08-03 13:13:17 -04002410}
2411
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002412TEST_P(SSLVersionTest, DefaultTicketKeyInitialization) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002413 static const uint8_t kZeroKey[kTicketKeyLen] = {};
2414 uint8_t ticket_key[kTicketKeyLen];
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002415 ASSERT_EQ(1, SSL_CTX_get_tlsext_ticket_keys(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002416 kTicketKeyLen));
2417 ASSERT_NE(0, OPENSSL_memcmp(ticket_key, kZeroKey, kTicketKeyLen));
2418}
2419
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002420TEST_P(SSLVersionTest, DefaultTicketKeyRotation) {
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002421 static const time_t kStartTime = 1001;
2422 g_current_time.tv_sec = kStartTime;
2423 uint8_t ticket_key[kTicketKeyLen];
2424
David Benjaminc11ea9422017-08-29 16:33:21 -04002425 // We use session reuse as a proxy for ticket decryption success, hence
2426 // disable session timeouts.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002427 SSL_CTX_set_timeout(server_ctx_.get(), std::numeric_limits<uint32_t>::max());
2428 SSL_CTX_set_session_psk_dhe_timeout(server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002429 std::numeric_limits<uint32_t>::max());
2430
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002431 SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
2432 SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002433
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002434 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
2435 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_OFF);
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002436
David Benjaminc11ea9422017-08-29 16:33:21 -04002437 // Initialize ticket_key with the current key.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002438 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2439 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002440
David Benjaminc11ea9422017-08-29 16:33:21 -04002441 // Verify ticket resumption actually works.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002442 bssl::UniquePtr<SSL> client, server;
2443 bssl::UniquePtr<SSL_SESSION> session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002444 CreateClientSession(client_ctx_.get(), server_ctx_.get());
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002445 ASSERT_TRUE(session);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002446 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002447 session.get(), true /* reused */));
2448
David Benjaminc11ea9422017-08-29 16:33:21 -04002449 // Advance time to just before key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002450 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL - 1;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002451 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002452 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002453 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002454 false /* NOT changed */));
2455
David Benjaminc11ea9422017-08-29 16:33:21 -04002456 // Force key rotation.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002457 g_current_time.tv_sec += 1;
2458 bssl::UniquePtr<SSL_SESSION> new_session =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002459 CreateClientSession(client_ctx_.get(), server_ctx_.get());
2460 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2461 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002462
David Benjaminc11ea9422017-08-29 16:33:21 -04002463 // Resumption with both old and new ticket should work.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002464 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002465 session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002466 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002467 new_session.get(), true /* reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002468 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002469 false /* NOT changed */));
2470
David Benjaminc11ea9422017-08-29 16:33:21 -04002471 // Force key rotation again. Resumption with the old ticket now fails.
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002472 g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002473 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002474 session.get(), false /* NOT reused */));
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002475 TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
2476 true /* changed */));
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002477
David Benjaminc11ea9422017-08-29 16:33:21 -04002478 // But resumption with the newer session still works.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002479 TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002480 new_session.get(), true /* reused */));
2481}
2482
David Benjamin0fc37ef2016-08-17 15:29:46 -04002483static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002484 SSL_CTX *ctx = reinterpret_cast<SSL_CTX *>(arg);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002485 SSL_set_SSL_CTX(ssl, ctx);
2486 return SSL_TLSEXT_ERR_OK;
2487}
2488
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002489TEST_P(SSLVersionTest, SNICallback) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002490 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002491 ASSERT_TRUE(cert2);
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002492 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002493 ASSERT_TRUE(key2);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002494
David Benjamin0fef3052016-11-18 15:11:10 +09002495 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
2496 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002497
David Benjamin83a32122017-02-14 18:34:54 -05002498 static const uint8_t kSCTList[] = {0, 6, 0, 4, 5, 6, 7, 8};
2499 static const uint8_t kOCSPResponse[] = {1, 2, 3, 4};
2500
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002501 bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
2502 ASSERT_TRUE(server_ctx2);
2503 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()));
2504 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()));
2505 ASSERT_TRUE(SSL_CTX_set_signed_cert_timestamp_list(
2506 server_ctx2.get(), kSCTList, sizeof(kSCTList)));
2507 ASSERT_TRUE(SSL_CTX_set_ocsp_response(server_ctx2.get(), kOCSPResponse,
2508 sizeof(kOCSPResponse)));
2509 // Historically signing preferences would be lost in some cases with the
2510 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2511 // this doesn't happen when |version| is TLS 1.2, configure the private
2512 // key to only sign SHA-256.
2513 ASSERT_TRUE(SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
2514 &kECDSAWithSHA256, 1));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002515
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002516 SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), SwitchContext);
2517 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002518
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002519 SSL_CTX_enable_signed_cert_timestamps(client_ctx_.get());
2520 SSL_CTX_enable_ocsp_stapling(client_ctx_.get());
David Benjamin83a32122017-02-14 18:34:54 -05002521
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002522 ASSERT_TRUE(Connect());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002523
David Benjamin0fef3052016-11-18 15:11:10 +09002524 // The client should have received |cert2|.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002525 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client_.get()));
2526 ASSERT_TRUE(peer);
2527 EXPECT_EQ(X509_cmp(peer.get(), cert2.get()), 0);
David Benjamin0fc37ef2016-08-17 15:29:46 -04002528
David Benjamin83a32122017-02-14 18:34:54 -05002529 // The client should have received |server_ctx2|'s SCT list.
2530 const uint8_t *data;
2531 size_t len;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002532 SSL_get0_signed_cert_timestamp_list(client_.get(), &data, &len);
2533 EXPECT_EQ(Bytes(kSCTList), Bytes(data, len));
David Benjamin83a32122017-02-14 18:34:54 -05002534
2535 // The client should have received |server_ctx2|'s OCSP response.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002536 SSL_get0_ocsp_response(client_.get(), &data, &len);
2537 EXPECT_EQ(Bytes(kOCSPResponse), Bytes(data, len));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002538}
2539
David Benjaminf0d8e222017-02-04 10:58:26 -05002540// Test that the early callback can swap the maximum version.
2541TEST(SSLTest, EarlyCallbackVersionSwitch) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002542 bssl::UniquePtr<X509> cert = GetTestCertificate();
2543 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2544 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2545 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002546 ASSERT_TRUE(cert);
2547 ASSERT_TRUE(key);
2548 ASSERT_TRUE(server_ctx);
2549 ASSERT_TRUE(client_ctx);
2550 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
2551 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
2552 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
2553 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
David Benjamin99620572016-08-30 00:35:36 -04002554
David Benjaminf0d8e222017-02-04 10:58:26 -05002555 SSL_CTX_set_select_certificate_cb(
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002556 server_ctx.get(),
2557 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
David Benjaminf0d8e222017-02-04 10:58:26 -05002558 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002559 return ssl_select_cert_error;
David Benjaminf0d8e222017-02-04 10:58:26 -05002560 }
2561
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002562 return ssl_select_cert_success;
David Benjaminf0d8e222017-02-04 10:58:26 -05002563 });
David Benjamin99620572016-08-30 00:35:36 -04002564
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002565 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05002566 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04002567 server_ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002568 EXPECT_EQ(TLS1_2_VERSION, SSL_version(client.get()));
David Benjamin99620572016-08-30 00:35:36 -04002569}
2570
David Benjaminf0d8e222017-02-04 10:58:26 -05002571TEST(SSLTest, SetVersion) {
David Benjamin2dc02042016-09-19 19:57:37 -04002572 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002573 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002574
David Benjaminf0d8e222017-02-04 10:58:26 -05002575 // Set valid TLS versions.
2576 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2577 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
2578 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2579 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002580
David Benjaminf0d8e222017-02-04 10:58:26 -05002581 // Invalid TLS versions are rejected.
2582 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2583 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x0200));
2584 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2585 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2586 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x0200));
2587 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002588
David Benjaminf0d8e222017-02-04 10:58:26 -05002589 // Zero is the default version.
2590 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002591 EXPECT_EQ(TLS1_2_VERSION, ctx->conf_max_version);
David Benjaminf0d8e222017-02-04 10:58:26 -05002592 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002593 EXPECT_EQ(TLS1_VERSION, ctx->conf_min_version);
David Benjamin3cfeb952017-03-01 16:48:38 -05002594
David Benjamin9bb15f52018-06-26 00:07:40 -04002595 // TLS 1.3 is available, but not by default.
David Benjamin3cfeb952017-03-01 16:48:38 -05002596 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002597 EXPECT_EQ(TLS1_3_VERSION, ctx->conf_max_version);
David Benjamine34bcc92016-09-21 16:53:09 -04002598
David Benjamin9bb15f52018-06-26 00:07:40 -04002599 // SSL 3.0 is not available.
2600 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION));
2601
David Benjamin353577c2017-06-29 15:54:58 -04002602 // TLS1_3_DRAFT_VERSION is not an API-level version.
Steven Valdez64cc1212017-12-04 11:15:37 -05002603 EXPECT_FALSE(
Steven Valdez7e5dd252018-01-22 15:20:31 -05002604 SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_DRAFT23_VERSION));
David Benjamin353577c2017-06-29 15:54:58 -04002605 ERR_clear_error();
2606
David Benjamin2dc02042016-09-19 19:57:37 -04002607 ctx.reset(SSL_CTX_new(DTLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002608 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002609
David Benjaminf0d8e222017-02-04 10:58:26 -05002610 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2611 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION));
2612 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2613 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002614
David Benjaminf0d8e222017-02-04 10:58:26 -05002615 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2616 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2617 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2618 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2619 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2620 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2621 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2622 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002623
David Benjaminf0d8e222017-02-04 10:58:26 -05002624 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002625 EXPECT_EQ(TLS1_2_VERSION, ctx->conf_max_version);
David Benjaminf0d8e222017-02-04 10:58:26 -05002626 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
David Benjaminfc08dfc2017-06-20 14:39:32 -04002627 EXPECT_EQ(TLS1_1_VERSION, ctx->conf_min_version);
David Benjamin2dc02042016-09-19 19:57:37 -04002628}
2629
David Benjamin458334a2016-12-15 13:53:25 -05002630static const char *GetVersionName(uint16_t version) {
2631 switch (version) {
David Benjamin458334a2016-12-15 13:53:25 -05002632 case TLS1_VERSION:
2633 return "TLSv1";
2634 case TLS1_1_VERSION:
2635 return "TLSv1.1";
2636 case TLS1_2_VERSION:
2637 return "TLSv1.2";
2638 case TLS1_3_VERSION:
2639 return "TLSv1.3";
2640 case DTLS1_VERSION:
2641 return "DTLSv1";
2642 case DTLS1_2_VERSION:
2643 return "DTLSv1.2";
2644 default:
2645 return "???";
2646 }
2647}
2648
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002649TEST_P(SSLVersionTest, Version) {
2650 ASSERT_TRUE(Connect());
David Benjamincb18ac22016-09-27 14:09:15 -04002651
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002652 EXPECT_EQ(SSL_version(client_.get()), version());
2653 EXPECT_EQ(SSL_version(server_.get()), version());
David Benjamincb18ac22016-09-27 14:09:15 -04002654
David Benjamin458334a2016-12-15 13:53:25 -05002655 // Test the version name is reported as expected.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002656 const char *version_name = GetVersionName(version());
2657 EXPECT_EQ(strcmp(version_name, SSL_get_version(client_.get())), 0);
2658 EXPECT_EQ(strcmp(version_name, SSL_get_version(server_.get())), 0);
David Benjamin458334a2016-12-15 13:53:25 -05002659
2660 // Test SSL_SESSION reports the same name.
2661 const char *client_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002662 SSL_SESSION_get_version(SSL_get_session(client_.get()));
David Benjamin458334a2016-12-15 13:53:25 -05002663 const char *server_name =
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002664 SSL_SESSION_get_version(SSL_get_session(server_.get()));
2665 EXPECT_EQ(strcmp(version_name, client_name), 0);
2666 EXPECT_EQ(strcmp(version_name, server_name), 0);
David Benjamincb18ac22016-09-27 14:09:15 -04002667}
2668
David Benjamin9ef31f02016-10-31 18:01:13 -04002669// Tests that that |SSL_get_pending_cipher| is available during the ALPN
2670// selection callback.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002671TEST_P(SSLVersionTest, ALPNCipherAvailable) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002672 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2673
David Benjamin9ef31f02016-10-31 18:01:13 -04002674 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002675 ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
2676 sizeof(kALPNProtos)),
2677 0);
David Benjamin0fef3052016-11-18 15:11:10 +09002678
2679 // The ALPN callback does not fail the handshake on error, so have the
2680 // callback write a boolean.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002681 std::pair<uint16_t, bool> callback_state(version(), false);
David Benjamin0fef3052016-11-18 15:11:10 +09002682 SSL_CTX_set_alpn_select_cb(
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002683 server_ctx_.get(),
David Benjamin0fef3052016-11-18 15:11:10 +09002684 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
2685 unsigned in_len, void *arg) -> int {
2686 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
2687 if (SSL_get_pending_cipher(ssl) != nullptr &&
2688 SSL_version(ssl) == state->first) {
2689 state->second = true;
2690 }
2691 return SSL_TLSEXT_ERR_NOACK;
2692 },
2693 &callback_state);
2694
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002695 ASSERT_TRUE(Connect());
David Benjamin0fef3052016-11-18 15:11:10 +09002696
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002697 ASSERT_TRUE(callback_state.second);
David Benjamin0fef3052016-11-18 15:11:10 +09002698}
2699
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002700TEST_P(SSLVersionTest, SSLClearSessionResumption) {
David Benjaminb79cc842016-12-07 15:57:14 -05002701 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
2702 // API pattern.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002703 if (version() == TLS1_3_VERSION) {
2704 return;
David Benjaminb79cc842016-12-07 15:57:14 -05002705 }
2706
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07002707 shed_handshake_config_ = false;
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002708 ASSERT_TRUE(Connect());
David Benjaminb79cc842016-12-07 15:57:14 -05002709
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002710 EXPECT_FALSE(SSL_session_reused(client_.get()));
2711 EXPECT_FALSE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002712
2713 // Reset everything.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002714 ASSERT_TRUE(SSL_clear(client_.get()));
2715 ASSERT_TRUE(SSL_clear(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002716
2717 // Attempt to connect a second time.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002718 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002719
2720 // |SSL_clear| should implicitly offer the previous session to the server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002721 EXPECT_TRUE(SSL_session_reused(client_.get()));
2722 EXPECT_TRUE(SSL_session_reused(server_.get()));
David Benjaminb79cc842016-12-07 15:57:14 -05002723}
2724
Matthew Braithwaiteb7bc80a2018-04-13 15:51:30 -07002725TEST_P(SSLVersionTest, SSLClearFailsWithShedding) {
2726 shed_handshake_config_ = false;
2727 ASSERT_TRUE(Connect());
2728 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
2729
2730 // Reset everything.
2731 ASSERT_TRUE(SSL_clear(client_.get()));
2732 ASSERT_TRUE(SSL_clear(server_.get()));
2733
2734 // Now enable shedding, and connect a second time.
2735 shed_handshake_config_ = true;
2736 ASSERT_TRUE(Connect());
2737 ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
2738
2739 // |SSL_clear| should now fail.
2740 ASSERT_FALSE(SSL_clear(client_.get()));
2741 ASSERT_FALSE(SSL_clear(server_.get()));
2742}
2743
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002744static bool ChainsEqual(STACK_OF(X509) * chain,
2745 const std::vector<X509 *> &expected) {
David Benjamin1444c3a2016-12-20 17:23:11 -05002746 if (sk_X509_num(chain) != expected.size()) {
2747 return false;
2748 }
2749
2750 for (size_t i = 0; i < expected.size(); i++) {
2751 if (X509_cmp(sk_X509_value(chain, i), expected[i]) != 0) {
2752 return false;
2753 }
2754 }
2755
2756 return true;
2757}
2758
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002759TEST_P(SSLVersionTest, AutoChain) {
2760 cert_ = GetChainTestCertificate();
2761 ASSERT_TRUE(cert_);
2762 key_ = GetChainTestKey();
2763 ASSERT_TRUE(key_);
David Benjamin1444c3a2016-12-20 17:23:11 -05002764 bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002765 ASSERT_TRUE(intermediate);
2766
2767 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2768 ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
David Benjamin1444c3a2016-12-20 17:23:11 -05002769
2770 // Configure both client and server to accept any certificate. Add
2771 // |intermediate| to the cert store.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002772 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx_.get()),
2773 intermediate.get()));
2774 ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(server_ctx_.get()),
2775 intermediate.get()));
2776 SSL_CTX_set_verify(client_ctx_.get(),
2777 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2778 nullptr);
2779 SSL_CTX_set_verify(server_ctx_.get(),
2780 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2781 nullptr);
2782 SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
2783 SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
David Benjamin1444c3a2016-12-20 17:23:11 -05002784
2785 // By default, the client and server should each only send the leaf.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002786 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002787
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002788 EXPECT_TRUE(
2789 ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()), {cert_.get()}));
2790 EXPECT_TRUE(
2791 ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()), {cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002792
2793 // If auto-chaining is enabled, then the intermediate is sent.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002794 SSL_CTX_clear_mode(client_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
2795 SSL_CTX_clear_mode(server_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
2796 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002797
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002798 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
2799 {cert_.get(), intermediate.get()}));
2800 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
2801 {cert_.get(), intermediate.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002802
2803 // Auto-chaining does not override explicitly-configured intermediates.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002804 ASSERT_TRUE(SSL_CTX_add1_chain_cert(client_ctx_.get(), cert_.get()));
2805 ASSERT_TRUE(SSL_CTX_add1_chain_cert(server_ctx_.get(), cert_.get()));
2806 ASSERT_TRUE(Connect());
David Benjamin1444c3a2016-12-20 17:23:11 -05002807
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002808 EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
2809 {cert_.get(), cert_.get()}));
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(server_.get()),
2812 {cert_.get(), cert_.get()}));
David Benjamin1444c3a2016-12-20 17:23:11 -05002813}
2814
David Benjamin48063c22017-01-01 23:56:36 -05002815static bool ExpectBadWriteRetry() {
2816 int err = ERR_get_error();
2817 if (ERR_GET_LIB(err) != ERR_LIB_SSL ||
2818 ERR_GET_REASON(err) != SSL_R_BAD_WRITE_RETRY) {
2819 char buf[ERR_ERROR_STRING_BUF_LEN];
2820 ERR_error_string_n(err, buf, sizeof(buf));
2821 fprintf(stderr, "Wanted SSL_R_BAD_WRITE_RETRY, got: %s.\n", buf);
2822 return false;
2823 }
2824
2825 if (ERR_peek_error() != 0) {
2826 fprintf(stderr, "Unexpected error following SSL_R_BAD_WRITE_RETRY.\n");
2827 return false;
2828 }
2829
2830 return true;
2831}
2832
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002833TEST_P(SSLVersionTest, SSLWriteRetry) {
2834 if (is_dtls()) {
2835 return;
David Benjamin48063c22017-01-01 23:56:36 -05002836 }
2837
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002838 for (bool enable_partial_write : {false, true}) {
2839 SCOPED_TRACE(enable_partial_write);
2840
David Benjamin48063c22017-01-01 23:56:36 -05002841 // Connect a client and server.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002842 ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
2843
2844 ASSERT_TRUE(Connect());
David Benjamin48063c22017-01-01 23:56:36 -05002845
2846 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002847 SSL_set_mode(client_.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002848 }
2849
2850 // Write without reading until the buffer is full and we have an unfinished
2851 // write. Keep a count so we may reread it again later. "hello!" will be
2852 // written in two chunks, "hello" and "!".
2853 char data[] = "hello!";
2854 static const int kChunkLen = 5; // The length of "hello".
2855 unsigned count = 0;
2856 for (;;) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002857 int ret = SSL_write(client_.get(), data, kChunkLen);
David Benjamin48063c22017-01-01 23:56:36 -05002858 if (ret <= 0) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002859 ASSERT_EQ(SSL_get_error(client_.get(), ret), SSL_ERROR_WANT_WRITE);
2860 break;
David Benjamin48063c22017-01-01 23:56:36 -05002861 }
2862
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002863 ASSERT_EQ(ret, 5);
David Benjamin48063c22017-01-01 23:56:36 -05002864
2865 count++;
2866 }
2867
2868 // Retrying with the same parameters is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002869 ASSERT_EQ(
2870 SSL_get_error(client_.get(), SSL_write(client_.get(), data, kChunkLen)),
2871 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002872
2873 // Retrying with the same buffer but shorter length is not legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002874 ASSERT_EQ(SSL_get_error(client_.get(),
2875 SSL_write(client_.get(), data, kChunkLen - 1)),
2876 SSL_ERROR_SSL);
2877 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002878
2879 // Retrying with a different buffer pointer is not legal.
2880 char data2[] = "hello";
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002881 ASSERT_EQ(SSL_get_error(client_.get(),
2882 SSL_write(client_.get(), data2, kChunkLen)),
2883 SSL_ERROR_SSL);
2884 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002885
2886 // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002887 SSL_set_mode(client_.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
2888 ASSERT_EQ(SSL_get_error(client_.get(),
2889 SSL_write(client_.get(), data2, kChunkLen)),
2890 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002891
2892 // |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| does not disable length checks.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002893 ASSERT_EQ(SSL_get_error(client_.get(),
2894 SSL_write(client_.get(), data2, kChunkLen - 1)),
2895 SSL_ERROR_SSL);
2896 ASSERT_TRUE(ExpectBadWriteRetry());
David Benjamin48063c22017-01-01 23:56:36 -05002897
2898 // Retrying with a larger buffer is legal.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002899 ASSERT_EQ(SSL_get_error(client_.get(),
2900 SSL_write(client_.get(), data, kChunkLen + 1)),
2901 SSL_ERROR_WANT_WRITE);
David Benjamin48063c22017-01-01 23:56:36 -05002902
2903 // Drain the buffer.
2904 char buf[20];
2905 for (unsigned i = 0; i < count; i++) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002906 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
2907 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
David Benjamin48063c22017-01-01 23:56:36 -05002908 }
2909
2910 // Now that there is space, a retry with a larger buffer should flush the
2911 // pending record, skip over that many bytes of input (on assumption they
2912 // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE
2913 // is set, this will complete in two steps.
2914 char data3[] = "_____!";
2915 if (enable_partial_write) {
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002916 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen);
2917 ASSERT_EQ(SSL_write(client_.get(), data3 + kChunkLen, 1), 1);
2918 } else {
2919 ASSERT_EQ(SSL_write(client_.get(), data3, kChunkLen + 1), kChunkLen + 1);
David Benjamin48063c22017-01-01 23:56:36 -05002920 }
2921
2922 // Check the last write was correct. The data will be spread over two
2923 // records, so SSL_read returns twice.
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002924 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
2925 ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
2926 ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), 1);
2927 ASSERT_EQ(buf[0], '!');
David Benjamin48063c22017-01-01 23:56:36 -05002928 }
David Benjamin48063c22017-01-01 23:56:36 -05002929}
2930
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002931TEST_P(SSLVersionTest, RecordCallback) {
2932 for (bool test_server : {true, false}) {
2933 SCOPED_TRACE(test_server);
2934 ResetContexts();
David Benjamin5df5be12017-06-22 19:43:11 -04002935
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002936 bool read_seen = false;
2937 bool write_seen = false;
2938 auto cb = [&](int is_write, int cb_version, int cb_type, const void *buf,
2939 size_t len, SSL *ssl) {
2940 if (cb_type != SSL3_RT_HEADER) {
2941 return;
Martin Kreichgauer72912d22017-08-04 12:06:43 -07002942 }
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002943
2944 // The callback does not report a version for records.
2945 EXPECT_EQ(0, cb_version);
2946
2947 if (is_write) {
2948 write_seen = true;
2949 } else {
2950 read_seen = true;
2951 }
2952
2953 // Sanity-check that the record header is plausible.
2954 CBS cbs;
2955 CBS_init(&cbs, reinterpret_cast<const uint8_t *>(buf), len);
2956 uint8_t type;
2957 uint16_t record_version, length;
2958 ASSERT_TRUE(CBS_get_u8(&cbs, &type));
2959 ASSERT_TRUE(CBS_get_u16(&cbs, &record_version));
Steven Valdez64cc1212017-12-04 11:15:37 -05002960 EXPECT_EQ(record_version & 0xff00, version() & 0xff00);
Martin Kreichgauer1a663262017-08-16 14:54:04 -07002961 if (is_dtls()) {
2962 uint16_t epoch;
2963 ASSERT_TRUE(CBS_get_u16(&cbs, &epoch));
2964 EXPECT_TRUE(epoch == 0 || epoch == 1) << "Invalid epoch: " << epoch;
2965 ASSERT_TRUE(CBS_skip(&cbs, 6));
2966 }
2967 ASSERT_TRUE(CBS_get_u16(&cbs, &length));
2968 EXPECT_EQ(0u, CBS_len(&cbs));
2969 };
2970 using CallbackType = decltype(cb);
2971 SSL_CTX *ctx = test_server ? server_ctx_.get() : client_ctx_.get();
2972 SSL_CTX_set_msg_callback(
2973 ctx, [](int is_write, int cb_version, int cb_type, const void *buf,
2974 size_t len, SSL *ssl, void *arg) {
2975 CallbackType *cb_ptr = reinterpret_cast<CallbackType *>(arg);
2976 (*cb_ptr)(is_write, cb_version, cb_type, buf, len, ssl);
2977 });
2978 SSL_CTX_set_msg_callback_arg(ctx, &cb);
2979
2980 ASSERT_TRUE(Connect());
2981
2982 EXPECT_TRUE(read_seen);
2983 EXPECT_TRUE(write_seen);
David Benjamin0fef3052016-11-18 15:11:10 +09002984 }
David Benjamin9ef31f02016-10-31 18:01:13 -04002985}
2986
David Benjamina8614602017-09-06 15:40:19 -04002987TEST_P(SSLVersionTest, GetServerName) {
David Benjamina8614602017-09-06 15:40:19 -04002988 ClientConfig config;
2989 config.servername = "host1";
2990
2991 SSL_CTX_set_tlsext_servername_callback(
2992 server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
2993 // During the handshake, |SSL_get_servername| must match |config|.
2994 ClientConfig *config_p = reinterpret_cast<ClientConfig *>(arg);
2995 EXPECT_STREQ(config_p->servername.c_str(),
2996 SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name));
2997 return SSL_TLSEXT_ERR_OK;
2998 });
2999 SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), &config);
3000
3001 ASSERT_TRUE(Connect(config));
3002 // After the handshake, it must also be available.
3003 EXPECT_STREQ(config.servername.c_str(),
3004 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3005
3006 // Establish a session under host1.
3007 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3008 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3009 bssl::UniquePtr<SSL_SESSION> session =
3010 CreateClientSession(client_ctx_.get(), server_ctx_.get(), config);
3011
3012 // If the client resumes a session with a different name, |SSL_get_servername|
3013 // must return the new name.
3014 ASSERT_TRUE(session);
3015 config.session = session.get();
3016 config.servername = "host2";
3017 ASSERT_TRUE(Connect(config));
3018 EXPECT_STREQ(config.servername.c_str(),
3019 SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
3020}
3021
David Benjamin3d8f0802017-09-06 16:12:52 -04003022// Test that session cache mode bits are honored in the client session callback.
3023TEST_P(SSLVersionTest, ClientSessionCacheMode) {
3024 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_OFF);
3025 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3026
3027 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_CLIENT);
3028 EXPECT_TRUE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3029
3030 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_SERVER);
3031 EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
3032}
3033
Adam Langleye1e78132017-01-31 15:24:31 -08003034TEST(SSLTest, AddChainCertHack) {
3035 // Ensure that we don't accidently break the hack that we have in place to
3036 // keep curl and serf happy when they use an |X509| even after transfering
3037 // ownership.
3038
3039 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3040 ASSERT_TRUE(ctx);
3041 X509 *cert = GetTestCertificate().release();
3042 ASSERT_TRUE(cert);
3043 SSL_CTX_add0_chain_cert(ctx.get(), cert);
3044
3045 // This should not trigger a use-after-free.
3046 X509_cmp(cert, cert);
3047}
3048
David Benjaminb2ff2622017-02-03 17:06:18 -05003049TEST(SSLTest, GetCertificate) {
3050 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3051 ASSERT_TRUE(ctx);
3052 bssl::UniquePtr<X509> cert = GetTestCertificate();
3053 ASSERT_TRUE(cert);
3054 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
3055 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3056 ASSERT_TRUE(ssl);
3057
3058 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
3059 ASSERT_TRUE(cert2);
3060 X509 *cert3 = SSL_get_certificate(ssl.get());
3061 ASSERT_TRUE(cert3);
3062
3063 // The old and new certificates must be identical.
3064 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
3065 EXPECT_EQ(0, X509_cmp(cert.get(), cert3));
3066
3067 uint8_t *der = nullptr;
3068 long der_len = i2d_X509(cert.get(), &der);
3069 ASSERT_LT(0, der_len);
3070 bssl::UniquePtr<uint8_t> free_der(der);
3071
3072 uint8_t *der2 = nullptr;
3073 long der2_len = i2d_X509(cert2, &der2);
3074 ASSERT_LT(0, der2_len);
3075 bssl::UniquePtr<uint8_t> free_der2(der2);
3076
3077 uint8_t *der3 = nullptr;
3078 long der3_len = i2d_X509(cert3, &der3);
3079 ASSERT_LT(0, der3_len);
3080 bssl::UniquePtr<uint8_t> free_der3(der3);
3081
3082 // They must also encode identically.
David Benjamin7d7554b2017-02-04 11:48:59 -05003083 EXPECT_EQ(Bytes(der, der_len), Bytes(der2, der2_len));
3084 EXPECT_EQ(Bytes(der, der_len), Bytes(der3, der3_len));
David Benjaminb2ff2622017-02-03 17:06:18 -05003085}
3086
Adam Langleyd04ca952017-02-28 11:26:51 -08003087TEST(SSLTest, SetChainAndKeyMismatch) {
3088 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_with_buffers_method()));
3089 ASSERT_TRUE(ctx);
3090
3091 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3092 ASSERT_TRUE(key);
3093 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3094 ASSERT_TRUE(leaf);
3095 std::vector<CRYPTO_BUFFER*> chain = {
3096 leaf.get(),
3097 };
3098
3099 // Should fail because |GetTestKey| doesn't match the chain-test certificate.
3100 ASSERT_FALSE(SSL_CTX_set_chain_and_key(ctx.get(), &chain[0], chain.size(),
3101 key.get(), nullptr));
3102 ERR_clear_error();
3103}
3104
3105TEST(SSLTest, SetChainAndKey) {
3106 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3107 ASSERT_TRUE(client_ctx);
3108 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3109 ASSERT_TRUE(server_ctx);
3110
3111 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3112 ASSERT_TRUE(key);
3113 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3114 ASSERT_TRUE(leaf);
3115 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3116 GetChainTestIntermediateBuffer();
3117 ASSERT_TRUE(intermediate);
3118 std::vector<CRYPTO_BUFFER*> chain = {
3119 leaf.get(), intermediate.get(),
3120 };
3121 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3122 chain.size(), key.get(), nullptr));
3123
David Benjamin3a1dd462017-07-11 16:13:10 -04003124 SSL_CTX_set_custom_verify(
3125 client_ctx.get(), SSL_VERIFY_PEER,
3126 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3127 return ssl_verify_ok;
3128 });
Adam Langleyd04ca952017-02-28 11:26:51 -08003129
3130 bssl::UniquePtr<SSL> client, server;
3131 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003132 server_ctx.get()));
Adam Langleyd04ca952017-02-28 11:26:51 -08003133}
3134
Matthew Braithwaite5301c102018-01-23 12:08:55 -08003135TEST(SSLTest, BuffersFailWithoutCustomVerify) {
3136 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3137 ASSERT_TRUE(client_ctx);
3138 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3139 ASSERT_TRUE(server_ctx);
3140
3141 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3142 ASSERT_TRUE(key);
3143 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3144 ASSERT_TRUE(leaf);
3145 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
3146 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3147 chain.size(), key.get(), nullptr));
3148
3149 // Without SSL_CTX_set_custom_verify(), i.e. with everything in the default
3150 // configuration, certificate verification should fail.
3151 bssl::UniquePtr<SSL> client, server;
3152 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3153 server_ctx.get()));
3154
3155 // Whereas with a verifier, the connection should succeed.
3156 SSL_CTX_set_custom_verify(
3157 client_ctx.get(), SSL_VERIFY_PEER,
3158 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3159 return ssl_verify_ok;
3160 });
3161 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3162 server_ctx.get()));
3163}
3164
3165TEST(SSLTest, CustomVerify) {
3166 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3167 ASSERT_TRUE(client_ctx);
3168 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3169 ASSERT_TRUE(server_ctx);
3170
3171 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3172 ASSERT_TRUE(key);
3173 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3174 ASSERT_TRUE(leaf);
3175 std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
3176 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3177 chain.size(), key.get(), nullptr));
3178
3179 SSL_CTX_set_custom_verify(
3180 client_ctx.get(), SSL_VERIFY_PEER,
3181 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3182 return ssl_verify_ok;
3183 });
3184
3185 bssl::UniquePtr<SSL> client, server;
3186 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3187 server_ctx.get()));
3188
3189 // With SSL_VERIFY_PEER, ssl_verify_invalid should result in a dropped
3190 // connection.
3191 SSL_CTX_set_custom_verify(
3192 client_ctx.get(), SSL_VERIFY_PEER,
3193 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3194 return ssl_verify_invalid;
3195 });
3196
3197 ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3198 server_ctx.get()));
3199
3200 // But with SSL_VERIFY_NONE, ssl_verify_invalid should not cause a dropped
3201 // connection.
3202 SSL_CTX_set_custom_verify(
3203 client_ctx.get(), SSL_VERIFY_NONE,
3204 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3205 return ssl_verify_invalid;
3206 });
3207
3208 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3209 server_ctx.get()));
3210}
3211
David Benjamin71dfad42017-07-16 17:27:39 -04003212TEST(SSLTest, ClientCABuffers) {
3213 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3214 ASSERT_TRUE(client_ctx);
3215 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3216 ASSERT_TRUE(server_ctx);
3217
3218 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3219 ASSERT_TRUE(key);
3220 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3221 ASSERT_TRUE(leaf);
3222 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3223 GetChainTestIntermediateBuffer();
3224 ASSERT_TRUE(intermediate);
3225 std::vector<CRYPTO_BUFFER *> chain = {
3226 leaf.get(),
3227 intermediate.get(),
3228 };
3229 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3230 chain.size(), key.get(), nullptr));
3231
3232 bssl::UniquePtr<CRYPTO_BUFFER> ca_name(
3233 CRYPTO_BUFFER_new(kTestName, sizeof(kTestName), nullptr));
3234 ASSERT_TRUE(ca_name);
3235 bssl::UniquePtr<STACK_OF(CRYPTO_BUFFER)> ca_names(
3236 sk_CRYPTO_BUFFER_new_null());
3237 ASSERT_TRUE(ca_names);
3238 ASSERT_TRUE(sk_CRYPTO_BUFFER_push(ca_names.get(), ca_name.get()));
3239 ca_name.release();
3240 SSL_CTX_set0_client_CAs(server_ctx.get(), ca_names.release());
3241
3242 // Configure client and server to accept all certificates.
3243 SSL_CTX_set_custom_verify(
3244 client_ctx.get(), SSL_VERIFY_PEER,
3245 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3246 return ssl_verify_ok;
3247 });
3248 SSL_CTX_set_custom_verify(
3249 server_ctx.get(), SSL_VERIFY_PEER,
3250 [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
3251 return ssl_verify_ok;
3252 });
3253
3254 bool cert_cb_called = false;
3255 SSL_CTX_set_cert_cb(
3256 client_ctx.get(),
3257 [](SSL *ssl, void *arg) -> int {
David Benjamin5f001d12018-05-08 16:46:48 -04003258 const STACK_OF(CRYPTO_BUFFER) *peer_names =
David Benjamin71dfad42017-07-16 17:27:39 -04003259 SSL_get0_server_requested_CAs(ssl);
3260 EXPECT_EQ(1u, sk_CRYPTO_BUFFER_num(peer_names));
3261 CRYPTO_BUFFER *peer_name = sk_CRYPTO_BUFFER_value(peer_names, 0);
3262 EXPECT_EQ(Bytes(kTestName), Bytes(CRYPTO_BUFFER_data(peer_name),
3263 CRYPTO_BUFFER_len(peer_name)));
3264 *reinterpret_cast<bool *>(arg) = true;
3265 return 1;
3266 },
3267 &cert_cb_called);
3268
3269 bssl::UniquePtr<SSL> client, server;
3270 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003271 server_ctx.get()));
David Benjamin71dfad42017-07-16 17:27:39 -04003272 EXPECT_TRUE(cert_cb_called);
3273}
3274
David Benjamin91222b82017-03-09 20:10:56 -05003275// Configuring the empty cipher list, though an error, should still modify the
3276// configuration.
3277TEST(SSLTest, EmptyCipherList) {
3278 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3279 ASSERT_TRUE(ctx);
3280
3281 // Initially, the cipher list is not empty.
3282 EXPECT_NE(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3283
3284 // Configuring the empty cipher list fails.
3285 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), ""));
3286 ERR_clear_error();
3287
3288 // But the cipher list is still updated to empty.
3289 EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3290}
3291
Adam Langley4c341d02017-03-08 19:33:21 -08003292// ssl_test_ticket_aead_failure_mode enumerates the possible ways in which the
3293// test |SSL_TICKET_AEAD_METHOD| can fail.
3294enum ssl_test_ticket_aead_failure_mode {
3295 ssl_test_ticket_aead_ok = 0,
3296 ssl_test_ticket_aead_seal_fail,
3297 ssl_test_ticket_aead_open_soft_fail,
3298 ssl_test_ticket_aead_open_hard_fail,
3299};
3300
3301struct ssl_test_ticket_aead_state {
3302 unsigned retry_count;
3303 ssl_test_ticket_aead_failure_mode failure_mode;
3304};
3305
3306static int ssl_test_ticket_aead_ex_index_dup(CRYPTO_EX_DATA *to,
3307 const CRYPTO_EX_DATA *from,
3308 void **from_d, int index,
3309 long argl, void *argp) {
3310 abort();
3311}
3312
3313static void ssl_test_ticket_aead_ex_index_free(void *parent, void *ptr,
3314 CRYPTO_EX_DATA *ad, int index,
3315 long argl, void *argp) {
3316 auto state = reinterpret_cast<ssl_test_ticket_aead_state*>(ptr);
3317 if (state == nullptr) {
3318 return;
3319 }
3320
3321 OPENSSL_free(state);
3322}
3323
3324static CRYPTO_once_t g_ssl_test_ticket_aead_ex_index_once = CRYPTO_ONCE_INIT;
3325static int g_ssl_test_ticket_aead_ex_index;
3326
3327static int ssl_test_ticket_aead_get_ex_index() {
3328 CRYPTO_once(&g_ssl_test_ticket_aead_ex_index_once, [] {
3329 g_ssl_test_ticket_aead_ex_index = SSL_get_ex_new_index(
3330 0, nullptr, nullptr, ssl_test_ticket_aead_ex_index_dup,
3331 ssl_test_ticket_aead_ex_index_free);
3332 });
3333 return g_ssl_test_ticket_aead_ex_index;
3334}
3335
3336static size_t ssl_test_ticket_aead_max_overhead(SSL *ssl) {
3337 return 1;
3338}
3339
3340static int ssl_test_ticket_aead_seal(SSL *ssl, uint8_t *out, size_t *out_len,
3341 size_t max_out_len, const uint8_t *in,
3342 size_t in_len) {
3343 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3344 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3345
3346 if (state->failure_mode == ssl_test_ticket_aead_seal_fail ||
3347 max_out_len < in_len + 1) {
3348 return 0;
3349 }
3350
3351 OPENSSL_memmove(out, in, in_len);
3352 out[in_len] = 0xff;
3353 *out_len = in_len + 1;
3354
3355 return 1;
3356}
3357
3358static ssl_ticket_aead_result_t ssl_test_ticket_aead_open(
3359 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len,
3360 const uint8_t *in, size_t in_len) {
3361 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3362 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3363
3364 if (state->retry_count > 0) {
3365 state->retry_count--;
3366 return ssl_ticket_aead_retry;
3367 }
3368
3369 switch (state->failure_mode) {
3370 case ssl_test_ticket_aead_ok:
3371 break;
3372 case ssl_test_ticket_aead_seal_fail:
3373 // If |seal| failed then there shouldn't be any ticket to try and
3374 // decrypt.
3375 abort();
3376 break;
3377 case ssl_test_ticket_aead_open_soft_fail:
3378 return ssl_ticket_aead_ignore_ticket;
3379 case ssl_test_ticket_aead_open_hard_fail:
3380 return ssl_ticket_aead_error;
3381 }
3382
3383 if (in_len == 0 || in[in_len - 1] != 0xff) {
3384 return ssl_ticket_aead_ignore_ticket;
3385 }
3386
3387 if (max_out_len < in_len - 1) {
3388 return ssl_ticket_aead_error;
3389 }
3390
3391 OPENSSL_memmove(out, in, in_len - 1);
3392 *out_len = in_len - 1;
3393 return ssl_ticket_aead_success;
3394}
3395
3396static const SSL_TICKET_AEAD_METHOD kSSLTestTicketMethod = {
3397 ssl_test_ticket_aead_max_overhead,
3398 ssl_test_ticket_aead_seal,
3399 ssl_test_ticket_aead_open,
3400};
3401
3402static void ConnectClientAndServerWithTicketMethod(
3403 bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
3404 SSL_CTX *client_ctx, SSL_CTX *server_ctx, unsigned retry_count,
3405 ssl_test_ticket_aead_failure_mode failure_mode, SSL_SESSION *session) {
3406 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
3407 ASSERT_TRUE(client);
3408 ASSERT_TRUE(server);
3409 SSL_set_connect_state(client.get());
3410 SSL_set_accept_state(server.get());
3411
3412 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3413 OPENSSL_malloc(sizeof(ssl_test_ticket_aead_state)));
3414 ASSERT_TRUE(state);
3415 OPENSSL_memset(state, 0, sizeof(ssl_test_ticket_aead_state));
3416 state->retry_count = retry_count;
3417 state->failure_mode = failure_mode;
3418
3419 ASSERT_TRUE(SSL_set_ex_data(server.get(), ssl_test_ticket_aead_get_ex_index(),
3420 state));
3421
3422 SSL_set_session(client.get(), session);
3423
3424 BIO *bio1, *bio2;
3425 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
3426
3427 // SSL_set_bio takes ownership.
3428 SSL_set_bio(client.get(), bio1, bio1);
3429 SSL_set_bio(server.get(), bio2, bio2);
3430
3431 if (CompleteHandshakes(client.get(), server.get())) {
3432 *out_client = std::move(client);
3433 *out_server = std::move(server);
3434 } else {
3435 out_client->reset();
3436 out_server->reset();
3437 }
3438}
3439
David Benjaminc9775322018-04-13 16:39:12 -04003440using TicketAEADMethodParam =
3441 testing::tuple<uint16_t, unsigned, ssl_test_ticket_aead_failure_mode>;
3442
Adam Langley4c341d02017-03-08 19:33:21 -08003443class TicketAEADMethodTest
David Benjaminc9775322018-04-13 16:39:12 -04003444 : public ::testing::TestWithParam<TicketAEADMethodParam> {};
Adam Langley4c341d02017-03-08 19:33:21 -08003445
3446TEST_P(TicketAEADMethodTest, Resume) {
3447 bssl::UniquePtr<X509> cert = GetTestCertificate();
3448 ASSERT_TRUE(cert);
3449 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3450 ASSERT_TRUE(key);
3451
3452 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
3453 ASSERT_TRUE(server_ctx);
3454 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
3455 ASSERT_TRUE(client_ctx);
3456
3457 const uint16_t version = testing::get<0>(GetParam());
3458 const unsigned retry_count = testing::get<1>(GetParam());
3459 const ssl_test_ticket_aead_failure_mode failure_mode =
3460 testing::get<2>(GetParam());
3461
3462 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3463 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3464 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), version));
3465 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), version));
3466 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), version));
3467 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), version));
3468
3469 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
3470 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
3471 SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
3472 SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
David Benjamin707af292017-03-10 17:47:18 -05003473 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langley4c341d02017-03-08 19:33:21 -08003474
3475 SSL_CTX_set_ticket_aead_method(server_ctx.get(), &kSSLTestTicketMethod);
3476
3477 bssl::UniquePtr<SSL> client, server;
3478 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3479 server_ctx.get(), retry_count,
3480 failure_mode, nullptr);
3481 switch (failure_mode) {
3482 case ssl_test_ticket_aead_ok:
3483 case ssl_test_ticket_aead_open_hard_fail:
3484 case ssl_test_ticket_aead_open_soft_fail:
3485 ASSERT_TRUE(client);
3486 break;
3487 case ssl_test_ticket_aead_seal_fail:
3488 EXPECT_FALSE(client);
3489 return;
3490 }
3491 EXPECT_FALSE(SSL_session_reused(client.get()));
3492 EXPECT_FALSE(SSL_session_reused(server.get()));
3493
David Benjamin707af292017-03-10 17:47:18 -05003494 // Run the read loop to account for post-handshake tickets in TLS 1.3.
3495 SSL_read(client.get(), nullptr, 0);
3496
3497 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
Adam Langley4c341d02017-03-08 19:33:21 -08003498 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3499 server_ctx.get(), retry_count,
David Benjamin707af292017-03-10 17:47:18 -05003500 failure_mode, session.get());
Adam Langley4c341d02017-03-08 19:33:21 -08003501 switch (failure_mode) {
3502 case ssl_test_ticket_aead_ok:
3503 ASSERT_TRUE(client);
3504 EXPECT_TRUE(SSL_session_reused(client.get()));
3505 EXPECT_TRUE(SSL_session_reused(server.get()));
3506 break;
3507 case ssl_test_ticket_aead_seal_fail:
3508 abort();
3509 break;
3510 case ssl_test_ticket_aead_open_hard_fail:
3511 EXPECT_FALSE(client);
3512 break;
3513 case ssl_test_ticket_aead_open_soft_fail:
3514 ASSERT_TRUE(client);
3515 EXPECT_FALSE(SSL_session_reused(client.get()));
3516 EXPECT_FALSE(SSL_session_reused(server.get()));
3517 }
3518}
3519
David Benjaminc9775322018-04-13 16:39:12 -04003520std::string TicketAEADMethodParamToString(
3521 const testing::TestParamInfo<TicketAEADMethodParam> &params) {
3522 std::string ret = GetVersionName(std::get<0>(params.param));
3523 // GTest only allows alphanumeric characters and '_' in the parameter
3524 // string. Additionally filter out the 'v' to get "TLS13" over "TLSv13".
3525 for (auto it = ret.begin(); it != ret.end();) {
3526 if (*it == '.' || *it == 'v') {
3527 it = ret.erase(it);
3528 } else {
3529 ++it;
3530 }
3531 }
3532 char retry_count[256];
3533 snprintf(retry_count, sizeof(retry_count), "%d", std::get<1>(params.param));
3534 ret += "_";
3535 ret += retry_count;
3536 ret += "Retries_";
3537 switch (std::get<2>(params.param)) {
3538 case ssl_test_ticket_aead_ok:
3539 ret += "OK";
3540 break;
3541 case ssl_test_ticket_aead_seal_fail:
3542 ret += "SealFail";
3543 break;
3544 case ssl_test_ticket_aead_open_soft_fail:
3545 ret += "OpenSoftFail";
3546 break;
3547 case ssl_test_ticket_aead_open_hard_fail:
3548 ret += "OpenHardFail";
3549 break;
3550 }
3551 return ret;
3552}
3553
Adam Langley4c341d02017-03-08 19:33:21 -08003554INSTANTIATE_TEST_CASE_P(
3555 TicketAEADMethodTests, TicketAEADMethodTest,
David Benjaminc9775322018-04-13 16:39:12 -04003556 testing::Combine(testing::Values(TLS1_2_VERSION, TLS1_3_VERSION),
3557 testing::Values(0, 1, 2),
3558 testing::Values(ssl_test_ticket_aead_ok,
3559 ssl_test_ticket_aead_seal_fail,
3560 ssl_test_ticket_aead_open_soft_fail,
3561 ssl_test_ticket_aead_open_hard_fail)),
3562 TicketAEADMethodParamToString);
Adam Langley4c341d02017-03-08 19:33:21 -08003563
David Benjaminca743582017-06-15 17:51:35 -04003564TEST(SSLTest, SelectNextProto) {
3565 uint8_t *result;
3566 uint8_t result_len;
3567
3568 // If there is an overlap, it should be returned.
3569 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3570 SSL_select_next_proto(&result, &result_len,
3571 (const uint8_t *)"\1a\2bb\3ccc", 9,
3572 (const uint8_t *)"\1x\1y\1a\1z", 8));
3573 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
3574
3575 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3576 SSL_select_next_proto(&result, &result_len,
3577 (const uint8_t *)"\1a\2bb\3ccc", 9,
3578 (const uint8_t *)"\1x\1y\2bb\1z", 9));
3579 EXPECT_EQ(Bytes("bb"), Bytes(result, result_len));
3580
3581 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3582 SSL_select_next_proto(&result, &result_len,
3583 (const uint8_t *)"\1a\2bb\3ccc", 9,
3584 (const uint8_t *)"\1x\1y\3ccc\1z", 10));
3585 EXPECT_EQ(Bytes("ccc"), Bytes(result, result_len));
3586
3587 // Peer preference order takes precedence over local.
3588 EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
3589 SSL_select_next_proto(&result, &result_len,
3590 (const uint8_t *)"\1a\2bb\3ccc", 9,
3591 (const uint8_t *)"\3ccc\2bb\1a", 9));
3592 EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
3593
3594 // If there is no overlap, return the first local protocol.
3595 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
3596 SSL_select_next_proto(&result, &result_len,
3597 (const uint8_t *)"\1a\2bb\3ccc", 9,
3598 (const uint8_t *)"\1x\2yy\3zzz", 9));
3599 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
3600
3601 EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
3602 SSL_select_next_proto(&result, &result_len, nullptr, 0,
3603 (const uint8_t *)"\1x\2yy\3zzz", 9));
3604 EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
3605}
3606
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003607TEST(SSLTest, SealRecord) {
3608 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3609 server_ctx(SSL_CTX_new(TLS_method()));
3610 ASSERT_TRUE(client_ctx);
3611 ASSERT_TRUE(server_ctx);
3612
3613 bssl::UniquePtr<X509> cert = GetTestCertificate();
3614 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3615 ASSERT_TRUE(cert);
3616 ASSERT_TRUE(key);
3617 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3618 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3619
3620 bssl::UniquePtr<SSL> client, server;
3621 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003622 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003623
3624 const std::vector<uint8_t> record = {1, 2, 3, 4, 5};
3625 std::vector<uint8_t> prefix(
3626 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003627 body(record.size()),
3628 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003629 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3630 bssl::MakeSpan(body), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003631 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003632
3633 std::vector<uint8_t> sealed;
3634 sealed.insert(sealed.end(), prefix.begin(), prefix.end());
3635 sealed.insert(sealed.end(), body.begin(), body.end());
3636 sealed.insert(sealed.end(), suffix.begin(), suffix.end());
3637 std::vector<uint8_t> sealed_copy = sealed;
3638
3639 bssl::Span<uint8_t> plaintext;
3640 size_t record_len;
3641 uint8_t alert = 255;
3642 EXPECT_EQ(bssl::OpenRecord(server.get(), &plaintext, &record_len, &alert,
3643 bssl::MakeSpan(sealed)),
3644 bssl::OpenRecordResult::kOK);
3645 EXPECT_EQ(record_len, sealed.size());
3646 EXPECT_EQ(plaintext, record);
3647 EXPECT_EQ(255, alert);
3648}
3649
3650TEST(SSLTest, SealRecordInPlace) {
3651 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3652 server_ctx(SSL_CTX_new(TLS_method()));
3653 ASSERT_TRUE(client_ctx);
3654 ASSERT_TRUE(server_ctx);
3655
3656 bssl::UniquePtr<X509> cert = GetTestCertificate();
3657 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3658 ASSERT_TRUE(cert);
3659 ASSERT_TRUE(key);
3660 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3661 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3662
3663 bssl::UniquePtr<SSL> client, server;
3664 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003665 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003666
3667 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
3668 std::vector<uint8_t> record = plaintext;
3669 std::vector<uint8_t> prefix(
3670 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003671 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003672 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3673 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003674 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003675 record.insert(record.begin(), prefix.begin(), prefix.end());
3676 record.insert(record.end(), suffix.begin(), suffix.end());
3677
3678 bssl::Span<uint8_t> result;
3679 size_t record_len;
3680 uint8_t alert;
3681 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
3682 bssl::MakeSpan(record)),
3683 bssl::OpenRecordResult::kOK);
3684 EXPECT_EQ(record_len, record.size());
3685 EXPECT_EQ(plaintext, result);
3686}
3687
3688TEST(SSLTest, SealRecordTrailingData) {
3689 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3690 server_ctx(SSL_CTX_new(TLS_method()));
3691 ASSERT_TRUE(client_ctx);
3692 ASSERT_TRUE(server_ctx);
3693
3694 bssl::UniquePtr<X509> cert = GetTestCertificate();
3695 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3696 ASSERT_TRUE(cert);
3697 ASSERT_TRUE(key);
3698 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3699 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3700
3701 bssl::UniquePtr<SSL> client, server;
3702 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003703 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003704
3705 const std::vector<uint8_t> plaintext = {1, 2, 3, 4, 5};
3706 std::vector<uint8_t> record = plaintext;
3707 std::vector<uint8_t> prefix(
3708 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003709 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003710 ASSERT_TRUE(bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3711 bssl::MakeSpan(record), bssl::MakeSpan(suffix),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003712 record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003713 record.insert(record.begin(), prefix.begin(), prefix.end());
3714 record.insert(record.end(), suffix.begin(), suffix.end());
3715 record.insert(record.end(), {5, 4, 3, 2, 1});
3716
3717 bssl::Span<uint8_t> result;
3718 size_t record_len;
3719 uint8_t alert;
3720 EXPECT_EQ(bssl::OpenRecord(server.get(), &result, &record_len, &alert,
3721 bssl::MakeSpan(record)),
3722 bssl::OpenRecordResult::kOK);
3723 EXPECT_EQ(record_len, record.size() - 5);
3724 EXPECT_EQ(plaintext, result);
3725}
3726
3727TEST(SSLTest, SealRecordInvalidSpanSize) {
3728 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method())),
3729 server_ctx(SSL_CTX_new(TLS_method()));
3730 ASSERT_TRUE(client_ctx);
3731 ASSERT_TRUE(server_ctx);
3732
3733 bssl::UniquePtr<X509> cert = GetTestCertificate();
3734 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3735 ASSERT_TRUE(cert);
3736 ASSERT_TRUE(key);
3737 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3738 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3739
3740 bssl::UniquePtr<SSL> client, server;
3741 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina8614602017-09-06 15:40:19 -04003742 server_ctx.get()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003743
3744 std::vector<uint8_t> record = {1, 2, 3, 4, 5};
3745 std::vector<uint8_t> prefix(
3746 bssl::SealRecordPrefixLen(client.get(), record.size())),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003747 body(record.size()),
3748 suffix(bssl::SealRecordSuffixLen(client.get(), record.size()));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003749
3750 auto expect_err = []() {
3751 int err = ERR_get_error();
3752 EXPECT_EQ(ERR_GET_LIB(err), ERR_LIB_SSL);
3753 EXPECT_EQ(ERR_GET_REASON(err), SSL_R_BUFFER_TOO_SMALL);
3754 ERR_clear_error();
3755 };
3756 EXPECT_FALSE(bssl::SealRecord(
3757 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003758 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003759 expect_err();
3760 EXPECT_FALSE(bssl::SealRecord(
3761 client.get(), bssl::MakeSpan(prefix.data(), prefix.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003762 bssl::MakeSpan(record), bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003763 expect_err();
3764
3765 EXPECT_FALSE(
3766 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3767 bssl::MakeSpan(record.data(), record.size() - 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003768 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003769 expect_err();
3770 EXPECT_FALSE(
3771 bssl::SealRecord(client.get(), bssl::MakeSpan(prefix),
3772 bssl::MakeSpan(record.data(), record.size() + 1),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003773 bssl::MakeSpan(suffix), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003774 expect_err();
3775
3776 EXPECT_FALSE(bssl::SealRecord(
3777 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003778 bssl::MakeSpan(suffix.data(), suffix.size() - 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003779 expect_err();
3780 EXPECT_FALSE(bssl::SealRecord(
3781 client.get(), bssl::MakeSpan(prefix), bssl::MakeSpan(record),
Martin Kreichgauerabbf3652017-07-21 16:27:54 -07003782 bssl::MakeSpan(suffix.data(), suffix.size() + 1), record));
Martin Kreichgauer17c30572017-07-18 12:42:18 -07003783 expect_err();
3784}
3785
David Benjamin617b8182017-08-29 15:33:10 -04003786// The client should gracefully handle no suitable ciphers being enabled.
3787TEST(SSLTest, NoCiphersAvailable) {
3788 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3789 ASSERT_TRUE(ctx);
3790
3791 // Configure |client_ctx| with a cipher list that does not intersect with its
3792 // version configuration.
3793 ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
3794 ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
3795 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
3796
3797 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3798 ASSERT_TRUE(ssl);
3799 SSL_set_connect_state(ssl.get());
3800
3801 UniquePtr<BIO> rbio(BIO_new(BIO_s_mem())), wbio(BIO_new(BIO_s_mem()));
3802 ASSERT_TRUE(rbio);
3803 ASSERT_TRUE(wbio);
3804 SSL_set0_rbio(ssl.get(), rbio.release());
3805 SSL_set0_wbio(ssl.get(), wbio.release());
3806
3807 int ret = SSL_do_handshake(ssl.get());
3808 EXPECT_EQ(-1, ret);
3809 EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), ret));
3810 uint32_t err = ERR_get_error();
3811 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
3812 EXPECT_EQ(SSL_R_NO_CIPHERS_AVAILABLE, ERR_GET_REASON(err));
3813}
3814
David Benjamina4bafd32017-10-03 15:06:29 -04003815TEST_P(SSLVersionTest, SessionVersion) {
3816 SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3817 SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3818
3819 bssl::UniquePtr<SSL_SESSION> session =
3820 CreateClientSession(client_ctx_.get(), server_ctx_.get());
3821 ASSERT_TRUE(session);
3822 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
3823
3824 // Sessions in TLS 1.3 and later should be single-use.
3825 EXPECT_EQ(version() == TLS1_3_VERSION,
3826 !!SSL_SESSION_should_be_single_use(session.get()));
3827
3828 // Making fake sessions for testing works.
3829 session.reset(SSL_SESSION_new(client_ctx_.get()));
3830 ASSERT_TRUE(session);
3831 ASSERT_TRUE(SSL_SESSION_set_protocol_version(session.get(), version()));
3832 EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
3833}
3834
David Benjaminfdb7a352017-10-12 17:34:18 -04003835TEST_P(SSLVersionTest, SSLPending) {
3836 UniquePtr<SSL> ssl(SSL_new(client_ctx_.get()));
3837 ASSERT_TRUE(ssl);
3838 EXPECT_EQ(0, SSL_pending(ssl.get()));
3839
3840 ASSERT_TRUE(Connect());
3841 EXPECT_EQ(0, SSL_pending(client_.get()));
3842
3843 ASSERT_EQ(5, SSL_write(server_.get(), "hello", 5));
3844 ASSERT_EQ(5, SSL_write(server_.get(), "world", 5));
3845 EXPECT_EQ(0, SSL_pending(client_.get()));
3846
3847 char buf[10];
3848 ASSERT_EQ(1, SSL_peek(client_.get(), buf, 1));
3849 EXPECT_EQ(5, SSL_pending(client_.get()));
3850
3851 ASSERT_EQ(1, SSL_read(client_.get(), buf, 1));
3852 EXPECT_EQ(4, SSL_pending(client_.get()));
3853
3854 ASSERT_EQ(4, SSL_read(client_.get(), buf, 10));
3855 EXPECT_EQ(0, SSL_pending(client_.get()));
3856
3857 ASSERT_EQ(2, SSL_read(client_.get(), buf, 2));
3858 EXPECT_EQ(3, SSL_pending(client_.get()));
3859}
3860
David Benjamina031b612017-10-11 20:48:25 -04003861// Test that post-handshake tickets consumed by |SSL_shutdown| are ignored.
3862TEST(SSLTest, ShutdownIgnoresTickets) {
3863 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3864 ASSERT_TRUE(ctx);
3865 ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_3_VERSION));
3866 ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
3867
3868 bssl::UniquePtr<X509> cert = GetTestCertificate();
3869 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3870 ASSERT_TRUE(cert);
3871 ASSERT_TRUE(key);
3872 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
3873 ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
3874
3875 SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_BOTH);
3876
3877 bssl::UniquePtr<SSL> client, server;
3878 ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
3879
3880 SSL_CTX_sess_set_new_cb(ctx.get(), [](SSL *ssl, SSL_SESSION *session) -> int {
3881 ADD_FAILURE() << "New session callback called during SSL_shutdown";
3882 return 0;
3883 });
3884
3885 // Send close_notify.
3886 EXPECT_EQ(0, SSL_shutdown(server.get()));
3887 EXPECT_EQ(0, SSL_shutdown(client.get()));
3888
3889 // Receive close_notify.
3890 EXPECT_EQ(1, SSL_shutdown(server.get()));
3891 EXPECT_EQ(1, SSL_shutdown(client.get()));
3892}
3893
David Benjamin6cc352e2017-11-02 17:21:39 -04003894TEST(SSLTest, SignatureAlgorithmProperties) {
3895 EXPECT_EQ(EVP_PKEY_NONE, SSL_get_signature_algorithm_key_type(0x1234));
3896 EXPECT_EQ(nullptr, SSL_get_signature_algorithm_digest(0x1234));
3897 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(0x1234));
3898
3899 EXPECT_EQ(EVP_PKEY_RSA,
3900 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
3901 EXPECT_EQ(EVP_md5_sha1(),
3902 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
3903 EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
3904
3905 EXPECT_EQ(EVP_PKEY_EC, SSL_get_signature_algorithm_key_type(
3906 SSL_SIGN_ECDSA_SECP256R1_SHA256));
3907 EXPECT_EQ(EVP_sha256(), SSL_get_signature_algorithm_digest(
3908 SSL_SIGN_ECDSA_SECP256R1_SHA256));
3909 EXPECT_FALSE(
3910 SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_ECDSA_SECP256R1_SHA256));
3911
3912 EXPECT_EQ(EVP_PKEY_RSA,
David Benjamin6879e192018-04-13 16:01:02 -04003913 SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04003914 EXPECT_EQ(EVP_sha384(),
David Benjamin6879e192018-04-13 16:01:02 -04003915 SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PSS_RSAE_SHA384));
3916 EXPECT_TRUE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PSS_RSAE_SHA384));
David Benjamin6cc352e2017-11-02 17:21:39 -04003917}
3918
Adam Langley0080d832018-06-07 16:39:49 -07003919static bool XORCompressFunc(SSL *ssl, CBB *out, Span<const uint8_t> in) {
3920 for (size_t i = 0; i < in.size(); i++) {
3921 if (!CBB_add_u8(out, in[i] ^ 0x55)) {
3922 return false;
3923 }
3924 }
3925
3926 SSL_set_app_data(ssl, XORCompressFunc);
3927
3928 return true;
3929}
3930
3931static bool XORDecompressFunc(SSL *ssl, bssl::UniquePtr<CRYPTO_BUFFER> *out,
3932 size_t uncompressed_len, Span<const uint8_t> in) {
3933 if (in.size() != uncompressed_len) {
3934 return false;
3935 }
3936
3937 uint8_t *data;
3938 out->reset(CRYPTO_BUFFER_alloc(&data, uncompressed_len));
3939 if (out->get() == nullptr) {
3940 return false;
3941 }
3942
3943 for (size_t i = 0; i < in.size(); i++) {
3944 data[i] = in[i] ^ 0x55;
3945 }
3946
3947 SSL_set_app_data(ssl, XORDecompressFunc);
3948
3949 return true;
3950}
3951
3952TEST(SSLTest, CertCompression) {
3953 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
3954 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
3955 ASSERT_TRUE(client_ctx);
3956 ASSERT_TRUE(server_ctx);
3957
3958 bssl::UniquePtr<X509> cert = GetTestCertificate();
3959 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3960 ASSERT_TRUE(cert);
3961 ASSERT_TRUE(key);
3962 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3963 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3964
3965 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
3966 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
3967 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
3968 client_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
3969 ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
3970 server_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
3971
3972 bssl::UniquePtr<SSL> client, server;
3973 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3974 server_ctx.get()));
3975
3976 EXPECT_TRUE(SSL_get_app_data(client.get()) == XORDecompressFunc);
3977 EXPECT_TRUE(SSL_get_app_data(server.get()) == XORCompressFunc);
3978}
3979
Adam Langleyddb57cf2018-01-26 09:17:53 -08003980void MoveBIOs(SSL *dest, SSL *src) {
3981 BIO *rbio = SSL_get_rbio(src);
3982 BIO_up_ref(rbio);
3983 SSL_set0_rbio(dest, rbio);
3984
3985 BIO *wbio = SSL_get_wbio(src);
3986 BIO_up_ref(wbio);
3987 SSL_set0_wbio(dest, wbio);
3988
3989 SSL_set0_rbio(src, nullptr);
3990 SSL_set0_wbio(src, nullptr);
3991}
3992
3993TEST(SSLTest, Handoff) {
3994 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
3995 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
3996 bssl::UniquePtr<SSL_CTX> handshaker_ctx(SSL_CTX_new(TLS_method()));
3997 ASSERT_TRUE(client_ctx);
3998 ASSERT_TRUE(server_ctx);
3999 ASSERT_TRUE(handshaker_ctx);
4000
4001 SSL_CTX_set_handoff_mode(server_ctx.get(), 1);
4002 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
4003 ASSERT_TRUE(
4004 SSL_CTX_set_max_proto_version(handshaker_ctx.get(), TLS1_2_VERSION));
4005
4006 bssl::UniquePtr<X509> cert = GetTestCertificate();
4007 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4008 ASSERT_TRUE(cert);
4009 ASSERT_TRUE(key);
4010 ASSERT_TRUE(SSL_CTX_use_certificate(handshaker_ctx.get(), cert.get()));
4011 ASSERT_TRUE(SSL_CTX_use_PrivateKey(handshaker_ctx.get(), key.get()));
4012
4013 bssl::UniquePtr<SSL> client, server;
4014 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4015 server_ctx.get(), ClientConfig(),
4016 false /* don't handshake */));
4017
4018 int client_ret = SSL_do_handshake(client.get());
4019 int client_err = SSL_get_error(client.get(), client_ret);
4020 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4021
4022 int server_ret = SSL_do_handshake(server.get());
4023 int server_err = SSL_get_error(server.get(), server_ret);
4024 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
4025
4026 ScopedCBB cbb;
4027 Array<uint8_t> handoff;
4028 ASSERT_TRUE(CBB_init(cbb.get(), 256));
4029 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get()));
4030 ASSERT_TRUE(CBBFinishArray(cbb.get(), &handoff));
4031
4032 bssl::UniquePtr<SSL> handshaker(SSL_new(handshaker_ctx.get()));
4033 ASSERT_TRUE(SSL_apply_handoff(handshaker.get(), handoff));
4034
4035 MoveBIOs(handshaker.get(), server.get());
4036
4037 int handshake_ret = SSL_do_handshake(handshaker.get());
4038 int handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
Matthew Braithwaite56986f92018-03-22 11:48:33 -07004039 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
Adam Langleyddb57cf2018-01-26 09:17:53 -08004040
Matthew Braithwaite56986f92018-03-22 11:48:33 -07004041 // Double-check that additional calls to |SSL_do_handshake| continue
4042 // to get |SSL_ERRROR_HANDBACK|.
4043 handshake_ret = SSL_do_handshake(handshaker.get());
4044 handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
4045 ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
Adam Langleyddb57cf2018-01-26 09:17:53 -08004046
4047 ScopedCBB cbb_handback;
4048 Array<uint8_t> handback;
4049 ASSERT_TRUE(CBB_init(cbb_handback.get(), 1024));
4050 ASSERT_TRUE(SSL_serialize_handback(handshaker.get(), cbb_handback.get()));
4051 ASSERT_TRUE(CBBFinishArray(cbb_handback.get(), &handback));
4052
4053 bssl::UniquePtr<SSL> server2(SSL_new(server_ctx.get()));
4054 ASSERT_TRUE(SSL_apply_handback(server2.get(), handback));
4055
4056 MoveBIOs(server2.get(), handshaker.get());
Matthew Braithwaite56986f92018-03-22 11:48:33 -07004057 ASSERT_TRUE(CompleteHandshakes(client.get(), server2.get()));
Adam Langleyddb57cf2018-01-26 09:17:53 -08004058
4059 uint8_t byte = 42;
4060 EXPECT_EQ(SSL_write(client.get(), &byte, 1), 1);
4061 EXPECT_EQ(SSL_read(server2.get(), &byte, 1), 1);
4062 EXPECT_EQ(42, byte);
4063
4064 byte = 43;
4065 EXPECT_EQ(SSL_write(server2.get(), &byte, 1), 1);
4066 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
4067 EXPECT_EQ(43, byte);
4068}
4069
4070TEST(SSLTest, HandoffDeclined) {
4071 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
4072 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
4073 ASSERT_TRUE(client_ctx);
4074 ASSERT_TRUE(server_ctx);
4075
4076 SSL_CTX_set_handoff_mode(server_ctx.get(), 1);
4077 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
4078
4079 bssl::UniquePtr<X509> cert = GetTestCertificate();
4080 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4081 ASSERT_TRUE(cert);
4082 ASSERT_TRUE(key);
4083 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
4084 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
4085
4086 bssl::UniquePtr<SSL> client, server;
4087 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4088 server_ctx.get(), ClientConfig(),
4089 false /* don't handshake */));
4090
4091 int client_ret = SSL_do_handshake(client.get());
4092 int client_err = SSL_get_error(client.get(), client_ret);
4093 ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4094
4095 int server_ret = SSL_do_handshake(server.get());
4096 int server_err = SSL_get_error(server.get(), server_ret);
4097 ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
4098
4099 ScopedCBB cbb;
4100 ASSERT_TRUE(CBB_init(cbb.get(), 256));
4101 ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get()));
4102
4103 ASSERT_TRUE(SSL_decline_handoff(server.get()));
4104
4105 ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
4106
4107 uint8_t byte = 42;
4108 EXPECT_EQ(SSL_write(client.get(), &byte, 1), 1);
4109 EXPECT_EQ(SSL_read(server.get(), &byte, 1), 1);
4110 EXPECT_EQ(42, byte);
4111
4112 byte = 43;
4113 EXPECT_EQ(SSL_write(server.get(), &byte, 1), 1);
4114 EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
4115 EXPECT_EQ(43, byte);
4116}
4117
David Benjamin96628432017-01-19 19:05:47 -05004118// TODO(davidben): Convert this file to GTest properly.
4119TEST(SSLTest, AllTests) {
David Benjamine11726a2017-04-23 12:14:28 -04004120 if (!TestSSL_SESSIONEncoding(kOpenSSLSession) ||
Adam Langley10f97f32016-07-12 08:09:33 -07004121 !TestSSL_SESSIONEncoding(kCustomSession) ||
4122 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
4123 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
4124 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
4125 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
Steven Valdeza833c352016-11-01 13:39:36 -04004126 // Test the padding extension at TLS 1.2.
4127 !TestPaddingExtension(TLS1_2_VERSION, TLS1_2_VERSION) ||
4128 // Test the padding extension at TLS 1.3 with a TLS 1.2 session, so there
4129 // will be no PSK binder after the padding extension.
4130 !TestPaddingExtension(TLS1_3_VERSION, TLS1_2_VERSION) ||
4131 // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
4132 // will be a PSK binder after the padding extension.
David Benjaminaaef8332018-06-29 16:45:49 -04004133 !TestPaddingExtension(TLS1_3_VERSION, TLS1_3_VERSION)) {
David Benjamin96628432017-01-19 19:05:47 -05004134 ADD_FAILURE() << "Tests failed";
David Benjaminbb0a17c2014-09-20 15:35:39 -04004135 }
David Benjamin2e521212014-07-16 14:37:51 -04004136}
Martin Kreichgauer72912d22017-08-04 12:06:43 -07004137
4138} // namespace
4139} // namespace bssl