blob: 3296c175e59b9e07013b25a2da4805b3d9ad9227 [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)
43/* Windows defines struct timeval in winsock2.h. */
44OPENSSL_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
52struct ExpectedCipher {
53 unsigned long id;
David Benjaminbb0a17c2014-09-20 15:35:39 -040054 int in_group_flag;
David Benjamin1d77e562015-03-22 17:22:08 -040055};
David Benjaminbb0a17c2014-09-20 15:35:39 -040056
David Benjamin1d77e562015-03-22 17:22:08 -040057struct CipherTest {
58 // The rule string to apply.
David Benjaminbb0a17c2014-09-20 15:35:39 -040059 const char *rule;
David Benjaminfb974e62015-12-16 19:34:22 -050060 // The list of expected ciphers, in order.
61 std::vector<ExpectedCipher> expected;
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -080062 // True if this cipher list should fail in strict mode.
63 bool strict_fail;
David Benjamin1d77e562015-03-22 17:22:08 -040064};
David Benjaminbb0a17c2014-09-20 15:35:39 -040065
Alessandro Ghedini5fd18072016-09-28 21:04:25 +010066struct CurveTest {
67 // The rule string to apply.
68 const char *rule;
69 // The list of expected curves, in order.
70 std::vector<uint16_t> expected;
71};
72
David Benjaminfb974e62015-12-16 19:34:22 -050073static const CipherTest kCipherTests[] = {
74 // Selecting individual ciphers should work.
75 {
76 "ECDHE-ECDSA-CHACHA20-POLY1305:"
77 "ECDHE-RSA-CHACHA20-POLY1305:"
78 "ECDHE-ECDSA-AES128-GCM-SHA256:"
79 "ECDHE-RSA-AES128-GCM-SHA256",
80 {
81 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -050082 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -050083 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
84 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
85 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -080086 false,
David Benjaminfb974e62015-12-16 19:34:22 -050087 },
88 // + reorders selected ciphers to the end, keeping their relative order.
89 {
90 "ECDHE-ECDSA-CHACHA20-POLY1305:"
91 "ECDHE-RSA-CHACHA20-POLY1305:"
92 "ECDHE-ECDSA-AES128-GCM-SHA256:"
93 "ECDHE-RSA-AES128-GCM-SHA256:"
94 "+aRSA",
95 {
96 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -050097 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
98 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -050099 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
100 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800101 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500102 },
103 // ! banishes ciphers from future selections.
104 {
105 "!aRSA:"
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_ECDSA_WITH_AES_128_GCM_SHA256, 0},
113 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800114 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500115 },
116 // Multiple masks can be ANDed in a single rule.
117 {
118 "kRSA+AESGCM+AES128",
119 {
120 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
121 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800122 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500123 },
124 // - removes selected ciphers, but preserves their order for future
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700125 // selections. Select AES_128_GCM, but order the key exchanges RSA,
David Benjaminfb974e62015-12-16 19:34:22 -0500126 // ECDHE_RSA.
127 {
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700128 "ALL:-kECDHE:"
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700129 "-kRSA:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500130 "AESGCM+AES128+aRSA",
131 {
132 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500133 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
134 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800135 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500136 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800137 // Unknown selectors are no-ops, except in strict mode.
David Benjaminfb974e62015-12-16 19:34:22 -0500138 {
139 "ECDHE-ECDSA-CHACHA20-POLY1305:"
140 "ECDHE-RSA-CHACHA20-POLY1305:"
141 "ECDHE-ECDSA-AES128-GCM-SHA256:"
142 "ECDHE-RSA-AES128-GCM-SHA256:"
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800143 "BOGUS1",
David Benjaminfb974e62015-12-16 19:34:22 -0500144 {
145 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500146 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500147 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
148 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
149 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800150 true,
151 },
152 // Unknown selectors are no-ops, except in strict mode.
153 {
154 "ECDHE-ECDSA-CHACHA20-POLY1305:"
155 "ECDHE-RSA-CHACHA20-POLY1305:"
156 "ECDHE-ECDSA-AES128-GCM-SHA256:"
157 "ECDHE-RSA-AES128-GCM-SHA256:"
158 "-BOGUS2:+BOGUS3:!BOGUS4",
159 {
160 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
161 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
162 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
163 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
164 },
165 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500166 },
167 // Square brackets specify equi-preference groups.
168 {
169 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
170 "[ECDHE-RSA-CHACHA20-POLY1305]:"
171 "ECDHE-RSA-AES128-GCM-SHA256",
172 {
173 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
David Benjaminfb974e62015-12-16 19:34:22 -0500174 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
Adam Langley2e839242017-01-19 15:12:44 -0800175 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500176 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
177 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800178 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500179 },
180 // @STRENGTH performs a stable strength-sort of the selected ciphers and
181 // only the selected ciphers.
182 {
183 // To simplify things, banish all but {ECDHE_RSA,RSA} x
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700184 // {CHACHA20,AES_256_CBC,AES_128_CBC} x SHA1.
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -0700185 "!AESGCM:!3DES:!SHA256:!SHA384:"
David Benjaminfb974e62015-12-16 19:34:22 -0500186 // Order some ciphers backwards by strength.
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700187 "ALL:-CHACHA20:-AES256:-AES128:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500188 // Select ECDHE ones and sort them by strength. Ties should resolve
189 // based on the order above.
190 "kECDHE:@STRENGTH:-ALL:"
191 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
192 // by strength. Then RSA, backwards by strength.
193 "aRSA",
194 {
195 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
196 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500197 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500198 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
199 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
200 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800201 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500202 },
203 // Exact ciphers may not be used in multi-part rules; they are treated
204 // as unknown aliases.
205 {
206 "ECDHE-ECDSA-AES128-GCM-SHA256:"
207 "ECDHE-RSA-AES128-GCM-SHA256:"
208 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
209 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
210 {
211 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
212 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
213 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800214 true,
David Benjaminfb974e62015-12-16 19:34:22 -0500215 },
216 // SSLv3 matches everything that existed before TLS 1.2.
217 {
218 "AES128-SHA:AES128-SHA256:!SSLv3",
219 {
220 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
221 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800222 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500223 },
224 // TLSv1.2 matches everything added in TLS 1.2.
225 {
226 "AES128-SHA:AES128-SHA256:!TLSv1.2",
227 {
228 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
229 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800230 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500231 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800232 // The two directives have no intersection. But each component is valid, so
233 // even in strict mode it is accepted.
David Benjaminfb974e62015-12-16 19:34:22 -0500234 {
235 "AES128-SHA:AES128-SHA256:!TLSv1.2+SSLv3",
236 {
237 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
238 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
239 },
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800240 false,
David Benjaminfb974e62015-12-16 19:34:22 -0500241 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400242};
243
244static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400245 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400246 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
247 "RSA]",
248 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400249 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400250 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400251 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400252 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400253 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400254 "",
255 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400256 // COMPLEMENTOFDEFAULT is empty.
257 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400258 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400259 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400260 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400261 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
262 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
263 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
264 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
Adam Langleyf99f2442016-10-02 09:53:38 -0700265 // Opcode supplied, but missing selector.
266 "+",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400267};
268
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700269static const char *kMustNotIncludeNull[] = {
270 "ALL",
271 "DEFAULT",
David Benjamind6e9eec2015-11-18 09:48:55 -0500272 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700273 "FIPS",
274 "SHA",
275 "SHA1",
276 "RSA",
277 "SSLv3",
278 "TLSv1",
279 "TLSv1.2",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700280};
281
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100282static const CurveTest kCurveTests[] = {
283 {
284 "P-256",
285 { SSL_CURVE_SECP256R1 },
286 },
287 {
288 "P-256:P-384:P-521:X25519",
289 {
290 SSL_CURVE_SECP256R1,
291 SSL_CURVE_SECP384R1,
292 SSL_CURVE_SECP521R1,
293 SSL_CURVE_X25519,
294 },
295 },
296};
297
298static const char *kBadCurvesLists[] = {
299 "",
300 ":",
301 "::",
302 "P-256::X25519",
303 "RSA:P-256",
304 "P-256:RSA",
305 "X25519:P-256:",
306 ":X25519:P-256",
307};
308
David Benjamin1d77e562015-03-22 17:22:08 -0400309static void PrintCipherPreferenceList(ssl_cipher_preference_list_st *list) {
310 bool in_group = false;
311 for (size_t i = 0; i < sk_SSL_CIPHER_num(list->ciphers); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400312 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(list->ciphers, i);
313 if (!in_group && list->in_group_flags[i]) {
314 fprintf(stderr, "\t[\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400315 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400316 }
317 fprintf(stderr, "\t");
318 if (in_group) {
319 fprintf(stderr, " ");
320 }
321 fprintf(stderr, "%s\n", SSL_CIPHER_get_name(cipher));
322 if (in_group && !list->in_group_flags[i]) {
323 fprintf(stderr, "\t]\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400324 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400325 }
326 }
327}
328
David Benjaminfb974e62015-12-16 19:34:22 -0500329static bool TestCipherRule(const CipherTest &t) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700330 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400331 if (!ctx) {
332 return false;
David Benjamin65226252015-02-05 16:49:47 -0500333 }
334
David Benjaminfb974e62015-12-16 19:34:22 -0500335 if (!SSL_CTX_set_cipher_list(ctx.get(), t.rule)) {
336 fprintf(stderr, "Error testing cipher rule '%s'\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400337 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400338 }
339
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800340 if (!SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule) != t.strict_fail) {
341 fprintf(stderr, "Unexpected strict failure result testing cipher rule '%s':"
342 " expected %d\n", t.rule, t.strict_fail);
343 return false;
344 }
345
David Benjamin1d77e562015-03-22 17:22:08 -0400346 // Compare the two lists.
David Benjaminfb974e62015-12-16 19:34:22 -0500347 if (sk_SSL_CIPHER_num(ctx->cipher_list->ciphers) != t.expected.size()) {
348 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
349 PrintCipherPreferenceList(ctx->cipher_list);
350 return false;
351 }
352
353 for (size_t i = 0; i < t.expected.size(); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400354 const SSL_CIPHER *cipher =
355 sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i);
David Benjaminfb974e62015-12-16 19:34:22 -0500356 if (t.expected[i].id != SSL_CIPHER_get_id(cipher) ||
357 t.expected[i].in_group_flag != ctx->cipher_list->in_group_flags[i]) {
358 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400359 PrintCipherPreferenceList(ctx->cipher_list);
360 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400361 }
362 }
363
David Benjamin1d77e562015-03-22 17:22:08 -0400364 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400365}
366
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700367static bool TestRuleDoesNotIncludeNull(const char *rule) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700368 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700369 if (!ctx) {
370 return false;
371 }
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800372 if (!SSL_CTX_set_strict_cipher_list(ctx.get(), rule)) {
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700373 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
374 return false;
375 }
376 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
377 if (SSL_CIPHER_is_NULL(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
378 fprintf(stderr, "Error: cipher rule '%s' includes NULL\n",rule);
379 return false;
380 }
381 }
382 return true;
383}
384
David Benjamin1d77e562015-03-22 17:22:08 -0400385static bool TestCipherRules() {
David Benjaminfb974e62015-12-16 19:34:22 -0500386 for (const CipherTest &test : kCipherTests) {
387 if (!TestCipherRule(test)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400388 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400389 }
390 }
391
David Benjaminfb974e62015-12-16 19:34:22 -0500392 for (const char *rule : kBadRules) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700393 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400394 if (!ctx) {
395 return false;
David Benjamin65226252015-02-05 16:49:47 -0500396 }
David Benjaminfb974e62015-12-16 19:34:22 -0500397 if (SSL_CTX_set_cipher_list(ctx.get(), rule)) {
398 fprintf(stderr, "Cipher rule '%s' unexpectedly succeeded\n", rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400399 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400400 }
401 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400402 }
403
David Benjaminfb974e62015-12-16 19:34:22 -0500404 for (const char *rule : kMustNotIncludeNull) {
405 if (!TestRuleDoesNotIncludeNull(rule)) {
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700406 return false;
407 }
408 }
409
David Benjamin1d77e562015-03-22 17:22:08 -0400410 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400411}
David Benjamin2e521212014-07-16 14:37:51 -0400412
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100413static bool TestCurveRule(const CurveTest &t) {
414 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
415 if (!ctx) {
416 return false;
417 }
418
419 if (!SSL_CTX_set1_curves_list(ctx.get(), t.rule)) {
420 fprintf(stderr, "Error testing curves list '%s'\n", t.rule);
421 return false;
422 }
423
424 // Compare the two lists.
425 if (ctx->supported_group_list_len != t.expected.size()) {
426 fprintf(stderr, "Error testing curves list '%s': length\n", t.rule);
427 return false;
428 }
429
430 for (size_t i = 0; i < t.expected.size(); i++) {
431 if (t.expected[i] != ctx->supported_group_list[i]) {
432 fprintf(stderr, "Error testing curves list '%s': mismatch\n", t.rule);
433 return false;
434 }
435 }
436
437 return true;
438}
439
440static bool TestCurveRules() {
441 for (const CurveTest &test : kCurveTests) {
442 if (!TestCurveRule(test)) {
443 return false;
444 }
445 }
446
447 for (const char *rule : kBadCurvesLists) {
448 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
449 if (!ctx) {
450 return false;
451 }
452 if (SSL_CTX_set1_curves_list(ctx.get(), rule)) {
453 fprintf(stderr, "Curves list '%s' unexpectedly succeeded\n", rule);
454 return false;
455 }
456 ERR_clear_error();
457 }
458
459 return true;
460}
461
Adam Langley364f7a62016-12-12 10:51:00 -0800462// kOpenSSLSession is a serialized SSL_SESSION.
Adam Langley10f97f32016-07-12 08:09:33 -0700463static const char kOpenSSLSession[] =
Adam Langley364f7a62016-12-12 10:51:00 -0800464 "MIIFqgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
Adam Langley10f97f32016-07-12 08:09:33 -0700465 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
466 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
467 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
468 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
469 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
470 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
471 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
472 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
473 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
474 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
475 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
476 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
477 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
478 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
479 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
480 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
481 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
482 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
483 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
484 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
485 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
486 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
487 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
488 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
489 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
490 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
491 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
492 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
493 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
Adam Langley364f7a62016-12-12 10:51:00 -0800494 "i4gv7Y5oliyntgMBAQA=";
Adam Langley10f97f32016-07-12 08:09:33 -0700495
496// kCustomSession is a custom serialized SSL_SESSION generated by
497// filling in missing fields from |kOpenSSLSession|. This includes
498// providing |peer_sha256|, so |peer| is not serialized.
499static const char kCustomSession[] =
500 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
501 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
502 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
503 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
504 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
505 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
506 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
507 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
508
509// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
510static const char kBoringSSLSession[] =
511 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
512 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
513 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
514 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
515 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
516 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
517 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
518 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
519 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
520 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
521 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
522 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
523 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
524 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
525 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
526 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
527 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
528 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
529 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
530 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
531 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
532 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
533 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
534 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
535 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
536 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
537 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
538 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
539 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
540 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
541 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
542 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
543 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
544 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
545 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
546 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
547 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
548 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
549 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
550 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
551 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
552 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
553 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
554 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
555 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
556 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
557 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
558 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
559 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
560 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
561 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
562 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
563 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
564 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
565 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
566 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
567 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
568 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
569 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
570 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
571 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
572 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
573 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
574 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
575 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
576 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
577 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
578 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
579 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
580 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
581 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
582 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
583 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
584 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
585 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
586 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
587 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
588 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
589 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
590 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
591 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
592 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
593 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
594 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
595 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
596 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
597 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
598 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
599 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
600 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
601 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
602 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
603 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
604 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
605 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
606
607// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
608// the final (optional) element of |kCustomSession| with tag number 30.
609static const char kBadSessionExtraField[] =
610 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
611 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
612 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
613 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
614 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
615 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
616 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
617 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
618
619// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
620// the version of |kCustomSession| with 2.
621static const char kBadSessionVersion[] =
622 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
623 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
624 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
625 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
626 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
627 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
628 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
629 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
630
631// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
632// appended.
633static const char kBadSessionTrailingData[] =
634 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
635 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
636 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
637 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
638 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
639 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
640 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
641 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
642
David Benjamin1d77e562015-03-22 17:22:08 -0400643static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400644 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400645 if (!EVP_DecodedLength(&len, strlen(in))) {
646 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400647 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400648 }
649
David Benjamin1d77e562015-03-22 17:22:08 -0400650 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800651 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400652 strlen(in))) {
653 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400654 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400655 }
David Benjamin1d77e562015-03-22 17:22:08 -0400656 out->resize(len);
657 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400658}
659
David Benjamin1d77e562015-03-22 17:22:08 -0400660static bool TestSSL_SESSIONEncoding(const char *input_b64) {
David Benjamin751e8892014-10-19 00:59:36 -0400661 const uint8_t *cptr;
662 uint8_t *ptr;
David Benjamin751e8892014-10-19 00:59:36 -0400663
David Benjamin1d77e562015-03-22 17:22:08 -0400664 // Decode the input.
665 std::vector<uint8_t> input;
666 if (!DecodeBase64(&input, input_b64)) {
667 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400668 }
669
David Benjamin1d77e562015-03-22 17:22:08 -0400670 // Verify the SSL_SESSION decodes.
Adam Langley46db7af2017-02-01 15:49:37 -0800671 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
672 if (!ssl_ctx) {
673 return false;
674 }
675 bssl::UniquePtr<SSL_SESSION> session(
676 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
David Benjaminfd67aa82015-06-15 19:41:48 -0400677 if (!session) {
678 fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400679 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400680 }
681
David Benjamin1d77e562015-03-22 17:22:08 -0400682 // Verify the SSL_SESSION encoding round-trips.
683 size_t encoded_len;
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700684 bssl::UniquePtr<uint8_t> encoded;
David Benjamin1d77e562015-03-22 17:22:08 -0400685 uint8_t *encoded_raw;
686 if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
David Benjamin3cac4502014-10-21 01:46:30 -0400687 fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400688 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400689 }
David Benjamin1d77e562015-03-22 17:22:08 -0400690 encoded.reset(encoded_raw);
691 if (encoded_len != input.size() ||
David Benjamin17cf2cb2016-12-13 01:07:13 -0500692 OPENSSL_memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin3cac4502014-10-21 01:46:30 -0400693 fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
Sigbjorn Vik2b23d242015-06-29 15:07:26 +0200694 hexdump(stderr, "Before: ", input.data(), input.size());
695 hexdump(stderr, "After: ", encoded_raw, encoded_len);
David Benjamin1d77e562015-03-22 17:22:08 -0400696 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400697 }
David Benjamin3cac4502014-10-21 01:46:30 -0400698
David Benjaminfd67aa82015-06-15 19:41:48 -0400699 // Verify the SSL_SESSION also decodes with the legacy API.
David Benjaminef14b2d2015-11-11 14:01:27 -0800700 cptr = input.data();
David Benjaminfd67aa82015-06-15 19:41:48 -0400701 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
David Benjaminef14b2d2015-11-11 14:01:27 -0800702 if (!session || cptr != input.data() + input.size()) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400703 fprintf(stderr, "d2i_SSL_SESSION failed\n");
704 return false;
705 }
706
David Benjamin1d77e562015-03-22 17:22:08 -0400707 // Verify the SSL_SESSION encoding round-trips via the legacy API.
708 int len = i2d_SSL_SESSION(session.get(), NULL);
709 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400710 fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400711 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400712 }
713
David Benjamin1d77e562015-03-22 17:22:08 -0400714 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
715 if (!encoded) {
David Benjamin751e8892014-10-19 00:59:36 -0400716 fprintf(stderr, "malloc failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400717 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400718 }
David Benjamin1d77e562015-03-22 17:22:08 -0400719
720 ptr = encoded.get();
721 len = i2d_SSL_SESSION(session.get(), &ptr);
722 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400723 fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400724 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400725 }
David Benjamin1d77e562015-03-22 17:22:08 -0400726 if (ptr != encoded.get() + input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400727 fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400728 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400729 }
David Benjamin17cf2cb2016-12-13 01:07:13 -0500730 if (OPENSSL_memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin751e8892014-10-19 00:59:36 -0400731 fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400732 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400733 }
734
David Benjamin1d77e562015-03-22 17:22:08 -0400735 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400736}
737
David Benjaminf297e022015-05-28 19:55:29 -0400738static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
739 std::vector<uint8_t> input;
740 if (!DecodeBase64(&input, input_b64)) {
741 return false;
742 }
743
744 // Verify that the SSL_SESSION fails to decode.
Adam Langley46db7af2017-02-01 15:49:37 -0800745 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
746 if (!ssl_ctx) {
747 return false;
748 }
749 bssl::UniquePtr<SSL_SESSION> session(
750 SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
David Benjaminf297e022015-05-28 19:55:29 -0400751 if (session) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400752 fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
David Benjaminf297e022015-05-28 19:55:29 -0400753 return false;
754 }
755 ERR_clear_error();
756 return true;
757}
758
David Benjamin10e664b2016-06-20 22:20:47 -0400759static bool TestDefaultVersion(uint16_t min_version, uint16_t max_version,
David Benjamin1d77e562015-03-22 17:22:08 -0400760 const SSL_METHOD *(*method)(void)) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700761 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400762 if (!ctx) {
763 return false;
David Benjamin82c9e902014-12-12 15:55:27 -0500764 }
David Benjaminb6a0a512016-06-21 10:33:21 -0400765 if (ctx->min_version != min_version || ctx->max_version != max_version) {
766 fprintf(stderr, "Got min %04x, max %04x; wanted min %04x, max %04x\n",
767 ctx->min_version, ctx->max_version, min_version, max_version);
768 return false;
769 }
770 return true;
David Benjamin82c9e902014-12-12 15:55:27 -0500771}
772
David Benjamin1d77e562015-03-22 17:22:08 -0400773static bool CipherGetRFCName(std::string *out, uint16_t value) {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500774 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(value);
775 if (cipher == NULL) {
David Benjamin1d77e562015-03-22 17:22:08 -0400776 return false;
David Benjamin65226252015-02-05 16:49:47 -0500777 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700778 bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
David Benjamin3fa65f02015-05-15 19:11:57 -0400779 if (!rfc_name) {
780 return false;
781 }
David Benjamin67be0482015-04-20 16:19:00 -0400782 out->assign(rfc_name.get());
David Benjamin1d77e562015-03-22 17:22:08 -0400783 return true;
David Benjamin65226252015-02-05 16:49:47 -0500784}
785
786typedef struct {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500787 int id;
David Benjamin65226252015-02-05 16:49:47 -0500788 const char *rfc_name;
789} CIPHER_RFC_NAME_TEST;
790
791static const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = {
Steven Valdez803c77a2016-09-06 14:13:43 -0400792 {SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA"},
793 {TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA"},
Steven Valdez803c77a2016-09-06 14:13:43 -0400794 {TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
795 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"},
796 {TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
797 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"},
798 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
799 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"},
800 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
801 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"},
802 {TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
803 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"},
804 {TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
805 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA"},
806 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
807 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"},
808 {TLS1_CK_AES_256_GCM_SHA384, "TLS_AES_256_GCM_SHA384"},
809 {TLS1_CK_AES_128_GCM_SHA256, "TLS_AES_128_GCM_SHA256"},
810 {TLS1_CK_CHACHA20_POLY1305_SHA256, "TLS_CHACHA20_POLY1305_SHA256"},
David Benjamin65226252015-02-05 16:49:47 -0500811};
812
David Benjamin1d77e562015-03-22 17:22:08 -0400813static bool TestCipherGetRFCName(void) {
814 for (size_t i = 0;
Steven Valdezcb966542016-08-17 16:56:14 -0400815 i < OPENSSL_ARRAY_SIZE(kCipherRFCNameTests); i++) {
David Benjamin65226252015-02-05 16:49:47 -0500816 const CIPHER_RFC_NAME_TEST *test = &kCipherRFCNameTests[i];
David Benjamin1d77e562015-03-22 17:22:08 -0400817 std::string rfc_name;
818 if (!CipherGetRFCName(&rfc_name, test->id & 0xffff)) {
819 fprintf(stderr, "SSL_CIPHER_get_rfc_name failed\n");
820 return false;
David Benjamin65226252015-02-05 16:49:47 -0500821 }
David Benjamin1d77e562015-03-22 17:22:08 -0400822 if (rfc_name != test->rfc_name) {
David Benjamin65226252015-02-05 16:49:47 -0500823 fprintf(stderr, "SSL_CIPHER_get_rfc_name: got '%s', wanted '%s'\n",
David Benjamin1d77e562015-03-22 17:22:08 -0400824 rfc_name.c_str(), test->rfc_name);
825 return false;
David Benjamin65226252015-02-05 16:49:47 -0500826 }
David Benjamin65226252015-02-05 16:49:47 -0500827 }
David Benjamin1d77e562015-03-22 17:22:08 -0400828 return true;
David Benjamin65226252015-02-05 16:49:47 -0500829}
830
Steven Valdeza833c352016-11-01 13:39:36 -0400831// CreateSessionWithTicket returns a sample |SSL_SESSION| with the specified
832// version and ticket length or nullptr on failure.
833static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(uint16_t version,
834 size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -0400835 std::vector<uint8_t> der;
836 if (!DecodeBase64(&der, kOpenSSLSession)) {
837 return nullptr;
838 }
Adam Langley46db7af2017-02-01 15:49:37 -0800839
840 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
841 if (!ssl_ctx) {
842 return nullptr;
843 }
Steven Valdeza833c352016-11-01 13:39:36 -0400844 bssl::UniquePtr<SSL_SESSION> session(
Adam Langley46db7af2017-02-01 15:49:37 -0800845 SSL_SESSION_from_bytes(der.data(), der.size(), ssl_ctx.get()));
David Benjamin422fe082015-07-21 22:03:43 -0400846 if (!session) {
847 return nullptr;
848 }
849
Steven Valdeza833c352016-11-01 13:39:36 -0400850 session->ssl_version = version;
851
David Benjamin422fe082015-07-21 22:03:43 -0400852 // Swap out the ticket for a garbage one.
853 OPENSSL_free(session->tlsext_tick);
854 session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len));
855 if (session->tlsext_tick == nullptr) {
856 return nullptr;
857 }
David Benjamin17cf2cb2016-12-13 01:07:13 -0500858 OPENSSL_memset(session->tlsext_tick, 'a', ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -0400859 session->tlsext_ticklen = ticket_len;
David Benjamin1269ddd2015-10-18 15:18:55 -0400860
861 // Fix up the timeout.
David Benjamin9b63f292016-11-15 00:44:05 -0500862#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
863 session->time = 1234;
864#else
David Benjamin1269ddd2015-10-18 15:18:55 -0400865 session->time = time(NULL);
David Benjamin9b63f292016-11-15 00:44:05 -0500866#endif
David Benjamin422fe082015-07-21 22:03:43 -0400867 return session;
868}
869
David Benjaminafc64de2016-07-19 17:12:41 +0200870static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700871 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +0200872 if (!bio) {
873 return false;
874 }
875 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -0400876 BIO_up_ref(bio.get());
877 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +0200878 int ret = SSL_connect(ssl);
879 if (ret > 0) {
880 // SSL_connect should fail without a BIO to write to.
881 return false;
882 }
883 ERR_clear_error();
884
885 const uint8_t *client_hello;
886 size_t client_hello_len;
887 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
888 return false;
889 }
890 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
891 return true;
892}
893
Steven Valdeza833c352016-11-01 13:39:36 -0400894// GetClientHelloLen creates a client SSL connection with the specified version
895// and ticket length. It returns the length of the ClientHello, not including
896// the record header, on success and zero on error.
897static size_t GetClientHelloLen(uint16_t max_version, uint16_t session_version,
898 size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700899 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Steven Valdeza833c352016-11-01 13:39:36 -0400900 bssl::UniquePtr<SSL_SESSION> session =
901 CreateSessionWithTicket(session_version, ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -0400902 if (!ctx || !session) {
903 return 0;
904 }
Steven Valdeza833c352016-11-01 13:39:36 -0400905
906 // Set a one-element cipher list so the baseline ClientHello is unpadded.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700907 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
Steven Valdez2c62fe92016-10-14 12:08:12 -0400908 if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800909 !SSL_set_strict_cipher_list(ssl.get(), "ECDHE-RSA-AES128-GCM-SHA256") ||
Steven Valdeza833c352016-11-01 13:39:36 -0400910 !SSL_set_max_proto_version(ssl.get(), max_version)) {
David Benjamin422fe082015-07-21 22:03:43 -0400911 return 0;
912 }
Steven Valdeza833c352016-11-01 13:39:36 -0400913
David Benjaminafc64de2016-07-19 17:12:41 +0200914 std::vector<uint8_t> client_hello;
915 if (!GetClientHello(ssl.get(), &client_hello) ||
916 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -0400917 return 0;
918 }
Steven Valdeza833c352016-11-01 13:39:36 -0400919
David Benjaminafc64de2016-07-19 17:12:41 +0200920 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -0400921}
922
923struct PaddingTest {
924 size_t input_len, padded_len;
925};
926
927static const PaddingTest kPaddingTests[] = {
928 // ClientHellos of length below 0x100 do not require padding.
929 {0xfe, 0xfe},
930 {0xff, 0xff},
931 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
932 {0x100, 0x200},
933 {0x123, 0x200},
934 {0x1fb, 0x200},
935 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
936 // padding extension takes a minimum of four bytes plus one required content
937 // byte. (To work around yet more server bugs, we avoid empty final
938 // extensions.)
939 {0x1fc, 0x201},
940 {0x1fd, 0x202},
941 {0x1fe, 0x203},
942 {0x1ff, 0x204},
943 // Finally, larger ClientHellos need no padding.
944 {0x200, 0x200},
945 {0x201, 0x201},
946};
947
Steven Valdeza833c352016-11-01 13:39:36 -0400948static bool TestPaddingExtension(uint16_t max_version,
949 uint16_t session_version) {
David Benjamin422fe082015-07-21 22:03:43 -0400950 // Sample a baseline length.
Steven Valdeza833c352016-11-01 13:39:36 -0400951 size_t base_len = GetClientHelloLen(max_version, session_version, 1);
David Benjamin422fe082015-07-21 22:03:43 -0400952 if (base_len == 0) {
953 return false;
954 }
955
956 for (const PaddingTest &test : kPaddingTests) {
957 if (base_len > test.input_len) {
Steven Valdeza833c352016-11-01 13:39:36 -0400958 fprintf(stderr,
959 "Baseline ClientHello too long (max_version = %04x, "
960 "session_version = %04x).\n",
961 max_version, session_version);
David Benjamin422fe082015-07-21 22:03:43 -0400962 return false;
963 }
964
Steven Valdeza833c352016-11-01 13:39:36 -0400965 size_t padded_len = GetClientHelloLen(max_version, session_version,
966 1 + test.input_len - base_len);
David Benjamin422fe082015-07-21 22:03:43 -0400967 if (padded_len != test.padded_len) {
Steven Valdeza833c352016-11-01 13:39:36 -0400968 fprintf(stderr,
969 "%u-byte ClientHello padded to %u bytes, not %u (max_version = "
970 "%04x, session_version = %04x).\n",
David Benjamin422fe082015-07-21 22:03:43 -0400971 static_cast<unsigned>(test.input_len),
972 static_cast<unsigned>(padded_len),
Steven Valdeza833c352016-11-01 13:39:36 -0400973 static_cast<unsigned>(test.padded_len), max_version,
974 session_version);
David Benjamin422fe082015-07-21 22:03:43 -0400975 return false;
976 }
977 }
Steven Valdeza833c352016-11-01 13:39:36 -0400978
David Benjamin422fe082015-07-21 22:03:43 -0400979 return true;
980}
981
David Benjamin1d128f32015-09-08 17:41:40 -0400982// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
983// before configuring as a server.
David Benjaminf0d8e222017-02-04 10:58:26 -0500984TEST(SSLTest, ClientCAList) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700985 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -0500986 ASSERT_TRUE(ctx);
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700987 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -0500988 ASSERT_TRUE(ssl);
David Benjamin1d128f32015-09-08 17:41:40 -0400989
Adam Langley34b4c822017-02-02 10:57:17 -0800990 bssl::UniquePtr<X509_NAME> name(X509_NAME_new());
991 ASSERT_TRUE(name);
David Benjamin1d128f32015-09-08 17:41:40 -0400992
Adam Langley34b4c822017-02-02 10:57:17 -0800993 bssl::UniquePtr<X509_NAME> name_dup(X509_NAME_dup(name.get()));
994 ASSERT_TRUE(name_dup);
995
996 bssl::UniquePtr<STACK_OF(X509_NAME)> stack(sk_X509_NAME_new_null());
997 ASSERT_TRUE(stack);
998
999 ASSERT_TRUE(sk_X509_NAME_push(stack.get(), name_dup.get()));
1000 name_dup.release();
1001
1002 // |SSL_set_client_CA_list| takes ownership.
1003 SSL_set_client_CA_list(ssl.get(), stack.release());
1004
1005 STACK_OF(X509_NAME) *result = SSL_get_client_CA_list(ssl.get());
1006 ASSERT_TRUE(result);
1007 ASSERT_EQ(1u, sk_X509_NAME_num(result));
1008 EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(result, 0), name.get()));
David Benjamin1d128f32015-09-08 17:41:40 -04001009}
1010
David Benjamin0f653952015-10-18 14:28:01 -04001011static void AppendSession(SSL_SESSION *session, void *arg) {
1012 std::vector<SSL_SESSION*> *out =
1013 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
1014 out->push_back(session);
1015}
1016
1017// ExpectCache returns true if |ctx|'s session cache consists of |expected|, in
1018// order.
1019static bool ExpectCache(SSL_CTX *ctx,
1020 const std::vector<SSL_SESSION*> &expected) {
1021 // Check the linked list.
1022 SSL_SESSION *ptr = ctx->session_cache_head;
1023 for (SSL_SESSION *session : expected) {
1024 if (ptr != session) {
1025 return false;
1026 }
1027 // TODO(davidben): This is an absurd way to denote the end of the list.
1028 if (ptr->next ==
1029 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
1030 ptr = nullptr;
1031 } else {
1032 ptr = ptr->next;
1033 }
1034 }
1035 if (ptr != nullptr) {
1036 return false;
1037 }
1038
1039 // Check the hash table.
1040 std::vector<SSL_SESSION*> actual, expected_copy;
1041 lh_SSL_SESSION_doall_arg(SSL_CTX_sessions(ctx), AppendSession, &actual);
1042 expected_copy = expected;
1043
1044 std::sort(actual.begin(), actual.end());
1045 std::sort(expected_copy.begin(), expected_copy.end());
1046
1047 return actual == expected_copy;
1048}
1049
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001050static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
Adam Langley46db7af2017-02-01 15:49:37 -08001051 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
1052 if (!ssl_ctx) {
1053 return nullptr;
1054 }
1055 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new(ssl_ctx.get()));
David Benjamin0f653952015-10-18 14:28:01 -04001056 if (!ret) {
1057 return nullptr;
1058 }
1059
1060 ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
David Benjamin17cf2cb2016-12-13 01:07:13 -05001061 OPENSSL_memset(ret->session_id, 0, ret->session_id_length);
1062 OPENSSL_memcpy(ret->session_id, &number, sizeof(number));
David Benjamin0f653952015-10-18 14:28:01 -04001063 return ret;
1064}
1065
David Benjamin0f653952015-10-18 14:28:01 -04001066// Test that the internal session cache behaves as expected.
1067static bool TestInternalSessionCache() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001068 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin0f653952015-10-18 14:28:01 -04001069 if (!ctx) {
1070 return false;
1071 }
1072
1073 // Prepare 10 test sessions.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001074 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
David Benjamin0f653952015-10-18 14:28:01 -04001075 for (int i = 0; i < 10; i++) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001076 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
David Benjamin0f653952015-10-18 14:28:01 -04001077 if (!session) {
1078 return false;
1079 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001080 sessions.push_back(std::move(session));
David Benjamin0f653952015-10-18 14:28:01 -04001081 }
1082
1083 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1084
1085 // Insert all the test sessions.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001086 for (const auto &session : sessions) {
1087 if (!SSL_CTX_add_session(ctx.get(), session.get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001088 return false;
1089 }
1090 }
1091
1092 // Only the last five should be in the list.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001093 std::vector<SSL_SESSION*> expected = {
1094 sessions[9].get(),
1095 sessions[8].get(),
1096 sessions[7].get(),
1097 sessions[6].get(),
1098 sessions[5].get(),
1099 };
David Benjamin0f653952015-10-18 14:28:01 -04001100 if (!ExpectCache(ctx.get(), expected)) {
1101 return false;
1102 }
1103
1104 // Inserting an element already in the cache should fail.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001105 if (SSL_CTX_add_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001106 !ExpectCache(ctx.get(), expected)) {
1107 return false;
1108 }
1109
1110 // Although collisions should be impossible (256-bit session IDs), the cache
1111 // must handle them gracefully.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001112 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
David Benjamin0f653952015-10-18 14:28:01 -04001113 if (!collision || !SSL_CTX_add_session(ctx.get(), collision.get())) {
1114 return false;
1115 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001116 expected = {
1117 collision.get(),
1118 sessions[9].get(),
1119 sessions[8].get(),
1120 sessions[6].get(),
1121 sessions[5].get(),
1122 };
David Benjamin0f653952015-10-18 14:28:01 -04001123 if (!ExpectCache(ctx.get(), expected)) {
1124 return false;
1125 }
1126
1127 // Removing sessions behaves correctly.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001128 if (!SSL_CTX_remove_session(ctx.get(), sessions[6].get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001129 return false;
1130 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001131 expected = {
1132 collision.get(),
1133 sessions[9].get(),
1134 sessions[8].get(),
1135 sessions[5].get(),
1136 };
David Benjamin0f653952015-10-18 14:28:01 -04001137 if (!ExpectCache(ctx.get(), expected)) {
1138 return false;
1139 }
1140
1141 // Removing sessions requires an exact match.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001142 if (SSL_CTX_remove_session(ctx.get(), sessions[0].get()) ||
1143 SSL_CTX_remove_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001144 !ExpectCache(ctx.get(), expected)) {
1145 return false;
1146 }
1147
1148 return true;
1149}
1150
David Benjaminde942382016-02-11 12:02:01 -05001151static uint16_t EpochFromSequence(uint64_t seq) {
1152 return static_cast<uint16_t>(seq >> 48);
1153}
1154
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001155static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001156 static const char kCertPEM[] =
1157 "-----BEGIN CERTIFICATE-----\n"
1158 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1159 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1160 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1161 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1162 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1163 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1164 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1165 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1166 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1167 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1168 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1169 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1170 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1171 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001172 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
David Benjamin1444c3a2016-12-20 17:23:11 -05001173 return bssl::UniquePtr<X509>(
1174 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjaminde942382016-02-11 12:02:01 -05001175}
1176
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001177static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001178 static const char kKeyPEM[] =
1179 "-----BEGIN RSA PRIVATE KEY-----\n"
1180 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1181 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1182 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1183 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1184 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1185 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1186 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1187 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1188 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1189 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1190 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1191 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1192 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1193 "-----END RSA PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001194 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1195 return bssl::UniquePtr<EVP_PKEY>(
David Benjaminde942382016-02-11 12:02:01 -05001196 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1197}
1198
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001199static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001200 static const char kCertPEM[] =
1201 "-----BEGIN CERTIFICATE-----\n"
1202 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1203 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1204 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1205 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1206 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1207 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1208 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1209 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1210 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1211 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1212 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001213 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1214 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjamin0fc37ef2016-08-17 15:29:46 -04001215}
1216
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001217static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001218 static const char kKeyPEM[] =
1219 "-----BEGIN PRIVATE KEY-----\n"
1220 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1221 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1222 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1223 "-----END PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001224 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1225 return bssl::UniquePtr<EVP_PKEY>(
David Benjamin0fc37ef2016-08-17 15:29:46 -04001226 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1227}
1228
Adam Langleyd04ca952017-02-28 11:26:51 -08001229static bssl::UniquePtr<CRYPTO_BUFFER> BufferFromPEM(const char *pem) {
1230 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1231 char *name, *header;
1232 uint8_t *data;
1233 long data_len;
1234 if (!PEM_read_bio(bio.get(), &name, &header, &data,
1235 &data_len)) {
1236 return nullptr;
1237 }
1238 OPENSSL_free(name);
1239 OPENSSL_free(header);
1240
1241 auto ret = bssl::UniquePtr<CRYPTO_BUFFER>(
1242 CRYPTO_BUFFER_new(data, data_len, nullptr));
1243 OPENSSL_free(data);
1244 return ret;
1245}
1246
1247static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestCertificateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001248 static const char kCertPEM[] =
1249 "-----BEGIN CERTIFICATE-----\n"
1250 "MIIC0jCCAbqgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQiBD\n"
1251 "QTAeFw0xNjAyMjgyMDI3MDNaFw0yNjAyMjUyMDI3MDNaMBgxFjAUBgNVBAMMDUNs\n"
1252 "aWVudCBDZXJ0IEEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRvaz8\n"
1253 "CC/cshpCafJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/\n"
1254 "kLRcH89M/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3\n"
1255 "tHb+xs2PSs8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+c\n"
1256 "IDs2rQ+lP7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1\n"
1257 "z7C8jU50Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9V\n"
1258 "iLeXANgZi+Xx9KgfAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI\n"
1259 "KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBFEVbmYl+2RtNw\n"
1260 "rDftRDF1v2QUbcN2ouSnQDHxeDQdSgasLzT3ui8iYu0Rw2WWcZ0DV5e0ztGPhWq7\n"
1261 "AO0B120aFRMOY+4+bzu9Q2FFkQqc7/fKTvTDzIJI5wrMnFvUfzzvxh3OHWMYSs/w\n"
1262 "giq33hTKeHEq6Jyk3btCny0Ycecyc3yGXH10sizUfiHlhviCkDuESk8mFDwDDzqW\n"
1263 "ZF0IipzFbEDHoIxLlm3GQxpiLoEV4k8KYJp3R5KBLFyxM6UGPz8h72mIPCJp2RuK\n"
1264 "MYgF91UDvVzvnYm6TfseM2+ewKirC00GOrZ7rEcFvtxnKSqYf4ckqfNdSU1Y+RRC\n"
1265 "1ngWZ7Ih\n"
1266 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001267 return BufferFromPEM(kCertPEM);
David Benjamin1444c3a2016-12-20 17:23:11 -05001268}
1269
Adam Langleyd04ca952017-02-28 11:26:51 -08001270static bssl::UniquePtr<X509> X509FromBuffer(
1271 bssl::UniquePtr<CRYPTO_BUFFER> buffer) {
1272 if (!buffer) {
1273 return nullptr;
1274 }
1275 const uint8_t *derp = CRYPTO_BUFFER_data(buffer.get());
1276 return bssl::UniquePtr<X509>(
1277 d2i_X509(NULL, &derp, CRYPTO_BUFFER_len(buffer.get())));
1278}
1279
1280static bssl::UniquePtr<X509> GetChainTestCertificate() {
1281 return X509FromBuffer(GetChainTestCertificateBuffer());
1282}
1283
1284static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestIntermediateBuffer() {
David Benjamin1444c3a2016-12-20 17:23:11 -05001285 static const char kCertPEM[] =
1286 "-----BEGIN CERTIFICATE-----\n"
1287 "MIICwjCCAaqgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS\n"
1288 "b290IENBMB4XDTE2MDIyODIwMjcwM1oXDTI2MDIyNTIwMjcwM1owDzENMAsGA1UE\n"
1289 "AwwEQiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALsSCYmDip2D\n"
1290 "GkjFxw7ykz26JSjELkl6ArlYjFJ3aT/SCh8qbS4gln7RH8CPBd78oFdfhIKQrwtZ\n"
1291 "3/q21ykD9BAS3qHe2YdcJfm8/kWAy5DvXk6NXU4qX334KofBAEpgdA/igEFq1P1l\n"
1292 "HAuIfZCpMRfT+i5WohVsGi8f/NgpRvVaMONLNfgw57mz1lbtFeBEISmX0kbsuJxF\n"
1293 "Qj/Bwhi5/0HAEXG8e7zN4cEx0yPRvmOATRdVb/8dW2pwOHRJq9R5M0NUkIsTSnL7\n"
1294 "6N/z8hRAHMsV3IudC5Yd7GXW1AGu9a+iKU+Q4xcZCoj0DC99tL4VKujrV1kAeqsM\n"
1295 "cz5/dKzi6+cCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
1296 "AQYwDQYJKoZIhvcNAQELBQADggEBAIIeZiEeNhWWQ8Y4D+AGDwqUUeG8NjCbKrXQ\n"
1297 "BlHg5wZ8xftFaiP1Dp/UAezmx2LNazdmuwrYB8lm3FVTyaPDTKEGIPS4wJKHgqH1\n"
1298 "QPDhqNm85ey7TEtI9oYjsNim/Rb+iGkIAMXaxt58SzxbjvP0kMr1JfJIZbic9vye\n"
1299 "NwIspMFIpP3FB8ywyu0T0hWtCQgL4J47nigCHpOu58deP88fS/Nyz/fyGVWOZ76b\n"
1300 "WhWwgM3P3X95fQ3d7oFPR/bVh0YV+Cf861INwplokXgXQ3/TCQ+HNXeAMWn3JLWv\n"
1301 "XFwk8owk9dq/kQGdndGgy3KTEW4ctPX5GNhf3LJ9Q7dLji4ReQ4=\n"
1302 "-----END CERTIFICATE-----\n";
Adam Langleyd04ca952017-02-28 11:26:51 -08001303 return BufferFromPEM(kCertPEM);
1304}
1305
1306static bssl::UniquePtr<X509> GetChainTestIntermediate() {
1307 return X509FromBuffer(GetChainTestIntermediateBuffer());
David Benjamin1444c3a2016-12-20 17:23:11 -05001308}
1309
1310static bssl::UniquePtr<EVP_PKEY> GetChainTestKey() {
1311 static const char kKeyPEM[] =
1312 "-----BEGIN PRIVATE KEY-----\n"
1313 "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRvaz8CC/cshpC\n"
1314 "afJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/kLRcH89M\n"
1315 "/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3tHb+xs2P\n"
1316 "Ss8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+cIDs2rQ+l\n"
1317 "P7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1z7C8jU50\n"
1318 "Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9ViLeXANgZ\n"
1319 "i+Xx9KgfAgMBAAECggEBAK0VjSJzkyPaamcyTVSWjo7GdaBGcK60lk657RjR+lK0\n"
1320 "YJ7pkej4oM2hdsVZFsP8Cs4E33nXLa/0pDsRov/qrp0WQm2skwqGMC1I/bZ0WRPk\n"
1321 "wHaDrBBfESWnJDX/AGpVtlyOjPmgmK6J2usMPihQUDkKdAYrVWJePrMIxt1q6BMe\n"
1322 "iczs3qriMmtY3bUc4UyUwJ5fhDLjshHvfuIpYQyI6EXZM6dZksn9LylXJnigY6QJ\n"
1323 "HxOYO0BDwOsZ8yQ8J8afLk88i0GizEkgE1z3REtQUwgWfxr1WV/ud+T6/ZhSAgH9\n"
1324 "042mQvSFZnIUSEsmCvjhWuAunfxHKCTcAoYISWfzWpkCgYEA7gpf3HHU5Tn+CgUn\n"
1325 "1X5uGpG3DmcMgfeGgs2r2f/IIg/5Ac1dfYILiybL1tN9zbyLCJfcbFpWBc9hJL6f\n"
1326 "CPc5hUiwWFJqBJewxQkC1Ae/HakHbip+IZ+Jr0842O4BAArvixk4Lb7/N2Ct9sTE\n"
1327 "NJO6RtK9lbEZ5uK61DglHy8CS2UCgYEA4ZC1o36kPAMQBggajgnucb2yuUEelk0f\n"
1328 "AEr+GI32MGE+93xMr7rAhBoqLg4AITyIfEnOSQ5HwagnIHonBbv1LV/Gf9ursx8Z\n"
1329 "YOGbvT8zzzC+SU1bkDzdjAYnFQVGIjMtKOBJ3K07++ypwX1fr4QsQ8uKL8WSOWwt\n"
1330 "Z3Bym6XiZzMCgYADnhy+2OwHX85AkLt+PyGlPbmuelpyTzS4IDAQbBa6jcuW/2wA\n"
1331 "UE2km75VUXmD+u2R/9zVuLm99NzhFhSMqlUxdV1YukfqMfP5yp1EY6m/5aW7QuIP\n"
1332 "2MDa7TVL9rIFMiVZ09RKvbBbQxjhuzPQKL6X/PPspnhiTefQ+dl2k9xREQKBgHDS\n"
1333 "fMfGNEeAEKezrfSVqxphE9/tXms3L+ZpnCaT+yu/uEr5dTIAawKoQ6i9f/sf1/Sy\n"
1334 "xedsqR+IB+oKrzIDDWMgoJybN4pkZ8E5lzhVQIjFjKgFdWLzzqyW9z1gYfABQPlN\n"
1335 "FiS20WX0vgP1vcKAjdNrHzc9zyHBpgQzDmAj3NZZAoGBAI8vKCKdH7w3aL5CNkZQ\n"
1336 "2buIeWNA2HZazVwAGG5F2TU/LmXfRKnG6dX5bkU+AkBZh56jNZy//hfFSewJB4Kk\n"
1337 "buB7ERSdaNbO21zXt9FEA3+z0RfMd/Zv2vlIWOSB5nzl/7UKti3sribK6s9ZVLfi\n"
1338 "SxpiPQ8d/hmSGwn4ksrWUsJD\n"
1339 "-----END PRIVATE KEY-----\n";
1340 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1341 return bssl::UniquePtr<EVP_PKEY>(
1342 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1343}
1344
David Benjaminb79cc842016-12-07 15:57:14 -05001345static bool CompleteHandshakes(SSL *client, SSL *server) {
1346 // Drive both their handshakes to completion.
1347 for (;;) {
1348 int client_ret = SSL_do_handshake(client);
1349 int client_err = SSL_get_error(client, client_ret);
1350 if (client_err != SSL_ERROR_NONE &&
1351 client_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001352 client_err != SSL_ERROR_WANT_WRITE &&
1353 client_err != SSL_ERROR_PENDING_TICKET) {
David Benjaminb79cc842016-12-07 15:57:14 -05001354 fprintf(stderr, "Client error: %d\n", client_err);
1355 return false;
1356 }
1357
1358 int server_ret = SSL_do_handshake(server);
1359 int server_err = SSL_get_error(server, server_ret);
1360 if (server_err != SSL_ERROR_NONE &&
1361 server_err != SSL_ERROR_WANT_READ &&
Adam Langley4c341d02017-03-08 19:33:21 -08001362 server_err != SSL_ERROR_WANT_WRITE &&
1363 server_err != SSL_ERROR_PENDING_TICKET) {
David Benjaminb79cc842016-12-07 15:57:14 -05001364 fprintf(stderr, "Server error: %d\n", server_err);
1365 return false;
1366 }
1367
1368 if (client_ret == 1 && server_ret == 1) {
1369 break;
1370 }
1371 }
1372
1373 return true;
1374}
1375
1376static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client,
1377 bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001378 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1379 SSL_SESSION *session) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001380 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001381 if (!client || !server) {
1382 return false;
1383 }
1384 SSL_set_connect_state(client.get());
1385 SSL_set_accept_state(server.get());
1386
David Benjamina20e5352016-08-02 19:09:41 -04001387 SSL_set_session(client.get(), session);
1388
David Benjaminde942382016-02-11 12:02:01 -05001389 BIO *bio1, *bio2;
1390 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1391 return false;
1392 }
1393 // SSL_set_bio takes ownership.
1394 SSL_set_bio(client.get(), bio1, bio1);
1395 SSL_set_bio(server.get(), bio2, bio2);
1396
David Benjaminb79cc842016-12-07 15:57:14 -05001397 if (!CompleteHandshakes(client.get(), server.get())) {
1398 return false;
David Benjaminde942382016-02-11 12:02:01 -05001399 }
1400
David Benjamin686bb192016-05-10 15:15:41 -04001401 *out_client = std::move(client);
1402 *out_server = std::move(server);
1403 return true;
1404}
1405
David Benjamin0fef3052016-11-18 15:11:10 +09001406static bool TestSequenceNumber(bool is_dtls, const SSL_METHOD *method,
1407 uint16_t version) {
1408 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
1409 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
1410 if (!server_ctx || !client_ctx ||
1411 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
1412 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
1413 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
1414 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
1415 return false;
1416 }
David Benjamin686bb192016-05-10 15:15:41 -04001417
David Benjamin0fef3052016-11-18 15:11:10 +09001418 bssl::UniquePtr<X509> cert = GetTestCertificate();
1419 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
1420 if (!cert || !key || !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1421 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1422 return false;
1423 }
David Benjamin686bb192016-05-10 15:15:41 -04001424
David Benjamin0fef3052016-11-18 15:11:10 +09001425 bssl::UniquePtr<SSL> client, server;
1426 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
1427 server_ctx.get(), nullptr /* no session */)) {
1428 return false;
1429 }
David Benjamin686bb192016-05-10 15:15:41 -04001430
David Benjamin0fef3052016-11-18 15:11:10 +09001431 // Drain any post-handshake messages to ensure there are no unread records
1432 // on either end.
1433 uint8_t byte = 0;
1434 if (SSL_read(client.get(), &byte, 1) > 0 ||
1435 SSL_read(server.get(), &byte, 1) > 0) {
1436 fprintf(stderr, "Received unexpected data.\n");
1437 return false;
1438 }
David Benjaminde942382016-02-11 12:02:01 -05001439
David Benjamin0fef3052016-11-18 15:11:10 +09001440 uint64_t client_read_seq = SSL_get_read_sequence(client.get());
1441 uint64_t client_write_seq = SSL_get_write_sequence(client.get());
1442 uint64_t server_read_seq = SSL_get_read_sequence(server.get());
1443 uint64_t server_write_seq = SSL_get_write_sequence(server.get());
Steven Valdez2c62fe92016-10-14 12:08:12 -04001444
David Benjamin0fef3052016-11-18 15:11:10 +09001445 if (is_dtls) {
1446 // Both client and server must be at epoch 1.
1447 if (EpochFromSequence(client_read_seq) != 1 ||
1448 EpochFromSequence(client_write_seq) != 1 ||
1449 EpochFromSequence(server_read_seq) != 1 ||
1450 EpochFromSequence(server_write_seq) != 1) {
1451 fprintf(stderr, "Bad epochs.\n");
1452 return false;
David Benjaminde942382016-02-11 12:02:01 -05001453 }
David Benjamin0fef3052016-11-18 15:11:10 +09001454
1455 // The next record to be written should exceed the largest received.
1456 if (client_write_seq <= server_read_seq ||
1457 server_write_seq <= client_read_seq) {
1458 fprintf(stderr, "Inconsistent sequence numbers.\n");
1459 return false;
1460 }
1461 } else {
1462 // The next record to be written should equal the next to be received.
1463 if (client_write_seq != server_read_seq ||
1464 server_write_seq != client_read_seq) {
1465 fprintf(stderr, "Inconsistent sequence numbers.\n");
1466 return false;
1467 }
1468 }
1469
1470 // Send a record from client to server.
1471 if (SSL_write(client.get(), &byte, 1) != 1 ||
1472 SSL_read(server.get(), &byte, 1) != 1) {
1473 fprintf(stderr, "Could not send byte.\n");
1474 return false;
1475 }
1476
1477 // The client write and server read sequence numbers should have
1478 // incremented.
1479 if (client_write_seq + 1 != SSL_get_write_sequence(client.get()) ||
1480 server_read_seq + 1 != SSL_get_read_sequence(server.get())) {
1481 fprintf(stderr, "Sequence numbers did not increment.\n");
1482 return false;
David Benjaminde942382016-02-11 12:02:01 -05001483 }
1484
1485 return true;
1486}
1487
David Benjamin68f37b72016-11-18 15:14:42 +09001488static bool TestOneSidedShutdown(bool is_dtls, const SSL_METHOD *method,
1489 uint16_t version) {
1490 // SSL_shutdown is a no-op in DTLS.
1491 if (is_dtls) {
1492 return true;
David Benjamin686bb192016-05-10 15:15:41 -04001493 }
1494
David Benjamin68f37b72016-11-18 15:14:42 +09001495 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
1496 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001497 bssl::UniquePtr<X509> cert = GetTestCertificate();
1498 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin68f37b72016-11-18 15:14:42 +09001499 if (!client_ctx || !server_ctx || !cert || !key ||
1500 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
1501 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
1502 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
1503 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
David Benjamin686bb192016-05-10 15:15:41 -04001504 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1505 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1506 return false;
1507 }
1508
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001509 bssl::UniquePtr<SSL> client, server;
David Benjamin686bb192016-05-10 15:15:41 -04001510 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001511 server_ctx.get(), nullptr /* no session */)) {
David Benjamin686bb192016-05-10 15:15:41 -04001512 return false;
1513 }
1514
1515 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1516 // one side has shut down.
1517 if (SSL_shutdown(client.get()) != 0) {
1518 fprintf(stderr, "Could not shutdown.\n");
1519 return false;
1520 }
1521
1522 // Reading from the server should consume the EOF.
1523 uint8_t byte;
1524 if (SSL_read(server.get(), &byte, 1) != 0 ||
1525 SSL_get_error(server.get(), 0) != SSL_ERROR_ZERO_RETURN) {
1526 fprintf(stderr, "Connection was not shut down cleanly.\n");
1527 return false;
1528 }
1529
1530 // However, the server may continue to write data and then shut down the
1531 // connection.
1532 byte = 42;
1533 if (SSL_write(server.get(), &byte, 1) != 1 ||
1534 SSL_read(client.get(), &byte, 1) != 1 ||
1535 byte != 42) {
1536 fprintf(stderr, "Could not send byte.\n");
1537 return false;
1538 }
1539
1540 // The server may then shutdown the connection.
1541 if (SSL_shutdown(server.get()) != 1 ||
1542 SSL_shutdown(client.get()) != 1) {
1543 fprintf(stderr, "Could not complete shutdown.\n");
1544 return false;
1545 }
1546
1547 return true;
1548}
David Benjamin68f37b72016-11-18 15:14:42 +09001549
David Benjaminf0d8e222017-02-04 10:58:26 -05001550TEST(SSLTest, SessionDuplication) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001551 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1552 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001553 ASSERT_TRUE(client_ctx);
1554 ASSERT_TRUE(server_ctx);
Steven Valdez87eab492016-06-27 16:34:59 -04001555
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001556 bssl::UniquePtr<X509> cert = GetTestCertificate();
1557 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminf0d8e222017-02-04 10:58:26 -05001558 ASSERT_TRUE(cert);
1559 ASSERT_TRUE(key);
1560 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
1561 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04001562
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001563 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05001564 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
1565 server_ctx.get(),
1566 nullptr /* no session */));
Steven Valdez87eab492016-06-27 16:34:59 -04001567
1568 SSL_SESSION *session0 = SSL_get_session(client.get());
David Benjaminf0d8e222017-02-04 10:58:26 -05001569 bssl::UniquePtr<SSL_SESSION> session1(
1570 SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL));
1571 ASSERT_TRUE(session1);
David Benjamin4501bd52016-08-01 13:39:41 -04001572
Steven Valdez84b5c002016-08-25 16:30:58 -04001573 session1->not_resumable = 0;
1574
Steven Valdez87eab492016-06-27 16:34:59 -04001575 uint8_t *s0_bytes, *s1_bytes;
1576 size_t s0_len, s1_len;
1577
David Benjaminf0d8e222017-02-04 10:58:26 -05001578 ASSERT_TRUE(SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001579 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001580
David Benjaminf0d8e222017-02-04 10:58:26 -05001581 ASSERT_TRUE(SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001582 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001583
David Benjamin7d7554b2017-02-04 11:48:59 -05001584 EXPECT_EQ(Bytes(s0_bytes, s0_len), Bytes(s1_bytes, s1_len));
Steven Valdez87eab492016-06-27 16:34:59 -04001585}
David Benjamin686bb192016-05-10 15:15:41 -04001586
David Benjaminf0d8e222017-02-04 10:58:26 -05001587static void ExpectFDs(const SSL *ssl, int rfd, int wfd) {
1588 EXPECT_EQ(rfd, SSL_get_rfd(ssl));
1589 EXPECT_EQ(wfd, SSL_get_wfd(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04001590
1591 // The wrapper BIOs are always equal when fds are equal, even if set
1592 // individually.
David Benjaminf0d8e222017-02-04 10:58:26 -05001593 if (rfd == wfd) {
1594 EXPECT_EQ(SSL_get_rbio(ssl), SSL_get_wbio(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04001595 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001596}
1597
David Benjaminf0d8e222017-02-04 10:58:26 -05001598TEST(SSLTest, SetFD) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001599 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001600 ASSERT_TRUE(ctx);
David Benjamin5c0fb882016-06-14 14:03:51 -04001601
1602 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001603 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001604 ASSERT_TRUE(ssl);
1605 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1606 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
1607 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04001608
1609 // Test setting the same FD.
1610 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001611 ASSERT_TRUE(ssl);
1612 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1613 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001614
1615 // Test setting the same FD one side at a time.
1616 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001617 ASSERT_TRUE(ssl);
1618 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1619 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1620 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001621
1622 // Test setting the same FD in the other order.
1623 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001624 ASSERT_TRUE(ssl);
1625 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1626 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1627 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001628
David Benjamin5c0fb882016-06-14 14:03:51 -04001629 // Test changing the read FD partway through.
1630 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001631 ASSERT_TRUE(ssl);
1632 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1633 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 2));
1634 ExpectFDs(ssl.get(), 2, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001635
1636 // Test changing the write FD partway through.
1637 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001638 ASSERT_TRUE(ssl);
1639 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1640 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
1641 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04001642
1643 // Test a no-op change to the read FD partway through.
1644 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001645 ASSERT_TRUE(ssl);
1646 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1647 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1648 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001649
1650 // Test a no-op change to the write FD partway through.
1651 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001652 ASSERT_TRUE(ssl);
1653 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1654 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1655 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001656
1657 // ASan builds will implicitly test that the internal |BIO| reference-counting
1658 // is correct.
David Benjamin5c0fb882016-06-14 14:03:51 -04001659}
1660
David Benjaminf0d8e222017-02-04 10:58:26 -05001661TEST(SSLTest, SetBIO) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001662 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001663 ASSERT_TRUE(ctx);
David Benjamin4501bd52016-08-01 13:39:41 -04001664
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001665 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1666 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04001667 bio3(BIO_new(BIO_s_mem()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001668 ASSERT_TRUE(ssl);
1669 ASSERT_TRUE(bio1);
1670 ASSERT_TRUE(bio2);
1671 ASSERT_TRUE(bio3);
David Benjamin4501bd52016-08-01 13:39:41 -04001672
1673 // SSL_set_bio takes one reference when the parameters are the same.
1674 BIO_up_ref(bio1.get());
1675 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1676
1677 // Repeating the call does nothing.
1678 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1679
1680 // It takes one reference each when the parameters are different.
1681 BIO_up_ref(bio2.get());
1682 BIO_up_ref(bio3.get());
1683 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1684
1685 // Repeating the call does nothing.
1686 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1687
1688 // It takes one reference when changing only wbio.
1689 BIO_up_ref(bio1.get());
1690 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1691
1692 // It takes one reference when changing only rbio and the two are different.
1693 BIO_up_ref(bio3.get());
1694 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1695
1696 // If setting wbio to rbio, it takes no additional references.
1697 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1698
1699 // From there, wbio may be switched to something else.
1700 BIO_up_ref(bio1.get());
1701 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1702
1703 // If setting rbio to wbio, it takes no additional references.
1704 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1705
1706 // From there, rbio may be switched to something else, but, for historical
1707 // reasons, it takes a reference to both parameters.
1708 BIO_up_ref(bio1.get());
1709 BIO_up_ref(bio2.get());
1710 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1711
1712 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1713 // is correct.
David Benjamin4501bd52016-08-01 13:39:41 -04001714}
1715
David Benjamin25490f22016-07-14 00:22:54 -04001716static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1717
David Benjamin0fef3052016-11-18 15:11:10 +09001718static bool TestGetPeerCertificate(bool is_dtls, const SSL_METHOD *method,
1719 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001720 bssl::UniquePtr<X509> cert = GetTestCertificate();
1721 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminadd5e522016-07-14 00:33:24 -04001722 if (!cert || !key) {
1723 return false;
1724 }
1725
David Benjamin0fef3052016-11-18 15:11:10 +09001726 // Configure both client and server to accept any certificate.
1727 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
1728 if (!ctx ||
1729 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1730 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
1731 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1732 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
1733 return false;
1734 }
1735 SSL_CTX_set_verify(
1736 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1737 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
David Benjaminadd5e522016-07-14 00:33:24 -04001738
David Benjamin0fef3052016-11-18 15:11:10 +09001739 bssl::UniquePtr<SSL> client, server;
1740 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1741 nullptr /* no session */)) {
1742 return false;
1743 }
David Benjaminadd5e522016-07-14 00:33:24 -04001744
David Benjamin0fef3052016-11-18 15:11:10 +09001745 // Client and server should both see the leaf certificate.
1746 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
1747 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1748 fprintf(stderr, "Server peer certificate did not match.\n");
1749 return false;
1750 }
David Benjaminadd5e522016-07-14 00:33:24 -04001751
David Benjamin0fef3052016-11-18 15:11:10 +09001752 peer.reset(SSL_get_peer_certificate(client.get()));
1753 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1754 fprintf(stderr, "Client peer certificate did not match.\n");
1755 return false;
1756 }
David Benjaminadd5e522016-07-14 00:33:24 -04001757
David Benjamin0fef3052016-11-18 15:11:10 +09001758 // However, for historical reasons, the chain includes the leaf on the
1759 // client, but does not on the server.
1760 if (sk_X509_num(SSL_get_peer_cert_chain(client.get())) != 1) {
1761 fprintf(stderr, "Client peer chain was incorrect.\n");
1762 return false;
1763 }
David Benjaminadd5e522016-07-14 00:33:24 -04001764
David Benjamin0fef3052016-11-18 15:11:10 +09001765 if (sk_X509_num(SSL_get_peer_cert_chain(server.get())) != 0) {
1766 fprintf(stderr, "Server peer chain was incorrect.\n");
1767 return false;
David Benjaminadd5e522016-07-14 00:33:24 -04001768 }
1769
1770 return true;
1771}
1772
David Benjamin0fef3052016-11-18 15:11:10 +09001773static bool TestRetainOnlySHA256OfCerts(bool is_dtls, const SSL_METHOD *method,
1774 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001775 bssl::UniquePtr<X509> cert = GetTestCertificate();
1776 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin25490f22016-07-14 00:22:54 -04001777 if (!cert || !key) {
1778 return false;
1779 }
1780
1781 uint8_t *cert_der = NULL;
1782 int cert_der_len = i2d_X509(cert.get(), &cert_der);
1783 if (cert_der_len < 0) {
1784 return false;
1785 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001786 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04001787
1788 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1789 SHA256(cert_der, cert_der_len, cert_sha256);
1790
David Benjamin0fef3052016-11-18 15:11:10 +09001791 // Configure both client and server to accept any certificate, but the
1792 // server must retain only the SHA-256 of the peer.
1793 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
1794 if (!ctx ||
1795 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1796 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
1797 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1798 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
1799 return false;
1800 }
1801 SSL_CTX_set_verify(
1802 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1803 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1804 SSL_CTX_set_retain_only_sha256_of_client_certs(ctx.get(), 1);
David Benjamin25490f22016-07-14 00:22:54 -04001805
David Benjamin0fef3052016-11-18 15:11:10 +09001806 bssl::UniquePtr<SSL> client, server;
1807 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1808 nullptr /* no session */)) {
1809 return false;
1810 }
David Benjamin25490f22016-07-14 00:22:54 -04001811
David Benjamin0fef3052016-11-18 15:11:10 +09001812 // The peer certificate has been dropped.
1813 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
1814 if (peer) {
1815 fprintf(stderr, "Peer certificate was retained.\n");
1816 return false;
1817 }
David Benjamin25490f22016-07-14 00:22:54 -04001818
David Benjamin0fef3052016-11-18 15:11:10 +09001819 SSL_SESSION *session = SSL_get_session(server.get());
1820 if (!session->peer_sha256_valid) {
1821 fprintf(stderr, "peer_sha256_valid was not set.\n");
1822 return false;
1823 }
David Benjamin25490f22016-07-14 00:22:54 -04001824
David Benjamin17cf2cb2016-12-13 01:07:13 -05001825 if (OPENSSL_memcmp(cert_sha256, session->peer_sha256, SHA256_DIGEST_LENGTH) !=
1826 0) {
David Benjamin0fef3052016-11-18 15:11:10 +09001827 fprintf(stderr, "peer_sha256 did not match.\n");
1828 return false;
David Benjamin25490f22016-07-14 00:22:54 -04001829 }
1830
1831 return true;
1832}
1833
David Benjaminafc64de2016-07-19 17:12:41 +02001834static bool ClientHelloMatches(uint16_t version, const uint8_t *expected,
1835 size_t expected_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001836 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001837 // Our default cipher list varies by CPU capabilities, so manually place the
1838 // ChaCha20 ciphers in front.
Matthew Braithwaite7e06de52017-04-10 15:52:14 -07001839 const char* cipher_list = "CHACHA20:ALL";
David Benjamin2dc02042016-09-19 19:57:37 -04001840 if (!ctx ||
David Benjamin3cfeb952017-03-01 16:48:38 -05001841 // SSLv3 is off by default.
1842 !SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION) ||
David Benjamine4706902016-09-20 15:12:23 -04001843 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001844 !SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list)) {
David Benjaminafc64de2016-07-19 17:12:41 +02001845 return false;
1846 }
David Benjamin2dc02042016-09-19 19:57:37 -04001847
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001848 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +02001849 if (!ssl) {
1850 return false;
1851 }
1852 std::vector<uint8_t> client_hello;
1853 if (!GetClientHello(ssl.get(), &client_hello)) {
1854 return false;
1855 }
1856
1857 // Zero the client_random.
1858 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
1859 1 + 3 + // handshake message header
1860 2; // client_version
1861 if (client_hello.size() < kRandomOffset + SSL3_RANDOM_SIZE) {
1862 fprintf(stderr, "ClientHello for version %04x too short.\n", version);
1863 return false;
1864 }
David Benjamin17cf2cb2016-12-13 01:07:13 -05001865 OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
David Benjaminafc64de2016-07-19 17:12:41 +02001866
1867 if (client_hello.size() != expected_len ||
David Benjamin17cf2cb2016-12-13 01:07:13 -05001868 OPENSSL_memcmp(client_hello.data(), expected, expected_len) != 0) {
David Benjaminafc64de2016-07-19 17:12:41 +02001869 fprintf(stderr, "ClientHello for version %04x did not match:\n", version);
1870 fprintf(stderr, "Got:\n\t");
1871 for (size_t i = 0; i < client_hello.size(); i++) {
1872 fprintf(stderr, "0x%02x, ", client_hello[i]);
1873 }
1874 fprintf(stderr, "\nWanted:\n\t");
1875 for (size_t i = 0; i < expected_len; i++) {
1876 fprintf(stderr, "0x%02x, ", expected[i]);
1877 }
1878 fprintf(stderr, "\n");
1879 return false;
1880 }
1881
1882 return true;
1883}
1884
1885// Tests that our ClientHellos do not change unexpectedly.
1886static bool TestClientHello() {
1887 static const uint8_t kSSL3ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001888 0x16,
1889 0x03, 0x00,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001890 0x00, 0x3b,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001891 0x01,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001892 0x00, 0x00, 0x37,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001893 0x03, 0x00,
1894 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1895 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1896 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1897 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1898 0x00,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001899 0x00, 0x10,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001900 0xc0, 0x09,
1901 0xc0, 0x13,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001902 0xc0, 0x0a,
1903 0xc0, 0x14,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001904 0x00, 0x2f,
1905 0x00, 0x35,
1906 0x00, 0x0a,
1907 0x00, 0xff, 0x01, 0x00,
David Benjaminafc64de2016-07-19 17:12:41 +02001908 };
1909 if (!ClientHelloMatches(SSL3_VERSION, kSSL3ClientHello,
1910 sizeof(kSSL3ClientHello))) {
1911 return false;
1912 }
1913
1914 static const uint8_t kTLS1ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001915 0x16,
1916 0x03, 0x01,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001917 0x00, 0x5a,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001918 0x01,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001919 0x00, 0x00, 0x56,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001920 0x03, 0x01,
1921 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1922 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1923 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1924 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1925 0x00,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001926 0x00, 0x0e,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001927 0xc0, 0x09,
1928 0xc0, 0x13,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001929 0xc0, 0x0a,
1930 0xc0, 0x14,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001931 0x00, 0x2f,
1932 0x00, 0x35,
1933 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001934 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1935 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1936 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1937 };
1938 if (!ClientHelloMatches(TLS1_VERSION, kTLS1ClientHello,
1939 sizeof(kTLS1ClientHello))) {
1940 return false;
1941 }
1942
1943 static const uint8_t kTLS11ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001944 0x16,
1945 0x03, 0x01,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001946 0x00, 0x5a,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001947 0x01,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001948 0x00, 0x00, 0x56,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001949 0x03, 0x02,
1950 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1951 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1952 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1953 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1954 0x00,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001955 0x00, 0x0e,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001956 0xc0, 0x09,
1957 0xc0, 0x13,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001958 0xc0, 0x0a,
1959 0xc0, 0x14,
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001960 0x00, 0x2f,
1961 0x00, 0x35,
1962 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001963 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1964 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1965 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1966 };
1967 if (!ClientHelloMatches(TLS1_1_VERSION, kTLS11ClientHello,
1968 sizeof(kTLS11ClientHello))) {
1969 return false;
1970 }
1971
David Benjamin3b584332017-01-24 22:47:18 -05001972 // kTLS12ClientHello assumes RSA-PSS, which is disabled for Android system
1973 // builds.
1974#if defined(BORINGSSL_ANDROID_SYSTEM)
1975 return true;
1976#endif
1977
David Benjaminafc64de2016-07-19 17:12:41 +02001978 static const uint8_t kTLS12ClientHello[] = {
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001979 0x16,
1980 0x03, 0x01,
1981 0x00, 0x8e,
1982 0x01,
1983 0x00, 0x00, 0x8a,
1984 0x03, 0x03,
David Benjamin57e929f2016-08-30 00:30:38 -04001985 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1986 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Matthew Braithwaitecedc6f12017-03-15 19:20:23 -07001987 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1988 0x00, 0x2a,
1989 0xcc, 0xa9,
1990 0xcc, 0xa8,
1991 0xc0, 0x2b,
1992 0xc0, 0x2f,
1993 0xc0, 0x2c,
1994 0xc0, 0x30,
1995 0xc0, 0x09,
1996 0xc0, 0x23,
1997 0xc0, 0x13,
1998 0xc0, 0x27,
1999 0xc0, 0x0a,
2000 0xc0, 0x24,
2001 0xc0, 0x14,
2002 0xc0, 0x28,
2003 0x00, 0x9c,
2004 0x00, 0x9d,
2005 0x00, 0x2f,
2006 0x00, 0x3c,
2007 0x00, 0x35,
2008 0x00, 0x3d,
2009 0x00, 0x0a,
2010 0x01, 0x00, 0x00, 0x37, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
2011 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04,
2012 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08,
2013 0x06, 0x06, 0x01, 0x02, 0x01, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
2014 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
David Benjaminafc64de2016-07-19 17:12:41 +02002015 };
2016 if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
2017 sizeof(kTLS12ClientHello))) {
2018 return false;
2019 }
2020
2021 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
2022 // implementation has settled enough that it won't change.
2023
2024 return true;
2025}
2026
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002027static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04002028
2029static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
2030 // Save the most recent session.
2031 g_last_session.reset(session);
2032 return 1;
2033}
2034
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002035static bssl::UniquePtr<SSL_SESSION> CreateClientSession(SSL_CTX *client_ctx,
David Benjamina20e5352016-08-02 19:09:41 -04002036 SSL_CTX *server_ctx) {
2037 g_last_session = nullptr;
2038 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2039
2040 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002041 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04002042 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
2043 nullptr /* no session */)) {
2044 fprintf(stderr, "Failed to connect client and server.\n");
2045 return nullptr;
2046 }
2047
2048 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2049 SSL_read(client.get(), nullptr, 0);
2050
2051 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2052
2053 if (!g_last_session) {
2054 fprintf(stderr, "Client did not receive a session.\n");
2055 return nullptr;
2056 }
2057 return std::move(g_last_session);
2058}
2059
2060static bool ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
2061 SSL_SESSION *session,
2062 bool reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002063 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04002064 if (!ConnectClientAndServer(&client, &server, client_ctx,
2065 server_ctx, session)) {
2066 fprintf(stderr, "Failed to connect client and server.\n");
2067 return false;
2068 }
2069
2070 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2071 fprintf(stderr, "Client and server were inconsistent.\n");
2072 return false;
2073 }
2074
2075 bool was_reused = !!SSL_session_reused(client.get());
2076 if (was_reused != reused) {
2077 fprintf(stderr, "Session was%s reused, but we expected the opposite.\n",
2078 was_reused ? "" : " not");
2079 return false;
2080 }
2081
2082 return true;
2083}
2084
David Benjamin3c51d9b2016-11-01 17:50:42 -04002085static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
2086 SSL_CTX *server_ctx,
2087 SSL_SESSION *session) {
2088 g_last_session = nullptr;
2089 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2090
2091 bssl::UniquePtr<SSL> client, server;
2092 if (!ConnectClientAndServer(&client, &server, client_ctx,
2093 server_ctx, session)) {
2094 fprintf(stderr, "Failed to connect client and server.\n");
2095 return nullptr;
2096 }
2097
2098 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2099 fprintf(stderr, "Client and server were inconsistent.\n");
2100 return nullptr;
2101 }
2102
2103 if (!SSL_session_reused(client.get())) {
2104 fprintf(stderr, "Session was not reused.\n");
2105 return nullptr;
2106 }
2107
2108 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2109 SSL_read(client.get(), nullptr, 0);
2110
2111 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2112
2113 if (!g_last_session) {
2114 fprintf(stderr, "Client did not receive a renewed session.\n");
2115 return nullptr;
2116 }
2117 return std::move(g_last_session);
2118}
2119
David Benjamina933c382016-10-28 00:10:03 -04002120static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
2121 static const uint8_t kContext[] = {3};
2122
2123 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
2124 return SSL_TLSEXT_ERR_ALERT_FATAL;
2125 }
2126
2127 return SSL_TLSEXT_ERR_OK;
2128}
2129
David Benjamin0fef3052016-11-18 15:11:10 +09002130static bool TestSessionIDContext(bool is_dtls, const SSL_METHOD *method,
2131 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002132 bssl::UniquePtr<X509> cert = GetTestCertificate();
2133 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamina20e5352016-08-02 19:09:41 -04002134 if (!cert || !key) {
2135 return false;
2136 }
2137
2138 static const uint8_t kContext1[] = {1};
2139 static const uint8_t kContext2[] = {2};
2140
David Benjamin0fef3052016-11-18 15:11:10 +09002141 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2142 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2143 if (!server_ctx || !client_ctx ||
2144 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2145 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2146 !SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
2147 sizeof(kContext1)) ||
2148 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2149 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2150 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2151 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2152 return false;
2153 }
David Benjamina20e5352016-08-02 19:09:41 -04002154
David Benjamin0fef3052016-11-18 15:11:10 +09002155 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2156 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002157
David Benjamin0fef3052016-11-18 15:11:10 +09002158 bssl::UniquePtr<SSL_SESSION> session =
2159 CreateClientSession(client_ctx.get(), server_ctx.get());
2160 if (!session) {
2161 fprintf(stderr, "Error getting session.\n");
2162 return false;
2163 }
David Benjamina20e5352016-08-02 19:09:41 -04002164
David Benjamin0fef3052016-11-18 15:11:10 +09002165 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2166 true /* expect session reused */)) {
2167 fprintf(stderr, "Error resuming session.\n");
2168 return false;
2169 }
David Benjamina20e5352016-08-02 19:09:41 -04002170
David Benjamin0fef3052016-11-18 15:11:10 +09002171 // Change the session ID context.
2172 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext2,
2173 sizeof(kContext2))) {
2174 return false;
2175 }
David Benjamina20e5352016-08-02 19:09:41 -04002176
David Benjamin0fef3052016-11-18 15:11:10 +09002177 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2178 false /* expect session not reused */)) {
2179 fprintf(stderr, "Error connecting with a different context.\n");
2180 return false;
2181 }
David Benjamina933c382016-10-28 00:10:03 -04002182
David Benjamin0fef3052016-11-18 15:11:10 +09002183 // Change the session ID context back and install an SNI callback to switch
2184 // it.
2185 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
2186 sizeof(kContext1))) {
2187 return false;
2188 }
David Benjamina933c382016-10-28 00:10:03 -04002189
David Benjamin0fef3052016-11-18 15:11:10 +09002190 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(),
2191 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04002192
David Benjamin0fef3052016-11-18 15:11:10 +09002193 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2194 false /* expect session not reused */)) {
2195 fprintf(stderr, "Error connecting with a context switch on SNI callback.\n");
2196 return false;
2197 }
David Benjamina933c382016-10-28 00:10:03 -04002198
David Benjamin0fef3052016-11-18 15:11:10 +09002199 // Switch the session ID context with the early callback instead.
2200 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), nullptr);
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002201 SSL_CTX_set_select_certificate_cb(
2202 server_ctx.get(),
2203 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
2204 static const uint8_t kContext[] = {3};
2205
2206 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
2207 sizeof(kContext))) {
2208 return ssl_select_cert_error;
2209 }
2210
2211 return ssl_select_cert_success;
2212 });
David Benjamina933c382016-10-28 00:10:03 -04002213
David Benjamin0fef3052016-11-18 15:11:10 +09002214 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2215 false /* expect session not reused */)) {
2216 fprintf(stderr,
2217 "Error connecting with a context switch on early callback.\n");
2218 return false;
David Benjamina20e5352016-08-02 19:09:41 -04002219 }
2220
2221 return true;
2222}
2223
David Benjamin721e8b72016-08-03 13:13:17 -04002224static timeval g_current_time;
2225
2226static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2227 *out_clock = g_current_time;
2228}
2229
David Benjamin17b30832017-01-28 14:00:32 -05002230static void FrozenTimeCallback(const SSL *ssl, timeval *out_clock) {
2231 out_clock->tv_sec = 1000;
2232 out_clock->tv_usec = 0;
2233}
2234
David Benjamin3c51d9b2016-11-01 17:50:42 -04002235static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
2236 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
2237 int encrypt) {
2238 static const uint8_t kZeros[16] = {0};
2239
2240 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -05002241 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamin3c51d9b2016-11-01 17:50:42 -04002242 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -05002243 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002244 return 0;
2245 }
2246
2247 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
2248 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
2249 return -1;
2250 }
2251
2252 // Returning two from the callback in decrypt mode renews the
2253 // session in TLS 1.2 and below.
2254 return encrypt ? 1 : 2;
2255}
2256
David Benjamin123db572016-11-03 16:59:25 -04002257static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjamin123db572016-11-03 16:59:25 -04002258 if (session->tlsext_ticklen < 16 + 16 + SHA256_DIGEST_LENGTH) {
2259 return false;
2260 }
2261
David Benjamin123db572016-11-03 16:59:25 -04002262 const uint8_t *ciphertext = session->tlsext_tick + 16 + 16;
2263 size_t len = session->tlsext_ticklen - 16 - 16 - SHA256_DIGEST_LENGTH;
2264 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
2265
David Benjamin9b63f292016-11-15 00:44:05 -05002266#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
2267 // Fuzzer-mode tickets are unencrypted.
David Benjamin17cf2cb2016-12-13 01:07:13 -05002268 OPENSSL_memcpy(plaintext.get(), ciphertext, len);
David Benjamin9b63f292016-11-15 00:44:05 -05002269#else
2270 static const uint8_t kZeros[16] = {0};
2271 const uint8_t *iv = session->tlsext_tick + 16;
David Benjamin123db572016-11-03 16:59:25 -04002272 bssl::ScopedEVP_CIPHER_CTX ctx;
2273 int len1, len2;
2274 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
2275 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
2276 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
2277 return false;
2278 }
2279
2280 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05002281#endif
David Benjamin123db572016-11-03 16:59:25 -04002282
Adam Langley46db7af2017-02-01 15:49:37 -08002283 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
2284 if (!ssl_ctx) {
2285 return false;
2286 }
David Benjamin123db572016-11-03 16:59:25 -04002287 bssl::UniquePtr<SSL_SESSION> server_session(
Adam Langley46db7af2017-02-01 15:49:37 -08002288 SSL_SESSION_from_bytes(plaintext.get(), len, ssl_ctx.get()));
David Benjamin123db572016-11-03 16:59:25 -04002289 if (!server_session) {
2290 return false;
2291 }
2292
2293 *out = server_session->time;
2294 return true;
2295}
2296
David Benjamin0fef3052016-11-18 15:11:10 +09002297static bool TestSessionTimeout(bool is_dtls, const SSL_METHOD *method,
2298 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002299 bssl::UniquePtr<X509> cert = GetTestCertificate();
2300 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin721e8b72016-08-03 13:13:17 -04002301 if (!cert || !key) {
2302 return false;
2303 }
2304
David Benjamin0fef3052016-11-18 15:11:10 +09002305 for (bool server_test : std::vector<bool>{false, true}) {
David Benjamin17b30832017-01-28 14:00:32 -05002306 static const time_t kStartTime = 1000;
David Benjamin0fef3052016-11-18 15:11:10 +09002307 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002308
David Benjamin17b30832017-01-28 14:00:32 -05002309 // We are willing to use a longer lifetime for TLS 1.3 sessions as
2310 // resumptions still perform ECDHE.
2311 const time_t timeout = version == TLS1_3_VERSION
2312 ? SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT
2313 : SSL_DEFAULT_SESSION_TIMEOUT;
2314
David Benjamin0fef3052016-11-18 15:11:10 +09002315 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2316 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2317 if (!server_ctx || !client_ctx ||
2318 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2319 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2320 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2321 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2322 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2323 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2324 return false;
2325 }
2326
2327 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2328 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
2329
David Benjamin17b30832017-01-28 14:00:32 -05002330 // Both client and server must enforce session timeouts. We configure the
2331 // other side with a frozen clock so it never expires tickets.
David Benjamin0fef3052016-11-18 15:11:10 +09002332 if (server_test) {
David Benjamin17b30832017-01-28 14:00:32 -05002333 SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002334 SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
2335 } else {
2336 SSL_CTX_set_current_time_cb(client_ctx.get(), CurrentTimeCallback);
David Benjamin17b30832017-01-28 14:00:32 -05002337 SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002338 }
2339
2340 // Configure a ticket callback which renews tickets.
2341 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx.get(), RenewTicketCallback);
2342
2343 bssl::UniquePtr<SSL_SESSION> session =
2344 CreateClientSession(client_ctx.get(), server_ctx.get());
2345 if (!session) {
2346 fprintf(stderr, "Error getting session.\n");
2347 return false;
2348 }
2349
2350 // Advance the clock just behind the timeout.
David Benjamin17b30832017-01-28 14:00:32 -05002351 g_current_time.tv_sec += timeout - 1;
David Benjamin0fef3052016-11-18 15:11:10 +09002352
2353 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2354 true /* expect session reused */)) {
2355 fprintf(stderr, "Error resuming session.\n");
2356 return false;
2357 }
2358
2359 // Advance the clock one more second.
2360 g_current_time.tv_sec++;
2361
2362 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2363 false /* expect session not reused */)) {
2364 fprintf(stderr, "Error resuming session.\n");
2365 return false;
2366 }
2367
2368 // Rewind the clock to before the session was minted.
2369 g_current_time.tv_sec = kStartTime - 1;
2370
2371 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2372 false /* expect session not reused */)) {
2373 fprintf(stderr, "Error resuming session.\n");
2374 return false;
2375 }
2376
2377 // SSL 3.0 cannot renew sessions.
2378 if (version == SSL3_VERSION) {
2379 continue;
2380 }
2381
2382 // Renew the session 10 seconds before expiration.
David Benjamin17b30832017-01-28 14:00:32 -05002383 time_t new_start_time = kStartTime + timeout - 10;
2384 g_current_time.tv_sec = new_start_time;
David Benjamin0fef3052016-11-18 15:11:10 +09002385 bssl::UniquePtr<SSL_SESSION> new_session =
2386 ExpectSessionRenewed(client_ctx.get(), server_ctx.get(), session.get());
2387 if (!new_session) {
2388 fprintf(stderr, "Error renewing session.\n");
2389 return false;
2390 }
2391
2392 // This new session is not the same object as before.
2393 if (session.get() == new_session.get()) {
2394 fprintf(stderr, "New and old sessions alias.\n");
2395 return false;
2396 }
2397
2398 // Check the sessions have timestamps measured from issuance.
2399 long session_time = 0;
2400 if (server_test) {
2401 if (!GetServerTicketTime(&session_time, new_session.get())) {
2402 fprintf(stderr, "Failed to decode session ticket.\n");
David Benjaminb2e2e322016-11-01 17:32:54 -04002403 return false;
2404 }
David Benjamin0fef3052016-11-18 15:11:10 +09002405 } else {
2406 session_time = new_session->time;
2407 }
David Benjamin721e8b72016-08-03 13:13:17 -04002408
David Benjamin0fef3052016-11-18 15:11:10 +09002409 if (session_time != g_current_time.tv_sec) {
2410 fprintf(stderr, "New session is not measured from issuance.\n");
2411 return false;
2412 }
David Benjamin721e8b72016-08-03 13:13:17 -04002413
David Benjamin17b30832017-01-28 14:00:32 -05002414 if (version == TLS1_3_VERSION) {
2415 // Renewal incorporates fresh key material in TLS 1.3, so we extend the
2416 // lifetime TLS 1.3.
2417 g_current_time.tv_sec = new_start_time + timeout - 1;
2418 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2419 new_session.get(),
2420 true /* expect session reused */)) {
2421 fprintf(stderr, "Error resuming renewed session.\n");
2422 return false;
2423 }
David Benjamin721e8b72016-08-03 13:13:17 -04002424
David Benjamin17b30832017-01-28 14:00:32 -05002425 // The new session expires after the new timeout.
2426 g_current_time.tv_sec = new_start_time + timeout + 1;
2427 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2428 new_session.get(),
2429 false /* expect session ot reused */)) {
2430 fprintf(stderr, "Renewed session's lifetime is too long.\n");
2431 return false;
2432 }
2433
2434 // Renew the session until it begins just past the auth timeout.
2435 time_t auth_end_time = kStartTime + SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
2436 while (new_start_time < auth_end_time - 1000) {
2437 // Get as close as possible to target start time.
2438 new_start_time =
2439 std::min(auth_end_time - 1000, new_start_time + timeout - 1);
2440 g_current_time.tv_sec = new_start_time;
2441 new_session = ExpectSessionRenewed(client_ctx.get(), server_ctx.get(),
2442 new_session.get());
2443 if (!new_session) {
2444 fprintf(stderr, "Error renewing session.\n");
2445 return false;
2446 }
2447 }
2448
2449 // Now the session's lifetime is bound by the auth timeout.
2450 g_current_time.tv_sec = auth_end_time - 1;
2451 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2452 new_session.get(),
2453 true /* expect session reused */)) {
2454 fprintf(stderr, "Error resuming renewed session.\n");
2455 return false;
2456 }
2457
2458 g_current_time.tv_sec = auth_end_time + 1;
2459 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2460 new_session.get(),
2461 false /* expect session ot reused */)) {
2462 fprintf(stderr, "Renewed session's lifetime is too long.\n");
2463 return false;
2464 }
2465 } else {
2466 // The new session is usable just before the old expiration.
2467 g_current_time.tv_sec = kStartTime + timeout - 1;
2468 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2469 new_session.get(),
2470 true /* expect session reused */)) {
2471 fprintf(stderr, "Error resuming renewed session.\n");
2472 return false;
2473 }
2474
2475 // Renewal does not extend the lifetime, so it is not usable beyond the
2476 // old expiration.
2477 g_current_time.tv_sec = kStartTime + timeout + 1;
2478 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2479 new_session.get(),
2480 false /* expect session not reused */)) {
2481 fprintf(stderr, "Renewed session's lifetime is too long.\n");
2482 return false;
2483 }
David Benjamin1b22f852016-10-27 16:36:32 -04002484 }
David Benjamin721e8b72016-08-03 13:13:17 -04002485 }
2486
2487 return true;
2488}
2489
David Benjamin0fc37ef2016-08-17 15:29:46 -04002490static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
2491 SSL_CTX *ctx = reinterpret_cast<SSL_CTX*>(arg);
2492 SSL_set_SSL_CTX(ssl, ctx);
2493 return SSL_TLSEXT_ERR_OK;
2494}
2495
David Benjamin0fef3052016-11-18 15:11:10 +09002496static bool TestSNICallback(bool is_dtls, const SSL_METHOD *method,
2497 uint16_t version) {
2498 // SSL 3.0 lacks extensions.
2499 if (version == SSL3_VERSION) {
2500 return true;
2501 }
2502
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002503 bssl::UniquePtr<X509> cert = GetTestCertificate();
2504 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2505 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
2506 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
David Benjamin0fc37ef2016-08-17 15:29:46 -04002507 if (!cert || !key || !cert2 || !key2) {
2508 return false;
2509 }
2510
David Benjamin0fef3052016-11-18 15:11:10 +09002511 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
2512 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002513
David Benjamin83a32122017-02-14 18:34:54 -05002514 static const uint8_t kSCTList[] = {0, 6, 0, 4, 5, 6, 7, 8};
2515 static const uint8_t kOCSPResponse[] = {1, 2, 3, 4};
2516
David Benjamin0fef3052016-11-18 15:11:10 +09002517 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2518 bssl::UniquePtr<SSL_CTX> server_ctx2(SSL_CTX_new(method));
2519 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2520 if (!server_ctx || !server_ctx2 || !client_ctx ||
2521 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2522 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2523 !SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()) ||
2524 !SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()) ||
David Benjamin83a32122017-02-14 18:34:54 -05002525 !SSL_CTX_set_signed_cert_timestamp_list(server_ctx2.get(), kSCTList,
2526 sizeof(kSCTList)) ||
2527 !SSL_CTX_set_ocsp_response(server_ctx2.get(), kOCSPResponse,
2528 sizeof(kOCSPResponse)) ||
David Benjamin0fef3052016-11-18 15:11:10 +09002529 // Historically signing preferences would be lost in some cases with the
2530 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2531 // this doesn't happen when |version| is TLS 1.2, configure the private
2532 // key to only sign SHA-256.
2533 !SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(), &kECDSAWithSHA256,
2534 1) ||
2535 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2536 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2537 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2538 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2539 !SSL_CTX_set_min_proto_version(server_ctx2.get(), version) ||
2540 !SSL_CTX_set_max_proto_version(server_ctx2.get(), version)) {
2541 return false;
2542 }
David Benjamin0fc37ef2016-08-17 15:29:46 -04002543
David Benjamin0fef3052016-11-18 15:11:10 +09002544 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), SwitchContext);
2545 SSL_CTX_set_tlsext_servername_arg(server_ctx.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002546
David Benjamin83a32122017-02-14 18:34:54 -05002547 SSL_CTX_enable_signed_cert_timestamps(client_ctx.get());
2548 SSL_CTX_enable_ocsp_stapling(client_ctx.get());
2549
David Benjamin0fef3052016-11-18 15:11:10 +09002550 bssl::UniquePtr<SSL> client, server;
2551 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2552 server_ctx.get(), nullptr)) {
2553 fprintf(stderr, "Handshake failed.\n");
2554 return false;
2555 }
David Benjamin0fc37ef2016-08-17 15:29:46 -04002556
David Benjamin0fef3052016-11-18 15:11:10 +09002557 // The client should have received |cert2|.
2558 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client.get()));
2559 if (!peer || X509_cmp(peer.get(), cert2.get()) != 0) {
2560 fprintf(stderr, "Incorrect certificate received.\n");
2561 return false;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002562 }
2563
David Benjamin83a32122017-02-14 18:34:54 -05002564 // The client should have received |server_ctx2|'s SCT list.
2565 const uint8_t *data;
2566 size_t len;
2567 SSL_get0_signed_cert_timestamp_list(client.get(), &data, &len);
2568 if (Bytes(kSCTList) != Bytes(data, len)) {
2569 fprintf(stderr, "Incorrect SCT list received.\n");
2570 return false;
2571 }
2572
2573 // The client should have received |server_ctx2|'s OCSP response.
2574 SSL_get0_ocsp_response(client.get(), &data, &len);
2575 if (Bytes(kOCSPResponse) != Bytes(data, len)) {
2576 fprintf(stderr, "Incorrect OCSP response received.\n");
2577 return false;
2578 }
2579
David Benjamin0fc37ef2016-08-17 15:29:46 -04002580 return true;
2581}
2582
David Benjaminf0d8e222017-02-04 10:58:26 -05002583// Test that the early callback can swap the maximum version.
2584TEST(SSLTest, EarlyCallbackVersionSwitch) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002585 bssl::UniquePtr<X509> cert = GetTestCertificate();
2586 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2587 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2588 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002589 ASSERT_TRUE(cert);
2590 ASSERT_TRUE(key);
2591 ASSERT_TRUE(server_ctx);
2592 ASSERT_TRUE(client_ctx);
2593 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
2594 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
2595 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
2596 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
David Benjamin99620572016-08-30 00:35:36 -04002597
David Benjaminf0d8e222017-02-04 10:58:26 -05002598 SSL_CTX_set_select_certificate_cb(
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002599 server_ctx.get(),
2600 [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
David Benjaminf0d8e222017-02-04 10:58:26 -05002601 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002602 return ssl_select_cert_error;
David Benjaminf0d8e222017-02-04 10:58:26 -05002603 }
2604
Alessandro Ghedini57e81e62017-03-14 23:36:00 +00002605 return ssl_select_cert_success;
David Benjaminf0d8e222017-02-04 10:58:26 -05002606 });
David Benjamin99620572016-08-30 00:35:36 -04002607
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002608 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05002609 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
2610 server_ctx.get(), nullptr));
2611 EXPECT_EQ(TLS1_2_VERSION, SSL_version(client.get()));
David Benjamin99620572016-08-30 00:35:36 -04002612}
2613
David Benjaminf0d8e222017-02-04 10:58:26 -05002614TEST(SSLTest, SetVersion) {
David Benjamin2dc02042016-09-19 19:57:37 -04002615 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002616 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002617
David Benjaminf0d8e222017-02-04 10:58:26 -05002618 // Set valid TLS versions.
2619 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2620 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
2621 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2622 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002623
David Benjaminf0d8e222017-02-04 10:58:26 -05002624 // Invalid TLS versions are rejected.
2625 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2626 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x0200));
2627 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2628 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2629 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x0200));
2630 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002631
David Benjaminf0d8e222017-02-04 10:58:26 -05002632 // Zero is the default version.
2633 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
2634 EXPECT_EQ(TLS1_2_VERSION, ctx->max_version);
2635 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
David Benjamin3cfeb952017-03-01 16:48:38 -05002636 EXPECT_EQ(TLS1_VERSION, ctx->min_version);
2637
2638 // SSL 3.0 and TLS 1.3 are available, but not by default.
2639 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION));
David Benjaminf0d8e222017-02-04 10:58:26 -05002640 EXPECT_EQ(SSL3_VERSION, ctx->min_version);
David Benjamin3cfeb952017-03-01 16:48:38 -05002641 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
2642 EXPECT_EQ(TLS1_3_VERSION, ctx->max_version);
David Benjamine34bcc92016-09-21 16:53:09 -04002643
David Benjamin2dc02042016-09-19 19:57:37 -04002644 ctx.reset(SSL_CTX_new(DTLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002645 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002646
David Benjaminf0d8e222017-02-04 10:58:26 -05002647 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2648 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION));
2649 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2650 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002651
David Benjaminf0d8e222017-02-04 10:58:26 -05002652 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2653 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2654 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2655 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2656 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2657 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2658 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2659 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002660
David Benjaminf0d8e222017-02-04 10:58:26 -05002661 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
2662 EXPECT_EQ(TLS1_2_VERSION, ctx->max_version);
2663 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
2664 EXPECT_EQ(TLS1_1_VERSION, ctx->min_version);
David Benjamin2dc02042016-09-19 19:57:37 -04002665}
2666
David Benjamin458334a2016-12-15 13:53:25 -05002667static const char *GetVersionName(uint16_t version) {
2668 switch (version) {
2669 case SSL3_VERSION:
2670 return "SSLv3";
2671 case TLS1_VERSION:
2672 return "TLSv1";
2673 case TLS1_1_VERSION:
2674 return "TLSv1.1";
2675 case TLS1_2_VERSION:
2676 return "TLSv1.2";
2677 case TLS1_3_VERSION:
2678 return "TLSv1.3";
2679 case DTLS1_VERSION:
2680 return "DTLSv1";
2681 case DTLS1_2_VERSION:
2682 return "DTLSv1.2";
2683 default:
2684 return "???";
2685 }
2686}
2687
David Benjamin0fef3052016-11-18 15:11:10 +09002688static bool TestVersion(bool is_dtls, const SSL_METHOD *method,
2689 uint16_t version) {
David Benjamincb18ac22016-09-27 14:09:15 -04002690 bssl::UniquePtr<X509> cert = GetTestCertificate();
2691 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2692 if (!cert || !key) {
2693 return false;
2694 }
2695
David Benjamin0fef3052016-11-18 15:11:10 +09002696 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2697 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2698 bssl::UniquePtr<SSL> client, server;
2699 if (!server_ctx || !client_ctx ||
2700 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2701 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2702 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2703 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2704 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2705 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2706 !ConnectClientAndServer(&client, &server, client_ctx.get(),
2707 server_ctx.get(), nullptr /* no session */)) {
2708 fprintf(stderr, "Failed to connect.\n");
2709 return false;
2710 }
David Benjamincb18ac22016-09-27 14:09:15 -04002711
David Benjamin0fef3052016-11-18 15:11:10 +09002712 if (SSL_version(client.get()) != version ||
2713 SSL_version(server.get()) != version) {
2714 fprintf(stderr, "Version mismatch. Got %04x and %04x, wanted %04x.\n",
2715 SSL_version(client.get()), SSL_version(server.get()), version);
2716 return false;
David Benjamincb18ac22016-09-27 14:09:15 -04002717 }
2718
David Benjamin458334a2016-12-15 13:53:25 -05002719 // Test the version name is reported as expected.
2720 const char *version_name = GetVersionName(version);
2721 if (strcmp(version_name, SSL_get_version(client.get())) != 0 ||
2722 strcmp(version_name, SSL_get_version(server.get())) != 0) {
2723 fprintf(stderr, "Version name mismatch. Got '%s' and '%s', wanted '%s'.\n",
2724 SSL_get_version(client.get()), SSL_get_version(server.get()),
2725 version_name);
2726 return false;
2727 }
2728
2729 // Test SSL_SESSION reports the same name.
2730 const char *client_name =
2731 SSL_SESSION_get_version(SSL_get_session(client.get()));
2732 const char *server_name =
2733 SSL_SESSION_get_version(SSL_get_session(server.get()));
2734 if (strcmp(version_name, client_name) != 0 ||
2735 strcmp(version_name, server_name) != 0) {
2736 fprintf(stderr,
2737 "Session version name mismatch. Got '%s' and '%s', wanted '%s'.\n",
2738 client_name, server_name, version_name);
2739 return false;
2740 }
2741
David Benjamincb18ac22016-09-27 14:09:15 -04002742 return true;
2743}
2744
David Benjamin9ef31f02016-10-31 18:01:13 -04002745// Tests that that |SSL_get_pending_cipher| is available during the ALPN
2746// selection callback.
David Benjamin0fef3052016-11-18 15:11:10 +09002747static bool TestALPNCipherAvailable(bool is_dtls, const SSL_METHOD *method,
2748 uint16_t version) {
2749 // SSL 3.0 lacks extensions.
2750 if (version == SSL3_VERSION) {
2751 return true;
2752 }
2753
David Benjamin9ef31f02016-10-31 18:01:13 -04002754 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
2755
2756 bssl::UniquePtr<X509> cert = GetTestCertificate();
2757 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2758 if (!cert || !key) {
2759 return false;
2760 }
2761
David Benjamin0fef3052016-11-18 15:11:10 +09002762 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
2763 if (!ctx || !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
2764 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
2765 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
2766 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
2767 SSL_CTX_set_alpn_protos(ctx.get(), kALPNProtos, sizeof(kALPNProtos)) !=
2768 0) {
2769 return false;
2770 }
2771
2772 // The ALPN callback does not fail the handshake on error, so have the
2773 // callback write a boolean.
2774 std::pair<uint16_t, bool> callback_state(version, false);
2775 SSL_CTX_set_alpn_select_cb(
2776 ctx.get(),
2777 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
2778 unsigned in_len, void *arg) -> int {
2779 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
2780 if (SSL_get_pending_cipher(ssl) != nullptr &&
2781 SSL_version(ssl) == state->first) {
2782 state->second = true;
2783 }
2784 return SSL_TLSEXT_ERR_NOACK;
2785 },
2786 &callback_state);
2787
2788 bssl::UniquePtr<SSL> client, server;
2789 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2790 nullptr /* no session */)) {
2791 return false;
2792 }
2793
2794 if (!callback_state.second) {
2795 fprintf(stderr, "The pending cipher was not known in the ALPN callback.\n");
2796 return false;
2797 }
2798
2799 return true;
2800}
2801
David Benjaminb79cc842016-12-07 15:57:14 -05002802static bool TestSSLClearSessionResumption(bool is_dtls,
2803 const SSL_METHOD *method,
2804 uint16_t version) {
2805 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
2806 // API pattern.
2807 if (version == TLS1_3_VERSION) {
2808 return true;
2809 }
2810
2811 bssl::UniquePtr<X509> cert = GetTestCertificate();
2812 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2813 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2814 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2815 if (!cert || !key || !server_ctx || !client_ctx ||
2816 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2817 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2818 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2819 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2820 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2821 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2822 return false;
2823 }
2824
2825 // Connect a client and a server.
2826 bssl::UniquePtr<SSL> client, server;
2827 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2828 server_ctx.get(), nullptr /* no session */)) {
2829 return false;
2830 }
2831
2832 if (SSL_session_reused(client.get()) ||
2833 SSL_session_reused(server.get())) {
2834 fprintf(stderr, "Session unexpectedly reused.\n");
2835 return false;
2836 }
2837
2838 // Reset everything.
2839 if (!SSL_clear(client.get()) ||
2840 !SSL_clear(server.get())) {
2841 fprintf(stderr, "SSL_clear failed.\n");
2842 return false;
2843 }
2844
2845 // Attempt to connect a second time.
2846 if (!CompleteHandshakes(client.get(), server.get())) {
2847 fprintf(stderr, "Could not reuse SSL objects.\n");
2848 return false;
2849 }
2850
2851 // |SSL_clear| should implicitly offer the previous session to the server.
2852 if (!SSL_session_reused(client.get()) ||
2853 !SSL_session_reused(server.get())) {
2854 fprintf(stderr, "Session was not reused in second try.\n");
2855 return false;
2856 }
2857
2858 return true;
2859}
2860
David Benjamin1444c3a2016-12-20 17:23:11 -05002861static bool ChainsEqual(STACK_OF(X509) *chain,
2862 const std::vector<X509 *> &expected) {
2863 if (sk_X509_num(chain) != expected.size()) {
2864 return false;
2865 }
2866
2867 for (size_t i = 0; i < expected.size(); i++) {
2868 if (X509_cmp(sk_X509_value(chain, i), expected[i]) != 0) {
2869 return false;
2870 }
2871 }
2872
2873 return true;
2874}
2875
2876static bool TestAutoChain(bool is_dtls, const SSL_METHOD *method,
2877 uint16_t version) {
David Benjamin1444c3a2016-12-20 17:23:11 -05002878 bssl::UniquePtr<X509> cert = GetChainTestCertificate();
2879 bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
2880 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
2881 if (!cert || !intermediate || !key) {
2882 return false;
2883 }
2884
2885 // Configure both client and server to accept any certificate. Add
2886 // |intermediate| to the cert store.
2887 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
2888 if (!ctx ||
2889 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
2890 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
2891 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
2892 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
2893 !X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx.get()),
2894 intermediate.get())) {
2895 return false;
2896 }
2897 SSL_CTX_set_verify(
2898 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
2899 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
2900
2901 // By default, the client and server should each only send the leaf.
2902 bssl::UniquePtr<SSL> client, server;
2903 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2904 nullptr /* no session */)) {
2905 return false;
2906 }
2907
2908 if (!ChainsEqual(SSL_get_peer_full_cert_chain(client.get()), {cert.get()})) {
2909 fprintf(stderr, "Client-received chain did not match.\n");
2910 return false;
2911 }
2912
2913 if (!ChainsEqual(SSL_get_peer_full_cert_chain(server.get()), {cert.get()})) {
2914 fprintf(stderr, "Server-received chain did not match.\n");
2915 return false;
2916 }
2917
2918 // If auto-chaining is enabled, then the intermediate is sent.
2919 SSL_CTX_clear_mode(ctx.get(), SSL_MODE_NO_AUTO_CHAIN);
2920 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2921 nullptr /* no session */)) {
2922 return false;
2923 }
2924
2925 if (!ChainsEqual(SSL_get_peer_full_cert_chain(client.get()),
2926 {cert.get(), intermediate.get()})) {
2927 fprintf(stderr, "Client-received chain did not match (auto-chaining).\n");
2928 return false;
2929 }
2930
2931 if (!ChainsEqual(SSL_get_peer_full_cert_chain(server.get()),
2932 {cert.get(), intermediate.get()})) {
2933 fprintf(stderr, "Server-received chain did not match (auto-chaining).\n");
2934 return false;
2935 }
2936
2937 // Auto-chaining does not override explicitly-configured intermediates.
2938 if (!SSL_CTX_add1_chain_cert(ctx.get(), cert.get()) ||
2939 !ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2940 nullptr /* no session */)) {
2941 return false;
2942 }
2943
2944 if (!ChainsEqual(SSL_get_peer_full_cert_chain(client.get()),
2945 {cert.get(), cert.get()})) {
2946 fprintf(stderr,
2947 "Client-received chain did not match (auto-chaining, explicit "
2948 "intermediate).\n");
2949 return false;
2950 }
2951
2952 if (!ChainsEqual(SSL_get_peer_full_cert_chain(server.get()),
2953 {cert.get(), cert.get()})) {
2954 fprintf(stderr,
2955 "Server-received chain did not match (auto-chaining, explicit "
2956 "intermediate).\n");
2957 return false;
2958 }
2959
2960 return true;
2961}
2962
David Benjamin48063c22017-01-01 23:56:36 -05002963static bool ExpectBadWriteRetry() {
2964 int err = ERR_get_error();
2965 if (ERR_GET_LIB(err) != ERR_LIB_SSL ||
2966 ERR_GET_REASON(err) != SSL_R_BAD_WRITE_RETRY) {
2967 char buf[ERR_ERROR_STRING_BUF_LEN];
2968 ERR_error_string_n(err, buf, sizeof(buf));
2969 fprintf(stderr, "Wanted SSL_R_BAD_WRITE_RETRY, got: %s.\n", buf);
2970 return false;
2971 }
2972
2973 if (ERR_peek_error() != 0) {
2974 fprintf(stderr, "Unexpected error following SSL_R_BAD_WRITE_RETRY.\n");
2975 return false;
2976 }
2977
2978 return true;
2979}
2980
2981static bool TestSSLWriteRetry(bool is_dtls, const SSL_METHOD *method,
2982 uint16_t version) {
2983 if (is_dtls) {
2984 return true;
2985 }
2986
2987 for (bool enable_partial_write : std::vector<bool>{false, true}) {
2988 // Connect a client and server.
2989 bssl::UniquePtr<X509> cert = GetTestCertificate();
2990 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2991 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
2992 bssl::UniquePtr<SSL> client, server;
2993 if (!cert || !key || !ctx ||
2994 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
2995 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
2996 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
2997 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
2998 !ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2999 nullptr /* no session */)) {
3000 return false;
3001 }
3002
3003 if (enable_partial_write) {
3004 SSL_set_mode(client.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
3005 }
3006
3007 // Write without reading until the buffer is full and we have an unfinished
3008 // write. Keep a count so we may reread it again later. "hello!" will be
3009 // written in two chunks, "hello" and "!".
3010 char data[] = "hello!";
3011 static const int kChunkLen = 5; // The length of "hello".
3012 unsigned count = 0;
3013 for (;;) {
3014 int ret = SSL_write(client.get(), data, kChunkLen);
3015 if (ret <= 0) {
3016 int err = SSL_get_error(client.get(), ret);
3017 if (SSL_get_error(client.get(), ret) == SSL_ERROR_WANT_WRITE) {
3018 break;
3019 }
3020 fprintf(stderr, "SSL_write failed in unexpected way: %d\n", err);
3021 return false;
3022 }
3023
3024 if (ret != 5) {
3025 fprintf(stderr, "SSL_write wrote %d bytes, expected 5.\n", ret);
3026 return false;
3027 }
3028
3029 count++;
3030 }
3031
3032 // Retrying with the same parameters is legal.
3033 if (SSL_get_error(client.get(), SSL_write(client.get(), data, kChunkLen)) !=
3034 SSL_ERROR_WANT_WRITE) {
3035 fprintf(stderr, "SSL_write retry unexpectedly failed.\n");
3036 return false;
3037 }
3038
3039 // Retrying with the same buffer but shorter length is not legal.
3040 if (SSL_get_error(client.get(),
3041 SSL_write(client.get(), data, kChunkLen - 1)) !=
3042 SSL_ERROR_SSL ||
3043 !ExpectBadWriteRetry()) {
3044 fprintf(stderr, "SSL_write retry did not fail as expected.\n");
3045 return false;
3046 }
3047
3048 // Retrying with a different buffer pointer is not legal.
3049 char data2[] = "hello";
3050 if (SSL_get_error(client.get(), SSL_write(client.get(), data2,
3051 kChunkLen)) != SSL_ERROR_SSL ||
3052 !ExpectBadWriteRetry()) {
3053 fprintf(stderr, "SSL_write retry did not fail as expected.\n");
3054 return false;
3055 }
3056
3057 // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move.
3058 SSL_set_mode(client.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
3059 if (SSL_get_error(client.get(),
3060 SSL_write(client.get(), data2, kChunkLen)) !=
3061 SSL_ERROR_WANT_WRITE) {
3062 fprintf(stderr, "SSL_write retry unexpectedly failed.\n");
3063 return false;
3064 }
3065
3066 // |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| does not disable length checks.
3067 if (SSL_get_error(client.get(),
3068 SSL_write(client.get(), data2, kChunkLen - 1)) !=
3069 SSL_ERROR_SSL ||
3070 !ExpectBadWriteRetry()) {
3071 fprintf(stderr, "SSL_write retry did not fail as expected.\n");
3072 return false;
3073 }
3074
3075 // Retrying with a larger buffer is legal.
3076 if (SSL_get_error(client.get(),
3077 SSL_write(client.get(), data, kChunkLen + 1)) !=
3078 SSL_ERROR_WANT_WRITE) {
3079 fprintf(stderr, "SSL_write retry unexpectedly failed.\n");
3080 return false;
3081 }
3082
3083 // Drain the buffer.
3084 char buf[20];
3085 for (unsigned i = 0; i < count; i++) {
3086 if (SSL_read(server.get(), buf, sizeof(buf)) != kChunkLen ||
3087 OPENSSL_memcmp(buf, "hello", kChunkLen) != 0) {
3088 fprintf(stderr, "Failed to read initial records.\n");
3089 return false;
3090 }
3091 }
3092
3093 // Now that there is space, a retry with a larger buffer should flush the
3094 // pending record, skip over that many bytes of input (on assumption they
3095 // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE
3096 // is set, this will complete in two steps.
3097 char data3[] = "_____!";
3098 if (enable_partial_write) {
3099 if (SSL_write(client.get(), data3, kChunkLen + 1) != kChunkLen ||
3100 SSL_write(client.get(), data3 + kChunkLen, 1) != 1) {
3101 fprintf(stderr, "SSL_write retry failed.\n");
3102 return false;
3103 }
3104 } else if (SSL_write(client.get(), data3, kChunkLen + 1) != kChunkLen + 1) {
3105 fprintf(stderr, "SSL_write retry failed.\n");
3106 return false;
3107 }
3108
3109 // Check the last write was correct. The data will be spread over two
3110 // records, so SSL_read returns twice.
3111 if (SSL_read(server.get(), buf, sizeof(buf)) != kChunkLen ||
3112 OPENSSL_memcmp(buf, "hello", kChunkLen) != 0 ||
3113 SSL_read(server.get(), buf, sizeof(buf)) != 1 ||
3114 buf[0] != '!') {
3115 fprintf(stderr, "Failed to read write retry.\n");
3116 return false;
3117 }
3118 }
3119
3120 return true;
3121}
3122
David Benjamin0fef3052016-11-18 15:11:10 +09003123static bool ForEachVersion(bool (*test_func)(bool is_dtls,
3124 const SSL_METHOD *method,
3125 uint16_t version)) {
3126 static uint16_t kTLSVersions[] = {
David Benjamin3b584332017-01-24 22:47:18 -05003127 SSL3_VERSION,
3128 TLS1_VERSION,
3129 TLS1_1_VERSION,
3130 TLS1_2_VERSION,
3131// TLS 1.3 requires RSA-PSS, which is disabled for Android system builds.
3132#if !defined(BORINGSSL_ANDROID_SYSTEM)
3133 TLS1_3_VERSION,
3134#endif
David Benjamin0fef3052016-11-18 15:11:10 +09003135 };
3136
3137 static uint16_t kDTLSVersions[] = {
3138 DTLS1_VERSION, DTLS1_2_VERSION,
3139 };
3140
David Benjamin9ef31f02016-10-31 18:01:13 -04003141 for (uint16_t version : kTLSVersions) {
David Benjamin0fef3052016-11-18 15:11:10 +09003142 if (!test_func(false, TLS_method(), version)) {
3143 fprintf(stderr, "Test failed at TLS version %04x.\n", version);
David Benjamin9ef31f02016-10-31 18:01:13 -04003144 return false;
3145 }
David Benjamin0fef3052016-11-18 15:11:10 +09003146 }
David Benjamin9ef31f02016-10-31 18:01:13 -04003147
David Benjamin0fef3052016-11-18 15:11:10 +09003148 for (uint16_t version : kDTLSVersions) {
3149 if (!test_func(true, DTLS_method(), version)) {
3150 fprintf(stderr, "Test failed at DTLS version %04x.\n", version);
David Benjamin9ef31f02016-10-31 18:01:13 -04003151 return false;
3152 }
3153 }
3154
3155 return true;
3156}
3157
Adam Langleye1e78132017-01-31 15:24:31 -08003158TEST(SSLTest, AddChainCertHack) {
3159 // Ensure that we don't accidently break the hack that we have in place to
3160 // keep curl and serf happy when they use an |X509| even after transfering
3161 // ownership.
3162
3163 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3164 ASSERT_TRUE(ctx);
3165 X509 *cert = GetTestCertificate().release();
3166 ASSERT_TRUE(cert);
3167 SSL_CTX_add0_chain_cert(ctx.get(), cert);
3168
3169 // This should not trigger a use-after-free.
3170 X509_cmp(cert, cert);
3171}
3172
David Benjaminb2ff2622017-02-03 17:06:18 -05003173TEST(SSLTest, GetCertificate) {
3174 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3175 ASSERT_TRUE(ctx);
3176 bssl::UniquePtr<X509> cert = GetTestCertificate();
3177 ASSERT_TRUE(cert);
3178 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
3179 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3180 ASSERT_TRUE(ssl);
3181
3182 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
3183 ASSERT_TRUE(cert2);
3184 X509 *cert3 = SSL_get_certificate(ssl.get());
3185 ASSERT_TRUE(cert3);
3186
3187 // The old and new certificates must be identical.
3188 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
3189 EXPECT_EQ(0, X509_cmp(cert.get(), cert3));
3190
3191 uint8_t *der = nullptr;
3192 long der_len = i2d_X509(cert.get(), &der);
3193 ASSERT_LT(0, der_len);
3194 bssl::UniquePtr<uint8_t> free_der(der);
3195
3196 uint8_t *der2 = nullptr;
3197 long der2_len = i2d_X509(cert2, &der2);
3198 ASSERT_LT(0, der2_len);
3199 bssl::UniquePtr<uint8_t> free_der2(der2);
3200
3201 uint8_t *der3 = nullptr;
3202 long der3_len = i2d_X509(cert3, &der3);
3203 ASSERT_LT(0, der3_len);
3204 bssl::UniquePtr<uint8_t> free_der3(der3);
3205
3206 // They must also encode identically.
David Benjamin7d7554b2017-02-04 11:48:59 -05003207 EXPECT_EQ(Bytes(der, der_len), Bytes(der2, der2_len));
3208 EXPECT_EQ(Bytes(der, der_len), Bytes(der3, der3_len));
David Benjaminb2ff2622017-02-03 17:06:18 -05003209}
3210
Adam Langleyd04ca952017-02-28 11:26:51 -08003211TEST(SSLTest, SetChainAndKeyMismatch) {
3212 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_with_buffers_method()));
3213 ASSERT_TRUE(ctx);
3214
3215 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3216 ASSERT_TRUE(key);
3217 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3218 ASSERT_TRUE(leaf);
3219 std::vector<CRYPTO_BUFFER*> chain = {
3220 leaf.get(),
3221 };
3222
3223 // Should fail because |GetTestKey| doesn't match the chain-test certificate.
3224 ASSERT_FALSE(SSL_CTX_set_chain_and_key(ctx.get(), &chain[0], chain.size(),
3225 key.get(), nullptr));
3226 ERR_clear_error();
3227}
3228
3229TEST(SSLTest, SetChainAndKey) {
3230 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3231 ASSERT_TRUE(client_ctx);
3232 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
3233 ASSERT_TRUE(server_ctx);
3234
3235 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
3236 ASSERT_TRUE(key);
3237 bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
3238 ASSERT_TRUE(leaf);
3239 bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
3240 GetChainTestIntermediateBuffer();
3241 ASSERT_TRUE(intermediate);
3242 std::vector<CRYPTO_BUFFER*> chain = {
3243 leaf.get(), intermediate.get(),
3244 };
3245 ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), &chain[0],
3246 chain.size(), key.get(), nullptr));
3247
3248 SSL_CTX_i_promise_to_verify_certs_after_the_handshake(client_ctx.get());
3249
3250 bssl::UniquePtr<SSL> client, server;
3251 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3252 server_ctx.get(),
3253 nullptr /* no session */));
3254}
3255
David Benjamin91222b82017-03-09 20:10:56 -05003256// Configuring the empty cipher list, though an error, should still modify the
3257// configuration.
3258TEST(SSLTest, EmptyCipherList) {
3259 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3260 ASSERT_TRUE(ctx);
3261
3262 // Initially, the cipher list is not empty.
3263 EXPECT_NE(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3264
3265 // Configuring the empty cipher list fails.
3266 EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), ""));
3267 ERR_clear_error();
3268
3269 // But the cipher list is still updated to empty.
3270 EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
3271}
3272
Adam Langley4c341d02017-03-08 19:33:21 -08003273// ssl_test_ticket_aead_failure_mode enumerates the possible ways in which the
3274// test |SSL_TICKET_AEAD_METHOD| can fail.
3275enum ssl_test_ticket_aead_failure_mode {
3276 ssl_test_ticket_aead_ok = 0,
3277 ssl_test_ticket_aead_seal_fail,
3278 ssl_test_ticket_aead_open_soft_fail,
3279 ssl_test_ticket_aead_open_hard_fail,
3280};
3281
3282struct ssl_test_ticket_aead_state {
3283 unsigned retry_count;
3284 ssl_test_ticket_aead_failure_mode failure_mode;
3285};
3286
3287static int ssl_test_ticket_aead_ex_index_dup(CRYPTO_EX_DATA *to,
3288 const CRYPTO_EX_DATA *from,
3289 void **from_d, int index,
3290 long argl, void *argp) {
3291 abort();
3292}
3293
3294static void ssl_test_ticket_aead_ex_index_free(void *parent, void *ptr,
3295 CRYPTO_EX_DATA *ad, int index,
3296 long argl, void *argp) {
3297 auto state = reinterpret_cast<ssl_test_ticket_aead_state*>(ptr);
3298 if (state == nullptr) {
3299 return;
3300 }
3301
3302 OPENSSL_free(state);
3303}
3304
3305static CRYPTO_once_t g_ssl_test_ticket_aead_ex_index_once = CRYPTO_ONCE_INIT;
3306static int g_ssl_test_ticket_aead_ex_index;
3307
3308static int ssl_test_ticket_aead_get_ex_index() {
3309 CRYPTO_once(&g_ssl_test_ticket_aead_ex_index_once, [] {
3310 g_ssl_test_ticket_aead_ex_index = SSL_get_ex_new_index(
3311 0, nullptr, nullptr, ssl_test_ticket_aead_ex_index_dup,
3312 ssl_test_ticket_aead_ex_index_free);
3313 });
3314 return g_ssl_test_ticket_aead_ex_index;
3315}
3316
3317static size_t ssl_test_ticket_aead_max_overhead(SSL *ssl) {
3318 return 1;
3319}
3320
3321static int ssl_test_ticket_aead_seal(SSL *ssl, uint8_t *out, size_t *out_len,
3322 size_t max_out_len, const uint8_t *in,
3323 size_t in_len) {
3324 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3325 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3326
3327 if (state->failure_mode == ssl_test_ticket_aead_seal_fail ||
3328 max_out_len < in_len + 1) {
3329 return 0;
3330 }
3331
3332 OPENSSL_memmove(out, in, in_len);
3333 out[in_len] = 0xff;
3334 *out_len = in_len + 1;
3335
3336 return 1;
3337}
3338
3339static ssl_ticket_aead_result_t ssl_test_ticket_aead_open(
3340 SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len,
3341 const uint8_t *in, size_t in_len) {
3342 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3343 SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
3344
3345 if (state->retry_count > 0) {
3346 state->retry_count--;
3347 return ssl_ticket_aead_retry;
3348 }
3349
3350 switch (state->failure_mode) {
3351 case ssl_test_ticket_aead_ok:
3352 break;
3353 case ssl_test_ticket_aead_seal_fail:
3354 // If |seal| failed then there shouldn't be any ticket to try and
3355 // decrypt.
3356 abort();
3357 break;
3358 case ssl_test_ticket_aead_open_soft_fail:
3359 return ssl_ticket_aead_ignore_ticket;
3360 case ssl_test_ticket_aead_open_hard_fail:
3361 return ssl_ticket_aead_error;
3362 }
3363
3364 if (in_len == 0 || in[in_len - 1] != 0xff) {
3365 return ssl_ticket_aead_ignore_ticket;
3366 }
3367
3368 if (max_out_len < in_len - 1) {
3369 return ssl_ticket_aead_error;
3370 }
3371
3372 OPENSSL_memmove(out, in, in_len - 1);
3373 *out_len = in_len - 1;
3374 return ssl_ticket_aead_success;
3375}
3376
3377static const SSL_TICKET_AEAD_METHOD kSSLTestTicketMethod = {
3378 ssl_test_ticket_aead_max_overhead,
3379 ssl_test_ticket_aead_seal,
3380 ssl_test_ticket_aead_open,
3381};
3382
3383static void ConnectClientAndServerWithTicketMethod(
3384 bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
3385 SSL_CTX *client_ctx, SSL_CTX *server_ctx, unsigned retry_count,
3386 ssl_test_ticket_aead_failure_mode failure_mode, SSL_SESSION *session) {
3387 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
3388 ASSERT_TRUE(client);
3389 ASSERT_TRUE(server);
3390 SSL_set_connect_state(client.get());
3391 SSL_set_accept_state(server.get());
3392
3393 auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
3394 OPENSSL_malloc(sizeof(ssl_test_ticket_aead_state)));
3395 ASSERT_TRUE(state);
3396 OPENSSL_memset(state, 0, sizeof(ssl_test_ticket_aead_state));
3397 state->retry_count = retry_count;
3398 state->failure_mode = failure_mode;
3399
3400 ASSERT_TRUE(SSL_set_ex_data(server.get(), ssl_test_ticket_aead_get_ex_index(),
3401 state));
3402
3403 SSL_set_session(client.get(), session);
3404
3405 BIO *bio1, *bio2;
3406 ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
3407
3408 // SSL_set_bio takes ownership.
3409 SSL_set_bio(client.get(), bio1, bio1);
3410 SSL_set_bio(server.get(), bio2, bio2);
3411
3412 if (CompleteHandshakes(client.get(), server.get())) {
3413 *out_client = std::move(client);
3414 *out_server = std::move(server);
3415 } else {
3416 out_client->reset();
3417 out_server->reset();
3418 }
3419}
3420
3421class TicketAEADMethodTest
3422 : public ::testing::TestWithParam<testing::tuple<
3423 uint16_t, unsigned, ssl_test_ticket_aead_failure_mode>> {};
3424
3425TEST_P(TicketAEADMethodTest, Resume) {
3426 bssl::UniquePtr<X509> cert = GetTestCertificate();
3427 ASSERT_TRUE(cert);
3428 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
3429 ASSERT_TRUE(key);
3430
3431 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
3432 ASSERT_TRUE(server_ctx);
3433 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
3434 ASSERT_TRUE(client_ctx);
3435
3436 const uint16_t version = testing::get<0>(GetParam());
3437 const unsigned retry_count = testing::get<1>(GetParam());
3438 const ssl_test_ticket_aead_failure_mode failure_mode =
3439 testing::get<2>(GetParam());
3440
3441 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
3442 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
3443 ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), version));
3444 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), version));
3445 ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), version));
3446 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), version));
3447
3448 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
3449 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
3450 SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
3451 SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
David Benjamin707af292017-03-10 17:47:18 -05003452 SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
Adam Langley4c341d02017-03-08 19:33:21 -08003453
3454 SSL_CTX_set_ticket_aead_method(server_ctx.get(), &kSSLTestTicketMethod);
3455
3456 bssl::UniquePtr<SSL> client, server;
3457 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3458 server_ctx.get(), retry_count,
3459 failure_mode, nullptr);
3460 switch (failure_mode) {
3461 case ssl_test_ticket_aead_ok:
3462 case ssl_test_ticket_aead_open_hard_fail:
3463 case ssl_test_ticket_aead_open_soft_fail:
3464 ASSERT_TRUE(client);
3465 break;
3466 case ssl_test_ticket_aead_seal_fail:
3467 EXPECT_FALSE(client);
3468 return;
3469 }
3470 EXPECT_FALSE(SSL_session_reused(client.get()));
3471 EXPECT_FALSE(SSL_session_reused(server.get()));
3472
David Benjamin707af292017-03-10 17:47:18 -05003473 // Run the read loop to account for post-handshake tickets in TLS 1.3.
3474 SSL_read(client.get(), nullptr, 0);
3475
3476 bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
Adam Langley4c341d02017-03-08 19:33:21 -08003477 ConnectClientAndServerWithTicketMethod(&client, &server, client_ctx.get(),
3478 server_ctx.get(), retry_count,
David Benjamin707af292017-03-10 17:47:18 -05003479 failure_mode, session.get());
Adam Langley4c341d02017-03-08 19:33:21 -08003480 switch (failure_mode) {
3481 case ssl_test_ticket_aead_ok:
3482 ASSERT_TRUE(client);
3483 EXPECT_TRUE(SSL_session_reused(client.get()));
3484 EXPECT_TRUE(SSL_session_reused(server.get()));
3485 break;
3486 case ssl_test_ticket_aead_seal_fail:
3487 abort();
3488 break;
3489 case ssl_test_ticket_aead_open_hard_fail:
3490 EXPECT_FALSE(client);
3491 break;
3492 case ssl_test_ticket_aead_open_soft_fail:
3493 ASSERT_TRUE(client);
3494 EXPECT_FALSE(SSL_session_reused(client.get()));
3495 EXPECT_FALSE(SSL_session_reused(server.get()));
3496 }
3497}
3498
3499INSTANTIATE_TEST_CASE_P(
3500 TicketAEADMethodTests, TicketAEADMethodTest,
3501 testing::Combine(
David Benjamin707af292017-03-10 17:47:18 -05003502 testing::Values(TLS1_2_VERSION, TLS1_3_VERSION),
Adam Langley4c341d02017-03-08 19:33:21 -08003503 testing::Values(0, 1, 2),
3504 testing::Values(ssl_test_ticket_aead_ok,
3505 ssl_test_ticket_aead_seal_fail,
3506 ssl_test_ticket_aead_open_soft_fail,
3507 ssl_test_ticket_aead_open_hard_fail)));
3508
David Benjamin3cfeb952017-03-01 16:48:38 -05003509TEST(SSLTest, SSL3Method) {
3510 bssl::UniquePtr<X509> cert = GetTestCertificate();
3511 ASSERT_TRUE(cert);
3512
3513 // For compatibility, SSLv3_method should work up to SSL_CTX_new and SSL_new.
3514 bssl::UniquePtr<SSL_CTX> ssl3_ctx(SSL_CTX_new(SSLv3_method()));
3515 ASSERT_TRUE(ssl3_ctx);
3516 ASSERT_TRUE(SSL_CTX_use_certificate(ssl3_ctx.get(), cert.get()));
3517 bssl::UniquePtr<SSL> ssl(SSL_new(ssl3_ctx.get()));
3518 EXPECT_TRUE(ssl);
3519
3520 // Create a normal TLS context to test against.
3521 bssl::UniquePtr<SSL_CTX> tls_ctx(SSL_CTX_new(TLS_method()));
3522 ASSERT_TRUE(tls_ctx);
3523 ASSERT_TRUE(SSL_CTX_use_certificate(tls_ctx.get(), cert.get()));
3524
3525 // However, handshaking an SSLv3_method server should fail to resolve the
3526 // version range. Explicit calls to SSL_CTX_set_min_proto_version are the only
3527 // way to enable SSL 3.0.
3528 bssl::UniquePtr<SSL> client, server;
3529 EXPECT_FALSE(ConnectClientAndServer(&client, &server, tls_ctx.get(),
3530 ssl3_ctx.get(),
3531 nullptr /* no session */));
3532 uint32_t err = ERR_get_error();
3533 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
3534 EXPECT_EQ(SSL_R_NO_SUPPORTED_VERSIONS_ENABLED, ERR_GET_REASON(err));
3535
3536 // Likewise for SSLv3_method clients.
3537 EXPECT_FALSE(ConnectClientAndServer(&client, &server, ssl3_ctx.get(),
3538 tls_ctx.get(),
3539 nullptr /* no session */));
3540 err = ERR_get_error();
3541 EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(err));
3542 EXPECT_EQ(SSL_R_NO_SUPPORTED_VERSIONS_ENABLED, ERR_GET_REASON(err));
3543}
3544
David Benjamin96628432017-01-19 19:05:47 -05003545// TODO(davidben): Convert this file to GTest properly.
3546TEST(SSLTest, AllTests) {
Adam Langley10f97f32016-07-12 08:09:33 -07003547 if (!TestCipherRules() ||
Alessandro Ghedini5fd18072016-09-28 21:04:25 +01003548 !TestCurveRules() ||
Adam Langley10f97f32016-07-12 08:09:33 -07003549 !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
3550 !TestSSL_SESSIONEncoding(kCustomSession) ||
3551 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
3552 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
3553 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
3554 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
David Benjamin10e664b2016-06-20 22:20:47 -04003555 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
David Benjamin3cfeb952017-03-01 16:48:38 -05003556 !TestDefaultVersion(TLS1_VERSION, TLS1_2_VERSION, &TLS_method) ||
Adam Langley10f97f32016-07-12 08:09:33 -07003557 !TestDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method) ||
3558 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method) ||
3559 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method) ||
3560 !TestDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method) ||
3561 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method) ||
3562 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method) ||
3563 !TestCipherGetRFCName() ||
Steven Valdeza833c352016-11-01 13:39:36 -04003564 // Test the padding extension at TLS 1.2.
3565 !TestPaddingExtension(TLS1_2_VERSION, TLS1_2_VERSION) ||
3566 // Test the padding extension at TLS 1.3 with a TLS 1.2 session, so there
3567 // will be no PSK binder after the padding extension.
3568 !TestPaddingExtension(TLS1_3_VERSION, TLS1_2_VERSION) ||
3569 // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
3570 // will be a PSK binder after the padding extension.
3571 !TestPaddingExtension(TLS1_3_VERSION, TLS1_3_DRAFT_VERSION) ||
Adam Langley10f97f32016-07-12 08:09:33 -07003572 !TestInternalSessionCache() ||
David Benjamin0fef3052016-11-18 15:11:10 +09003573 !ForEachVersion(TestSequenceNumber) ||
David Benjamin68f37b72016-11-18 15:14:42 +09003574 !ForEachVersion(TestOneSidedShutdown) ||
David Benjamin0fef3052016-11-18 15:11:10 +09003575 !ForEachVersion(TestGetPeerCertificate) ||
3576 !ForEachVersion(TestRetainOnlySHA256OfCerts) ||
David Benjamina20e5352016-08-02 19:09:41 -04003577 !TestClientHello() ||
David Benjamin0fef3052016-11-18 15:11:10 +09003578 !ForEachVersion(TestSessionIDContext) ||
3579 !ForEachVersion(TestSessionTimeout) ||
3580 !ForEachVersion(TestSNICallback) ||
David Benjamin0fef3052016-11-18 15:11:10 +09003581 !ForEachVersion(TestVersion) ||
David Benjaminb79cc842016-12-07 15:57:14 -05003582 !ForEachVersion(TestALPNCipherAvailable) ||
David Benjamin1444c3a2016-12-20 17:23:11 -05003583 !ForEachVersion(TestSSLClearSessionResumption) ||
David Benjamin48063c22017-01-01 23:56:36 -05003584 !ForEachVersion(TestAutoChain) ||
3585 !ForEachVersion(TestSSLWriteRetry)) {
David Benjamin96628432017-01-19 19:05:47 -05003586 ADD_FAILURE() << "Tests failed";
David Benjaminbb0a17c2014-09-20 15:35:39 -04003587 }
David Benjamin2e521212014-07-16 14:37:51 -04003588}