blob: 97bcab3216f63c2ae2142152f7fac3ec0ee2302b [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
125 // selections. Select AES_128_GCM, but order the key exchanges RSA, DHE_RSA,
126 // ECDHE_RSA.
127 {
128 "ALL:-kECDHE:-kDHE:-kRSA:-ALL:"
129 "AESGCM+AES128+aRSA",
130 {
131 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
132 {TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, 0},
133 {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 Braithwaitea57dcfb2017-02-17 22:08:23 -0800185 "!kEDH:!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"},
794 {TLS1_CK_DHE_RSA_WITH_AES_256_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"},
795 {TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
796 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"},
797 {TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
798 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"},
799 {TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
800 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"},
801 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
802 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"},
803 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
804 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"},
805 {TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
806 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"},
807 {TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
808 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA"},
809 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
810 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"},
811 {TLS1_CK_AES_256_GCM_SHA384, "TLS_AES_256_GCM_SHA384"},
812 {TLS1_CK_AES_128_GCM_SHA256, "TLS_AES_128_GCM_SHA256"},
813 {TLS1_CK_CHACHA20_POLY1305_SHA256, "TLS_CHACHA20_POLY1305_SHA256"},
David Benjamin65226252015-02-05 16:49:47 -0500814};
815
David Benjamin1d77e562015-03-22 17:22:08 -0400816static bool TestCipherGetRFCName(void) {
817 for (size_t i = 0;
Steven Valdezcb966542016-08-17 16:56:14 -0400818 i < OPENSSL_ARRAY_SIZE(kCipherRFCNameTests); i++) {
David Benjamin65226252015-02-05 16:49:47 -0500819 const CIPHER_RFC_NAME_TEST *test = &kCipherRFCNameTests[i];
David Benjamin1d77e562015-03-22 17:22:08 -0400820 std::string rfc_name;
821 if (!CipherGetRFCName(&rfc_name, test->id & 0xffff)) {
822 fprintf(stderr, "SSL_CIPHER_get_rfc_name failed\n");
823 return false;
David Benjamin65226252015-02-05 16:49:47 -0500824 }
David Benjamin1d77e562015-03-22 17:22:08 -0400825 if (rfc_name != test->rfc_name) {
David Benjamin65226252015-02-05 16:49:47 -0500826 fprintf(stderr, "SSL_CIPHER_get_rfc_name: got '%s', wanted '%s'\n",
David Benjamin1d77e562015-03-22 17:22:08 -0400827 rfc_name.c_str(), test->rfc_name);
828 return false;
David Benjamin65226252015-02-05 16:49:47 -0500829 }
David Benjamin65226252015-02-05 16:49:47 -0500830 }
David Benjamin1d77e562015-03-22 17:22:08 -0400831 return true;
David Benjamin65226252015-02-05 16:49:47 -0500832}
833
Steven Valdeza833c352016-11-01 13:39:36 -0400834// CreateSessionWithTicket returns a sample |SSL_SESSION| with the specified
835// version and ticket length or nullptr on failure.
836static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(uint16_t version,
837 size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -0400838 std::vector<uint8_t> der;
839 if (!DecodeBase64(&der, kOpenSSLSession)) {
840 return nullptr;
841 }
Adam Langley46db7af2017-02-01 15:49:37 -0800842
843 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
844 if (!ssl_ctx) {
845 return nullptr;
846 }
Steven Valdeza833c352016-11-01 13:39:36 -0400847 bssl::UniquePtr<SSL_SESSION> session(
Adam Langley46db7af2017-02-01 15:49:37 -0800848 SSL_SESSION_from_bytes(der.data(), der.size(), ssl_ctx.get()));
David Benjamin422fe082015-07-21 22:03:43 -0400849 if (!session) {
850 return nullptr;
851 }
852
Steven Valdeza833c352016-11-01 13:39:36 -0400853 session->ssl_version = version;
854
David Benjamin422fe082015-07-21 22:03:43 -0400855 // Swap out the ticket for a garbage one.
856 OPENSSL_free(session->tlsext_tick);
857 session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len));
858 if (session->tlsext_tick == nullptr) {
859 return nullptr;
860 }
David Benjamin17cf2cb2016-12-13 01:07:13 -0500861 OPENSSL_memset(session->tlsext_tick, 'a', ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -0400862 session->tlsext_ticklen = ticket_len;
David Benjamin1269ddd2015-10-18 15:18:55 -0400863
864 // Fix up the timeout.
David Benjamin9b63f292016-11-15 00:44:05 -0500865#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
866 session->time = 1234;
867#else
David Benjamin1269ddd2015-10-18 15:18:55 -0400868 session->time = time(NULL);
David Benjamin9b63f292016-11-15 00:44:05 -0500869#endif
David Benjamin422fe082015-07-21 22:03:43 -0400870 return session;
871}
872
David Benjaminafc64de2016-07-19 17:12:41 +0200873static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700874 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +0200875 if (!bio) {
876 return false;
877 }
878 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -0400879 BIO_up_ref(bio.get());
880 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +0200881 int ret = SSL_connect(ssl);
882 if (ret > 0) {
883 // SSL_connect should fail without a BIO to write to.
884 return false;
885 }
886 ERR_clear_error();
887
888 const uint8_t *client_hello;
889 size_t client_hello_len;
890 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
891 return false;
892 }
893 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
894 return true;
895}
896
Steven Valdeza833c352016-11-01 13:39:36 -0400897// GetClientHelloLen creates a client SSL connection with the specified version
898// and ticket length. It returns the length of the ClientHello, not including
899// the record header, on success and zero on error.
900static size_t GetClientHelloLen(uint16_t max_version, uint16_t session_version,
901 size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700902 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Steven Valdeza833c352016-11-01 13:39:36 -0400903 bssl::UniquePtr<SSL_SESSION> session =
904 CreateSessionWithTicket(session_version, ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -0400905 if (!ctx || !session) {
906 return 0;
907 }
Steven Valdeza833c352016-11-01 13:39:36 -0400908
909 // Set a one-element cipher list so the baseline ClientHello is unpadded.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700910 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
Steven Valdez2c62fe92016-10-14 12:08:12 -0400911 if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -0800912 !SSL_set_strict_cipher_list(ssl.get(), "ECDHE-RSA-AES128-GCM-SHA256") ||
Steven Valdeza833c352016-11-01 13:39:36 -0400913 !SSL_set_max_proto_version(ssl.get(), max_version)) {
David Benjamin422fe082015-07-21 22:03:43 -0400914 return 0;
915 }
Steven Valdeza833c352016-11-01 13:39:36 -0400916
David Benjaminafc64de2016-07-19 17:12:41 +0200917 std::vector<uint8_t> client_hello;
918 if (!GetClientHello(ssl.get(), &client_hello) ||
919 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -0400920 return 0;
921 }
Steven Valdeza833c352016-11-01 13:39:36 -0400922
David Benjaminafc64de2016-07-19 17:12:41 +0200923 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -0400924}
925
926struct PaddingTest {
927 size_t input_len, padded_len;
928};
929
930static const PaddingTest kPaddingTests[] = {
931 // ClientHellos of length below 0x100 do not require padding.
932 {0xfe, 0xfe},
933 {0xff, 0xff},
934 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
935 {0x100, 0x200},
936 {0x123, 0x200},
937 {0x1fb, 0x200},
938 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
939 // padding extension takes a minimum of four bytes plus one required content
940 // byte. (To work around yet more server bugs, we avoid empty final
941 // extensions.)
942 {0x1fc, 0x201},
943 {0x1fd, 0x202},
944 {0x1fe, 0x203},
945 {0x1ff, 0x204},
946 // Finally, larger ClientHellos need no padding.
947 {0x200, 0x200},
948 {0x201, 0x201},
949};
950
Steven Valdeza833c352016-11-01 13:39:36 -0400951static bool TestPaddingExtension(uint16_t max_version,
952 uint16_t session_version) {
David Benjamin422fe082015-07-21 22:03:43 -0400953 // Sample a baseline length.
Steven Valdeza833c352016-11-01 13:39:36 -0400954 size_t base_len = GetClientHelloLen(max_version, session_version, 1);
David Benjamin422fe082015-07-21 22:03:43 -0400955 if (base_len == 0) {
956 return false;
957 }
958
959 for (const PaddingTest &test : kPaddingTests) {
960 if (base_len > test.input_len) {
Steven Valdeza833c352016-11-01 13:39:36 -0400961 fprintf(stderr,
962 "Baseline ClientHello too long (max_version = %04x, "
963 "session_version = %04x).\n",
964 max_version, session_version);
David Benjamin422fe082015-07-21 22:03:43 -0400965 return false;
966 }
967
Steven Valdeza833c352016-11-01 13:39:36 -0400968 size_t padded_len = GetClientHelloLen(max_version, session_version,
969 1 + test.input_len - base_len);
David Benjamin422fe082015-07-21 22:03:43 -0400970 if (padded_len != test.padded_len) {
Steven Valdeza833c352016-11-01 13:39:36 -0400971 fprintf(stderr,
972 "%u-byte ClientHello padded to %u bytes, not %u (max_version = "
973 "%04x, session_version = %04x).\n",
David Benjamin422fe082015-07-21 22:03:43 -0400974 static_cast<unsigned>(test.input_len),
975 static_cast<unsigned>(padded_len),
Steven Valdeza833c352016-11-01 13:39:36 -0400976 static_cast<unsigned>(test.padded_len), max_version,
977 session_version);
David Benjamin422fe082015-07-21 22:03:43 -0400978 return false;
979 }
980 }
Steven Valdeza833c352016-11-01 13:39:36 -0400981
David Benjamin422fe082015-07-21 22:03:43 -0400982 return true;
983}
984
David Benjamin1d128f32015-09-08 17:41:40 -0400985// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
986// before configuring as a server.
David Benjaminf0d8e222017-02-04 10:58:26 -0500987TEST(SSLTest, ClientCAList) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700988 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -0500989 ASSERT_TRUE(ctx);
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700990 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -0500991 ASSERT_TRUE(ssl);
David Benjamin1d128f32015-09-08 17:41:40 -0400992
993 STACK_OF(X509_NAME) *stack = sk_X509_NAME_new_null();
David Benjaminf0d8e222017-02-04 10:58:26 -0500994 ASSERT_TRUE(stack);
David Benjamin1d128f32015-09-08 17:41:40 -0400995 // |SSL_set_client_CA_list| takes ownership.
996 SSL_set_client_CA_list(ssl.get(), stack);
997
David Benjaminf0d8e222017-02-04 10:58:26 -0500998 EXPECT_EQ(stack, SSL_get_client_CA_list(ssl.get()));
David Benjamin1d128f32015-09-08 17:41:40 -0400999}
1000
David Benjamin0f653952015-10-18 14:28:01 -04001001static void AppendSession(SSL_SESSION *session, void *arg) {
1002 std::vector<SSL_SESSION*> *out =
1003 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
1004 out->push_back(session);
1005}
1006
1007// ExpectCache returns true if |ctx|'s session cache consists of |expected|, in
1008// order.
1009static bool ExpectCache(SSL_CTX *ctx,
1010 const std::vector<SSL_SESSION*> &expected) {
1011 // Check the linked list.
1012 SSL_SESSION *ptr = ctx->session_cache_head;
1013 for (SSL_SESSION *session : expected) {
1014 if (ptr != session) {
1015 return false;
1016 }
1017 // TODO(davidben): This is an absurd way to denote the end of the list.
1018 if (ptr->next ==
1019 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
1020 ptr = nullptr;
1021 } else {
1022 ptr = ptr->next;
1023 }
1024 }
1025 if (ptr != nullptr) {
1026 return false;
1027 }
1028
1029 // Check the hash table.
1030 std::vector<SSL_SESSION*> actual, expected_copy;
1031 lh_SSL_SESSION_doall_arg(SSL_CTX_sessions(ctx), AppendSession, &actual);
1032 expected_copy = expected;
1033
1034 std::sort(actual.begin(), actual.end());
1035 std::sort(expected_copy.begin(), expected_copy.end());
1036
1037 return actual == expected_copy;
1038}
1039
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001040static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
Adam Langley46db7af2017-02-01 15:49:37 -08001041 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
1042 if (!ssl_ctx) {
1043 return nullptr;
1044 }
1045 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new(ssl_ctx.get()));
David Benjamin0f653952015-10-18 14:28:01 -04001046 if (!ret) {
1047 return nullptr;
1048 }
1049
1050 ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
David Benjamin17cf2cb2016-12-13 01:07:13 -05001051 OPENSSL_memset(ret->session_id, 0, ret->session_id_length);
1052 OPENSSL_memcpy(ret->session_id, &number, sizeof(number));
David Benjamin0f653952015-10-18 14:28:01 -04001053 return ret;
1054}
1055
David Benjamin0f653952015-10-18 14:28:01 -04001056// Test that the internal session cache behaves as expected.
1057static bool TestInternalSessionCache() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001058 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin0f653952015-10-18 14:28:01 -04001059 if (!ctx) {
1060 return false;
1061 }
1062
1063 // Prepare 10 test sessions.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001064 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
David Benjamin0f653952015-10-18 14:28:01 -04001065 for (int i = 0; i < 10; i++) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001066 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
David Benjamin0f653952015-10-18 14:28:01 -04001067 if (!session) {
1068 return false;
1069 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001070 sessions.push_back(std::move(session));
David Benjamin0f653952015-10-18 14:28:01 -04001071 }
1072
1073 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1074
1075 // Insert all the test sessions.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001076 for (const auto &session : sessions) {
1077 if (!SSL_CTX_add_session(ctx.get(), session.get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001078 return false;
1079 }
1080 }
1081
1082 // Only the last five should be in the list.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001083 std::vector<SSL_SESSION*> expected = {
1084 sessions[9].get(),
1085 sessions[8].get(),
1086 sessions[7].get(),
1087 sessions[6].get(),
1088 sessions[5].get(),
1089 };
David Benjamin0f653952015-10-18 14:28:01 -04001090 if (!ExpectCache(ctx.get(), expected)) {
1091 return false;
1092 }
1093
1094 // Inserting an element already in the cache should fail.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001095 if (SSL_CTX_add_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001096 !ExpectCache(ctx.get(), expected)) {
1097 return false;
1098 }
1099
1100 // Although collisions should be impossible (256-bit session IDs), the cache
1101 // must handle them gracefully.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001102 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
David Benjamin0f653952015-10-18 14:28:01 -04001103 if (!collision || !SSL_CTX_add_session(ctx.get(), collision.get())) {
1104 return false;
1105 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001106 expected = {
1107 collision.get(),
1108 sessions[9].get(),
1109 sessions[8].get(),
1110 sessions[6].get(),
1111 sessions[5].get(),
1112 };
David Benjamin0f653952015-10-18 14:28:01 -04001113 if (!ExpectCache(ctx.get(), expected)) {
1114 return false;
1115 }
1116
1117 // Removing sessions behaves correctly.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001118 if (!SSL_CTX_remove_session(ctx.get(), sessions[6].get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001119 return false;
1120 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001121 expected = {
1122 collision.get(),
1123 sessions[9].get(),
1124 sessions[8].get(),
1125 sessions[5].get(),
1126 };
David Benjamin0f653952015-10-18 14:28:01 -04001127 if (!ExpectCache(ctx.get(), expected)) {
1128 return false;
1129 }
1130
1131 // Removing sessions requires an exact match.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001132 if (SSL_CTX_remove_session(ctx.get(), sessions[0].get()) ||
1133 SSL_CTX_remove_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001134 !ExpectCache(ctx.get(), expected)) {
1135 return false;
1136 }
1137
1138 return true;
1139}
1140
David Benjaminde942382016-02-11 12:02:01 -05001141static uint16_t EpochFromSequence(uint64_t seq) {
1142 return static_cast<uint16_t>(seq >> 48);
1143}
1144
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001145static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001146 static const char kCertPEM[] =
1147 "-----BEGIN CERTIFICATE-----\n"
1148 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1149 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1150 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1151 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1152 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1153 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1154 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1155 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1156 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1157 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1158 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1159 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1160 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1161 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001162 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
David Benjamin1444c3a2016-12-20 17:23:11 -05001163 return bssl::UniquePtr<X509>(
1164 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjaminde942382016-02-11 12:02:01 -05001165}
1166
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001167static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001168 static const char kKeyPEM[] =
1169 "-----BEGIN RSA PRIVATE KEY-----\n"
1170 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1171 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1172 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1173 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1174 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1175 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1176 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1177 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1178 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1179 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1180 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1181 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1182 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1183 "-----END RSA PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001184 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1185 return bssl::UniquePtr<EVP_PKEY>(
David Benjaminde942382016-02-11 12:02:01 -05001186 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1187}
1188
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001189static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001190 static const char kCertPEM[] =
1191 "-----BEGIN CERTIFICATE-----\n"
1192 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1193 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1194 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1195 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1196 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1197 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1198 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1199 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1200 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1201 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1202 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001203 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1204 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjamin0fc37ef2016-08-17 15:29:46 -04001205}
1206
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001207static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001208 static const char kKeyPEM[] =
1209 "-----BEGIN PRIVATE KEY-----\n"
1210 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1211 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1212 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1213 "-----END PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001214 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1215 return bssl::UniquePtr<EVP_PKEY>(
David Benjamin0fc37ef2016-08-17 15:29:46 -04001216 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1217}
1218
David Benjamin1444c3a2016-12-20 17:23:11 -05001219static bssl::UniquePtr<X509> GetChainTestCertificate() {
1220 static const char kCertPEM[] =
1221 "-----BEGIN CERTIFICATE-----\n"
1222 "MIIC0jCCAbqgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQiBD\n"
1223 "QTAeFw0xNjAyMjgyMDI3MDNaFw0yNjAyMjUyMDI3MDNaMBgxFjAUBgNVBAMMDUNs\n"
1224 "aWVudCBDZXJ0IEEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRvaz8\n"
1225 "CC/cshpCafJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/\n"
1226 "kLRcH89M/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3\n"
1227 "tHb+xs2PSs8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+c\n"
1228 "IDs2rQ+lP7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1\n"
1229 "z7C8jU50Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9V\n"
1230 "iLeXANgZi+Xx9KgfAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI\n"
1231 "KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBFEVbmYl+2RtNw\n"
1232 "rDftRDF1v2QUbcN2ouSnQDHxeDQdSgasLzT3ui8iYu0Rw2WWcZ0DV5e0ztGPhWq7\n"
1233 "AO0B120aFRMOY+4+bzu9Q2FFkQqc7/fKTvTDzIJI5wrMnFvUfzzvxh3OHWMYSs/w\n"
1234 "giq33hTKeHEq6Jyk3btCny0Ycecyc3yGXH10sizUfiHlhviCkDuESk8mFDwDDzqW\n"
1235 "ZF0IipzFbEDHoIxLlm3GQxpiLoEV4k8KYJp3R5KBLFyxM6UGPz8h72mIPCJp2RuK\n"
1236 "MYgF91UDvVzvnYm6TfseM2+ewKirC00GOrZ7rEcFvtxnKSqYf4ckqfNdSU1Y+RRC\n"
1237 "1ngWZ7Ih\n"
1238 "-----END CERTIFICATE-----\n";
1239 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1240 return bssl::UniquePtr<X509>(
1241 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
1242}
1243
1244static bssl::UniquePtr<X509> GetChainTestIntermediate() {
1245 static const char kCertPEM[] =
1246 "-----BEGIN CERTIFICATE-----\n"
1247 "MIICwjCCAaqgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS\n"
1248 "b290IENBMB4XDTE2MDIyODIwMjcwM1oXDTI2MDIyNTIwMjcwM1owDzENMAsGA1UE\n"
1249 "AwwEQiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALsSCYmDip2D\n"
1250 "GkjFxw7ykz26JSjELkl6ArlYjFJ3aT/SCh8qbS4gln7RH8CPBd78oFdfhIKQrwtZ\n"
1251 "3/q21ykD9BAS3qHe2YdcJfm8/kWAy5DvXk6NXU4qX334KofBAEpgdA/igEFq1P1l\n"
1252 "HAuIfZCpMRfT+i5WohVsGi8f/NgpRvVaMONLNfgw57mz1lbtFeBEISmX0kbsuJxF\n"
1253 "Qj/Bwhi5/0HAEXG8e7zN4cEx0yPRvmOATRdVb/8dW2pwOHRJq9R5M0NUkIsTSnL7\n"
1254 "6N/z8hRAHMsV3IudC5Yd7GXW1AGu9a+iKU+Q4xcZCoj0DC99tL4VKujrV1kAeqsM\n"
1255 "cz5/dKzi6+cCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
1256 "AQYwDQYJKoZIhvcNAQELBQADggEBAIIeZiEeNhWWQ8Y4D+AGDwqUUeG8NjCbKrXQ\n"
1257 "BlHg5wZ8xftFaiP1Dp/UAezmx2LNazdmuwrYB8lm3FVTyaPDTKEGIPS4wJKHgqH1\n"
1258 "QPDhqNm85ey7TEtI9oYjsNim/Rb+iGkIAMXaxt58SzxbjvP0kMr1JfJIZbic9vye\n"
1259 "NwIspMFIpP3FB8ywyu0T0hWtCQgL4J47nigCHpOu58deP88fS/Nyz/fyGVWOZ76b\n"
1260 "WhWwgM3P3X95fQ3d7oFPR/bVh0YV+Cf861INwplokXgXQ3/TCQ+HNXeAMWn3JLWv\n"
1261 "XFwk8owk9dq/kQGdndGgy3KTEW4ctPX5GNhf3LJ9Q7dLji4ReQ4=\n"
1262 "-----END CERTIFICATE-----\n";
1263 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1264 return bssl::UniquePtr<X509>(
1265 PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
1266}
1267
1268static bssl::UniquePtr<EVP_PKEY> GetChainTestKey() {
1269 static const char kKeyPEM[] =
1270 "-----BEGIN PRIVATE KEY-----\n"
1271 "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRvaz8CC/cshpC\n"
1272 "afJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/kLRcH89M\n"
1273 "/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3tHb+xs2P\n"
1274 "Ss8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+cIDs2rQ+l\n"
1275 "P7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1z7C8jU50\n"
1276 "Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9ViLeXANgZ\n"
1277 "i+Xx9KgfAgMBAAECggEBAK0VjSJzkyPaamcyTVSWjo7GdaBGcK60lk657RjR+lK0\n"
1278 "YJ7pkej4oM2hdsVZFsP8Cs4E33nXLa/0pDsRov/qrp0WQm2skwqGMC1I/bZ0WRPk\n"
1279 "wHaDrBBfESWnJDX/AGpVtlyOjPmgmK6J2usMPihQUDkKdAYrVWJePrMIxt1q6BMe\n"
1280 "iczs3qriMmtY3bUc4UyUwJ5fhDLjshHvfuIpYQyI6EXZM6dZksn9LylXJnigY6QJ\n"
1281 "HxOYO0BDwOsZ8yQ8J8afLk88i0GizEkgE1z3REtQUwgWfxr1WV/ud+T6/ZhSAgH9\n"
1282 "042mQvSFZnIUSEsmCvjhWuAunfxHKCTcAoYISWfzWpkCgYEA7gpf3HHU5Tn+CgUn\n"
1283 "1X5uGpG3DmcMgfeGgs2r2f/IIg/5Ac1dfYILiybL1tN9zbyLCJfcbFpWBc9hJL6f\n"
1284 "CPc5hUiwWFJqBJewxQkC1Ae/HakHbip+IZ+Jr0842O4BAArvixk4Lb7/N2Ct9sTE\n"
1285 "NJO6RtK9lbEZ5uK61DglHy8CS2UCgYEA4ZC1o36kPAMQBggajgnucb2yuUEelk0f\n"
1286 "AEr+GI32MGE+93xMr7rAhBoqLg4AITyIfEnOSQ5HwagnIHonBbv1LV/Gf9ursx8Z\n"
1287 "YOGbvT8zzzC+SU1bkDzdjAYnFQVGIjMtKOBJ3K07++ypwX1fr4QsQ8uKL8WSOWwt\n"
1288 "Z3Bym6XiZzMCgYADnhy+2OwHX85AkLt+PyGlPbmuelpyTzS4IDAQbBa6jcuW/2wA\n"
1289 "UE2km75VUXmD+u2R/9zVuLm99NzhFhSMqlUxdV1YukfqMfP5yp1EY6m/5aW7QuIP\n"
1290 "2MDa7TVL9rIFMiVZ09RKvbBbQxjhuzPQKL6X/PPspnhiTefQ+dl2k9xREQKBgHDS\n"
1291 "fMfGNEeAEKezrfSVqxphE9/tXms3L+ZpnCaT+yu/uEr5dTIAawKoQ6i9f/sf1/Sy\n"
1292 "xedsqR+IB+oKrzIDDWMgoJybN4pkZ8E5lzhVQIjFjKgFdWLzzqyW9z1gYfABQPlN\n"
1293 "FiS20WX0vgP1vcKAjdNrHzc9zyHBpgQzDmAj3NZZAoGBAI8vKCKdH7w3aL5CNkZQ\n"
1294 "2buIeWNA2HZazVwAGG5F2TU/LmXfRKnG6dX5bkU+AkBZh56jNZy//hfFSewJB4Kk\n"
1295 "buB7ERSdaNbO21zXt9FEA3+z0RfMd/Zv2vlIWOSB5nzl/7UKti3sribK6s9ZVLfi\n"
1296 "SxpiPQ8d/hmSGwn4ksrWUsJD\n"
1297 "-----END PRIVATE KEY-----\n";
1298 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1299 return bssl::UniquePtr<EVP_PKEY>(
1300 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1301}
1302
David Benjaminb79cc842016-12-07 15:57:14 -05001303static bool CompleteHandshakes(SSL *client, SSL *server) {
1304 // Drive both their handshakes to completion.
1305 for (;;) {
1306 int client_ret = SSL_do_handshake(client);
1307 int client_err = SSL_get_error(client, client_ret);
1308 if (client_err != SSL_ERROR_NONE &&
1309 client_err != SSL_ERROR_WANT_READ &&
1310 client_err != SSL_ERROR_WANT_WRITE) {
1311 fprintf(stderr, "Client error: %d\n", client_err);
1312 return false;
1313 }
1314
1315 int server_ret = SSL_do_handshake(server);
1316 int server_err = SSL_get_error(server, server_ret);
1317 if (server_err != SSL_ERROR_NONE &&
1318 server_err != SSL_ERROR_WANT_READ &&
1319 server_err != SSL_ERROR_WANT_WRITE) {
1320 fprintf(stderr, "Server error: %d\n", server_err);
1321 return false;
1322 }
1323
1324 if (client_ret == 1 && server_ret == 1) {
1325 break;
1326 }
1327 }
1328
1329 return true;
1330}
1331
1332static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client,
1333 bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001334 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1335 SSL_SESSION *session) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001336 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001337 if (!client || !server) {
1338 return false;
1339 }
1340 SSL_set_connect_state(client.get());
1341 SSL_set_accept_state(server.get());
1342
David Benjamina20e5352016-08-02 19:09:41 -04001343 SSL_set_session(client.get(), session);
1344
David Benjaminde942382016-02-11 12:02:01 -05001345 BIO *bio1, *bio2;
1346 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1347 return false;
1348 }
1349 // SSL_set_bio takes ownership.
1350 SSL_set_bio(client.get(), bio1, bio1);
1351 SSL_set_bio(server.get(), bio2, bio2);
1352
David Benjaminb79cc842016-12-07 15:57:14 -05001353 if (!CompleteHandshakes(client.get(), server.get())) {
1354 return false;
David Benjaminde942382016-02-11 12:02:01 -05001355 }
1356
David Benjamin686bb192016-05-10 15:15:41 -04001357 *out_client = std::move(client);
1358 *out_server = std::move(server);
1359 return true;
1360}
1361
David Benjamin0fef3052016-11-18 15:11:10 +09001362static bool TestSequenceNumber(bool is_dtls, const SSL_METHOD *method,
1363 uint16_t version) {
1364 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
1365 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
1366 if (!server_ctx || !client_ctx ||
1367 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
1368 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
1369 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
1370 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
1371 return false;
1372 }
David Benjamin686bb192016-05-10 15:15:41 -04001373
David Benjamin0fef3052016-11-18 15:11:10 +09001374 bssl::UniquePtr<X509> cert = GetTestCertificate();
1375 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
1376 if (!cert || !key || !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1377 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1378 return false;
1379 }
David Benjamin686bb192016-05-10 15:15:41 -04001380
David Benjamin0fef3052016-11-18 15:11:10 +09001381 bssl::UniquePtr<SSL> client, server;
1382 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
1383 server_ctx.get(), nullptr /* no session */)) {
1384 return false;
1385 }
David Benjamin686bb192016-05-10 15:15:41 -04001386
David Benjamin0fef3052016-11-18 15:11:10 +09001387 // Drain any post-handshake messages to ensure there are no unread records
1388 // on either end.
1389 uint8_t byte = 0;
1390 if (SSL_read(client.get(), &byte, 1) > 0 ||
1391 SSL_read(server.get(), &byte, 1) > 0) {
1392 fprintf(stderr, "Received unexpected data.\n");
1393 return false;
1394 }
David Benjaminde942382016-02-11 12:02:01 -05001395
David Benjamin0fef3052016-11-18 15:11:10 +09001396 uint64_t client_read_seq = SSL_get_read_sequence(client.get());
1397 uint64_t client_write_seq = SSL_get_write_sequence(client.get());
1398 uint64_t server_read_seq = SSL_get_read_sequence(server.get());
1399 uint64_t server_write_seq = SSL_get_write_sequence(server.get());
Steven Valdez2c62fe92016-10-14 12:08:12 -04001400
David Benjamin0fef3052016-11-18 15:11:10 +09001401 if (is_dtls) {
1402 // Both client and server must be at epoch 1.
1403 if (EpochFromSequence(client_read_seq) != 1 ||
1404 EpochFromSequence(client_write_seq) != 1 ||
1405 EpochFromSequence(server_read_seq) != 1 ||
1406 EpochFromSequence(server_write_seq) != 1) {
1407 fprintf(stderr, "Bad epochs.\n");
1408 return false;
David Benjaminde942382016-02-11 12:02:01 -05001409 }
David Benjamin0fef3052016-11-18 15:11:10 +09001410
1411 // The next record to be written should exceed the largest received.
1412 if (client_write_seq <= server_read_seq ||
1413 server_write_seq <= client_read_seq) {
1414 fprintf(stderr, "Inconsistent sequence numbers.\n");
1415 return false;
1416 }
1417 } else {
1418 // The next record to be written should equal the next to be received.
1419 if (client_write_seq != server_read_seq ||
1420 server_write_seq != client_read_seq) {
1421 fprintf(stderr, "Inconsistent sequence numbers.\n");
1422 return false;
1423 }
1424 }
1425
1426 // Send a record from client to server.
1427 if (SSL_write(client.get(), &byte, 1) != 1 ||
1428 SSL_read(server.get(), &byte, 1) != 1) {
1429 fprintf(stderr, "Could not send byte.\n");
1430 return false;
1431 }
1432
1433 // The client write and server read sequence numbers should have
1434 // incremented.
1435 if (client_write_seq + 1 != SSL_get_write_sequence(client.get()) ||
1436 server_read_seq + 1 != SSL_get_read_sequence(server.get())) {
1437 fprintf(stderr, "Sequence numbers did not increment.\n");
1438 return false;
David Benjaminde942382016-02-11 12:02:01 -05001439 }
1440
1441 return true;
1442}
1443
David Benjamin68f37b72016-11-18 15:14:42 +09001444static bool TestOneSidedShutdown(bool is_dtls, const SSL_METHOD *method,
1445 uint16_t version) {
1446 // SSL_shutdown is a no-op in DTLS.
1447 if (is_dtls) {
1448 return true;
David Benjamin686bb192016-05-10 15:15:41 -04001449 }
1450
David Benjamin68f37b72016-11-18 15:14:42 +09001451 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
1452 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001453 bssl::UniquePtr<X509> cert = GetTestCertificate();
1454 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin68f37b72016-11-18 15:14:42 +09001455 if (!client_ctx || !server_ctx || !cert || !key ||
1456 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
1457 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
1458 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
1459 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
David Benjamin686bb192016-05-10 15:15:41 -04001460 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1461 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1462 return false;
1463 }
1464
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001465 bssl::UniquePtr<SSL> client, server;
David Benjamin686bb192016-05-10 15:15:41 -04001466 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001467 server_ctx.get(), nullptr /* no session */)) {
David Benjamin686bb192016-05-10 15:15:41 -04001468 return false;
1469 }
1470
1471 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1472 // one side has shut down.
1473 if (SSL_shutdown(client.get()) != 0) {
1474 fprintf(stderr, "Could not shutdown.\n");
1475 return false;
1476 }
1477
1478 // Reading from the server should consume the EOF.
1479 uint8_t byte;
1480 if (SSL_read(server.get(), &byte, 1) != 0 ||
1481 SSL_get_error(server.get(), 0) != SSL_ERROR_ZERO_RETURN) {
1482 fprintf(stderr, "Connection was not shut down cleanly.\n");
1483 return false;
1484 }
1485
1486 // However, the server may continue to write data and then shut down the
1487 // connection.
1488 byte = 42;
1489 if (SSL_write(server.get(), &byte, 1) != 1 ||
1490 SSL_read(client.get(), &byte, 1) != 1 ||
1491 byte != 42) {
1492 fprintf(stderr, "Could not send byte.\n");
1493 return false;
1494 }
1495
1496 // The server may then shutdown the connection.
1497 if (SSL_shutdown(server.get()) != 1 ||
1498 SSL_shutdown(client.get()) != 1) {
1499 fprintf(stderr, "Could not complete shutdown.\n");
1500 return false;
1501 }
1502
1503 return true;
1504}
David Benjamin68f37b72016-11-18 15:14:42 +09001505
David Benjaminf0d8e222017-02-04 10:58:26 -05001506TEST(SSLTest, SessionDuplication) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001507 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1508 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001509 ASSERT_TRUE(client_ctx);
1510 ASSERT_TRUE(server_ctx);
Steven Valdez87eab492016-06-27 16:34:59 -04001511
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001512 bssl::UniquePtr<X509> cert = GetTestCertificate();
1513 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminf0d8e222017-02-04 10:58:26 -05001514 ASSERT_TRUE(cert);
1515 ASSERT_TRUE(key);
1516 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
1517 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
Steven Valdez87eab492016-06-27 16:34:59 -04001518
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001519 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05001520 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
1521 server_ctx.get(),
1522 nullptr /* no session */));
Steven Valdez87eab492016-06-27 16:34:59 -04001523
1524 SSL_SESSION *session0 = SSL_get_session(client.get());
David Benjaminf0d8e222017-02-04 10:58:26 -05001525 bssl::UniquePtr<SSL_SESSION> session1(
1526 SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL));
1527 ASSERT_TRUE(session1);
David Benjamin4501bd52016-08-01 13:39:41 -04001528
Steven Valdez84b5c002016-08-25 16:30:58 -04001529 session1->not_resumable = 0;
1530
Steven Valdez87eab492016-06-27 16:34:59 -04001531 uint8_t *s0_bytes, *s1_bytes;
1532 size_t s0_len, s1_len;
1533
David Benjaminf0d8e222017-02-04 10:58:26 -05001534 ASSERT_TRUE(SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001535 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001536
David Benjaminf0d8e222017-02-04 10:58:26 -05001537 ASSERT_TRUE(SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len));
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001538 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001539
David Benjamin7d7554b2017-02-04 11:48:59 -05001540 EXPECT_EQ(Bytes(s0_bytes, s0_len), Bytes(s1_bytes, s1_len));
Steven Valdez87eab492016-06-27 16:34:59 -04001541}
David Benjamin686bb192016-05-10 15:15:41 -04001542
David Benjaminf0d8e222017-02-04 10:58:26 -05001543static void ExpectFDs(const SSL *ssl, int rfd, int wfd) {
1544 EXPECT_EQ(rfd, SSL_get_rfd(ssl));
1545 EXPECT_EQ(wfd, SSL_get_wfd(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04001546
1547 // The wrapper BIOs are always equal when fds are equal, even if set
1548 // individually.
David Benjaminf0d8e222017-02-04 10:58:26 -05001549 if (rfd == wfd) {
1550 EXPECT_EQ(SSL_get_rbio(ssl), SSL_get_wbio(ssl));
David Benjamin5c0fb882016-06-14 14:03:51 -04001551 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001552}
1553
David Benjaminf0d8e222017-02-04 10:58:26 -05001554TEST(SSLTest, SetFD) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001555 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001556 ASSERT_TRUE(ctx);
David Benjamin5c0fb882016-06-14 14:03:51 -04001557
1558 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001559 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001560 ASSERT_TRUE(ssl);
1561 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1562 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
1563 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04001564
1565 // Test setting the same FD.
1566 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001567 ASSERT_TRUE(ssl);
1568 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1569 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001570
1571 // Test setting the same FD one side at a time.
1572 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001573 ASSERT_TRUE(ssl);
1574 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1575 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1576 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001577
1578 // Test setting the same FD in the other order.
1579 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001580 ASSERT_TRUE(ssl);
1581 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1582 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1583 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001584
David Benjamin5c0fb882016-06-14 14:03:51 -04001585 // Test changing the read FD partway through.
1586 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001587 ASSERT_TRUE(ssl);
1588 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1589 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 2));
1590 ExpectFDs(ssl.get(), 2, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001591
1592 // Test changing the write FD partway through.
1593 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001594 ASSERT_TRUE(ssl);
1595 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1596 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
1597 ExpectFDs(ssl.get(), 1, 2);
David Benjamin5c0fb882016-06-14 14:03:51 -04001598
1599 // Test a no-op change to the read FD partway through.
1600 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001601 ASSERT_TRUE(ssl);
1602 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1603 EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
1604 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001605
1606 // Test a no-op change to the write FD partway through.
1607 ssl.reset(SSL_new(ctx.get()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001608 ASSERT_TRUE(ssl);
1609 EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
1610 EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
1611 ExpectFDs(ssl.get(), 1, 1);
David Benjamin5c0fb882016-06-14 14:03:51 -04001612
1613 // ASan builds will implicitly test that the internal |BIO| reference-counting
1614 // is correct.
David Benjamin5c0fb882016-06-14 14:03:51 -04001615}
1616
David Benjaminf0d8e222017-02-04 10:58:26 -05001617TEST(SSLTest, SetBIO) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001618 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001619 ASSERT_TRUE(ctx);
David Benjamin4501bd52016-08-01 13:39:41 -04001620
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001621 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1622 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04001623 bio3(BIO_new(BIO_s_mem()));
David Benjaminf0d8e222017-02-04 10:58:26 -05001624 ASSERT_TRUE(ssl);
1625 ASSERT_TRUE(bio1);
1626 ASSERT_TRUE(bio2);
1627 ASSERT_TRUE(bio3);
David Benjamin4501bd52016-08-01 13:39:41 -04001628
1629 // SSL_set_bio takes one reference when the parameters are the same.
1630 BIO_up_ref(bio1.get());
1631 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1632
1633 // Repeating the call does nothing.
1634 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1635
1636 // It takes one reference each when the parameters are different.
1637 BIO_up_ref(bio2.get());
1638 BIO_up_ref(bio3.get());
1639 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1640
1641 // Repeating the call does nothing.
1642 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1643
1644 // It takes one reference when changing only wbio.
1645 BIO_up_ref(bio1.get());
1646 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1647
1648 // It takes one reference when changing only rbio and the two are different.
1649 BIO_up_ref(bio3.get());
1650 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1651
1652 // If setting wbio to rbio, it takes no additional references.
1653 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1654
1655 // From there, wbio may be switched to something else.
1656 BIO_up_ref(bio1.get());
1657 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1658
1659 // If setting rbio to wbio, it takes no additional references.
1660 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1661
1662 // From there, rbio may be switched to something else, but, for historical
1663 // reasons, it takes a reference to both parameters.
1664 BIO_up_ref(bio1.get());
1665 BIO_up_ref(bio2.get());
1666 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1667
1668 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1669 // is correct.
David Benjamin4501bd52016-08-01 13:39:41 -04001670}
1671
David Benjamin25490f22016-07-14 00:22:54 -04001672static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1673
David Benjamin0fef3052016-11-18 15:11:10 +09001674static bool TestGetPeerCertificate(bool is_dtls, const SSL_METHOD *method,
1675 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001676 bssl::UniquePtr<X509> cert = GetTestCertificate();
1677 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminadd5e522016-07-14 00:33:24 -04001678 if (!cert || !key) {
1679 return false;
1680 }
1681
David Benjamin0fef3052016-11-18 15:11:10 +09001682 // Configure both client and server to accept any certificate.
1683 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
1684 if (!ctx ||
1685 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1686 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
1687 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1688 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
1689 return false;
1690 }
1691 SSL_CTX_set_verify(
1692 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1693 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
David Benjaminadd5e522016-07-14 00:33:24 -04001694
David Benjamin0fef3052016-11-18 15:11:10 +09001695 bssl::UniquePtr<SSL> client, server;
1696 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1697 nullptr /* no session */)) {
1698 return false;
1699 }
David Benjaminadd5e522016-07-14 00:33:24 -04001700
David Benjamin0fef3052016-11-18 15:11:10 +09001701 // Client and server should both see the leaf certificate.
1702 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
1703 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1704 fprintf(stderr, "Server peer certificate did not match.\n");
1705 return false;
1706 }
David Benjaminadd5e522016-07-14 00:33:24 -04001707
David Benjamin0fef3052016-11-18 15:11:10 +09001708 peer.reset(SSL_get_peer_certificate(client.get()));
1709 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1710 fprintf(stderr, "Client peer certificate did not match.\n");
1711 return false;
1712 }
David Benjaminadd5e522016-07-14 00:33:24 -04001713
David Benjamin0fef3052016-11-18 15:11:10 +09001714 // However, for historical reasons, the chain includes the leaf on the
1715 // client, but does not on the server.
1716 if (sk_X509_num(SSL_get_peer_cert_chain(client.get())) != 1) {
1717 fprintf(stderr, "Client peer chain was incorrect.\n");
1718 return false;
1719 }
David Benjaminadd5e522016-07-14 00:33:24 -04001720
David Benjamin0fef3052016-11-18 15:11:10 +09001721 if (sk_X509_num(SSL_get_peer_cert_chain(server.get())) != 0) {
1722 fprintf(stderr, "Server peer chain was incorrect.\n");
1723 return false;
David Benjaminadd5e522016-07-14 00:33:24 -04001724 }
1725
1726 return true;
1727}
1728
David Benjamin0fef3052016-11-18 15:11:10 +09001729static bool TestRetainOnlySHA256OfCerts(bool is_dtls, const SSL_METHOD *method,
1730 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001731 bssl::UniquePtr<X509> cert = GetTestCertificate();
1732 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin25490f22016-07-14 00:22:54 -04001733 if (!cert || !key) {
1734 return false;
1735 }
1736
1737 uint8_t *cert_der = NULL;
1738 int cert_der_len = i2d_X509(cert.get(), &cert_der);
1739 if (cert_der_len < 0) {
1740 return false;
1741 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001742 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04001743
1744 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1745 SHA256(cert_der, cert_der_len, cert_sha256);
1746
David Benjamin0fef3052016-11-18 15:11:10 +09001747 // Configure both client and server to accept any certificate, but the
1748 // server must retain only the SHA-256 of the peer.
1749 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
1750 if (!ctx ||
1751 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1752 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
1753 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1754 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
1755 return false;
1756 }
1757 SSL_CTX_set_verify(
1758 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1759 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1760 SSL_CTX_set_retain_only_sha256_of_client_certs(ctx.get(), 1);
David Benjamin25490f22016-07-14 00:22:54 -04001761
David Benjamin0fef3052016-11-18 15:11:10 +09001762 bssl::UniquePtr<SSL> client, server;
1763 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1764 nullptr /* no session */)) {
1765 return false;
1766 }
David Benjamin25490f22016-07-14 00:22:54 -04001767
David Benjamin0fef3052016-11-18 15:11:10 +09001768 // The peer certificate has been dropped.
1769 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
1770 if (peer) {
1771 fprintf(stderr, "Peer certificate was retained.\n");
1772 return false;
1773 }
David Benjamin25490f22016-07-14 00:22:54 -04001774
David Benjamin0fef3052016-11-18 15:11:10 +09001775 SSL_SESSION *session = SSL_get_session(server.get());
1776 if (!session->peer_sha256_valid) {
1777 fprintf(stderr, "peer_sha256_valid was not set.\n");
1778 return false;
1779 }
David Benjamin25490f22016-07-14 00:22:54 -04001780
David Benjamin17cf2cb2016-12-13 01:07:13 -05001781 if (OPENSSL_memcmp(cert_sha256, session->peer_sha256, SHA256_DIGEST_LENGTH) !=
1782 0) {
David Benjamin0fef3052016-11-18 15:11:10 +09001783 fprintf(stderr, "peer_sha256 did not match.\n");
1784 return false;
David Benjamin25490f22016-07-14 00:22:54 -04001785 }
1786
1787 return true;
1788}
1789
David Benjaminafc64de2016-07-19 17:12:41 +02001790static bool ClientHelloMatches(uint16_t version, const uint8_t *expected,
1791 size_t expected_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001792 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin2dc02042016-09-19 19:57:37 -04001793 if (!ctx ||
David Benjamine4706902016-09-20 15:12:23 -04001794 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001795 // Our default cipher list varies by CPU capabilities, so manually place
1796 // the ChaCha20 ciphers in front.
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -08001797 !SSL_CTX_set_strict_cipher_list(ctx.get(), "CHACHA20:ALL")) {
David Benjaminafc64de2016-07-19 17:12:41 +02001798 return false;
1799 }
David Benjamin2dc02042016-09-19 19:57:37 -04001800
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001801 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +02001802 if (!ssl) {
1803 return false;
1804 }
1805 std::vector<uint8_t> client_hello;
1806 if (!GetClientHello(ssl.get(), &client_hello)) {
1807 return false;
1808 }
1809
1810 // Zero the client_random.
1811 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
1812 1 + 3 + // handshake message header
1813 2; // client_version
1814 if (client_hello.size() < kRandomOffset + SSL3_RANDOM_SIZE) {
1815 fprintf(stderr, "ClientHello for version %04x too short.\n", version);
1816 return false;
1817 }
David Benjamin17cf2cb2016-12-13 01:07:13 -05001818 OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
David Benjaminafc64de2016-07-19 17:12:41 +02001819
1820 if (client_hello.size() != expected_len ||
David Benjamin17cf2cb2016-12-13 01:07:13 -05001821 OPENSSL_memcmp(client_hello.data(), expected, expected_len) != 0) {
David Benjaminafc64de2016-07-19 17:12:41 +02001822 fprintf(stderr, "ClientHello for version %04x did not match:\n", version);
1823 fprintf(stderr, "Got:\n\t");
1824 for (size_t i = 0; i < client_hello.size(); i++) {
1825 fprintf(stderr, "0x%02x, ", client_hello[i]);
1826 }
1827 fprintf(stderr, "\nWanted:\n\t");
1828 for (size_t i = 0; i < expected_len; i++) {
1829 fprintf(stderr, "0x%02x, ", expected[i]);
1830 }
1831 fprintf(stderr, "\n");
1832 return false;
1833 }
1834
1835 return true;
1836}
1837
1838// Tests that our ClientHellos do not change unexpectedly.
1839static bool TestClientHello() {
1840 static const uint8_t kSSL3ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001841 0x16,
1842 0x03, 0x00,
1843 0x00, 0x3f,
1844 0x01,
1845 0x00, 0x00, 0x3b,
1846 0x03, 0x00,
1847 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1848 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1849 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1850 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1851 0x00,
1852 0x00, 0x14,
1853 0xc0, 0x09,
1854 0xc0, 0x13,
1855 0x00, 0x33,
1856 0xc0, 0x0a,
1857 0xc0, 0x14,
1858 0x00, 0x39,
1859 0x00, 0x2f,
1860 0x00, 0x35,
1861 0x00, 0x0a,
1862 0x00, 0xff, 0x01, 0x00,
David Benjaminafc64de2016-07-19 17:12:41 +02001863 };
1864 if (!ClientHelloMatches(SSL3_VERSION, kSSL3ClientHello,
1865 sizeof(kSSL3ClientHello))) {
1866 return false;
1867 }
1868
1869 static const uint8_t kTLS1ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001870 0x16,
1871 0x03, 0x01,
1872 0x00, 0x5e,
1873 0x01,
1874 0x00, 0x00, 0x5a,
1875 0x03, 0x01,
1876 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1877 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1878 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1879 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1880 0x00,
1881 0x00, 0x12,
1882 0xc0, 0x09,
1883 0xc0, 0x13,
1884 0x00, 0x33,
1885 0xc0, 0x0a,
1886 0xc0, 0x14,
1887 0x00, 0x39,
1888 0x00, 0x2f,
1889 0x00, 0x35,
1890 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001891 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1892 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1893 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1894 };
1895 if (!ClientHelloMatches(TLS1_VERSION, kTLS1ClientHello,
1896 sizeof(kTLS1ClientHello))) {
1897 return false;
1898 }
1899
1900 static const uint8_t kTLS11ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001901 0x16,
1902 0x03, 0x01,
1903 0x00, 0x5e,
1904 0x01,
1905 0x00, 0x00, 0x5a,
1906 0x03, 0x02,
1907 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1908 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1909 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1910 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1911 0x00,
1912 0x00, 0x12,
1913 0xc0, 0x09,
1914 0xc0, 0x13,
1915 0x00, 0x33,
1916 0xc0, 0x0a,
1917 0xc0, 0x14,
1918 0x00, 0x39,
1919 0x00, 0x2f,
1920 0x00, 0x35,
1921 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001922 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1923 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1924 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1925 };
1926 if (!ClientHelloMatches(TLS1_1_VERSION, kTLS11ClientHello,
1927 sizeof(kTLS11ClientHello))) {
1928 return false;
1929 }
1930
David Benjamin3b584332017-01-24 22:47:18 -05001931 // kTLS12ClientHello assumes RSA-PSS, which is disabled for Android system
1932 // builds.
1933#if defined(BORINGSSL_ANDROID_SYSTEM)
1934 return true;
1935#endif
1936
David Benjaminafc64de2016-07-19 17:12:41 +02001937 static const uint8_t kTLS12ClientHello[] = {
Adam Langley2e839242017-01-19 15:12:44 -08001938 0x16, 0x03, 0x01, 0x00, 0x9a, 0x01, 0x00, 0x00, 0x96, 0x03, 0x03, 0x00,
David Benjamin57e929f2016-08-30 00:30:38 -04001939 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1940 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Adam Langley2e839242017-01-19 15:12:44 -08001941 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0xcc, 0xa9,
1942 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0x00, 0x9e, 0xc0, 0x2c, 0xc0, 0x30,
1943 0x00, 0x9f, 0xc0, 0x09, 0xc0, 0x23, 0xc0, 0x13, 0xc0, 0x27, 0x00, 0x33,
1944 0x00, 0x67, 0xc0, 0x0a, 0xc0, 0x24, 0xc0, 0x14, 0xc0, 0x28, 0x00, 0x39,
1945 0x00, 0x6b, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x3c, 0x00, 0x35,
1946 0x00, 0x3d, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37, 0xff, 0x01, 0x00, 0x01,
1947 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
1948 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
1949 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x00, 0x0b, 0x00,
1950 0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00,
1951 0x17, 0x00, 0x18,
David Benjaminafc64de2016-07-19 17:12:41 +02001952 };
1953 if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
1954 sizeof(kTLS12ClientHello))) {
1955 return false;
1956 }
1957
1958 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
1959 // implementation has settled enough that it won't change.
1960
1961 return true;
1962}
1963
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001964static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04001965
1966static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
1967 // Save the most recent session.
1968 g_last_session.reset(session);
1969 return 1;
1970}
1971
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001972static bssl::UniquePtr<SSL_SESSION> CreateClientSession(SSL_CTX *client_ctx,
David Benjamina20e5352016-08-02 19:09:41 -04001973 SSL_CTX *server_ctx) {
1974 g_last_session = nullptr;
1975 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
1976
1977 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001978 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001979 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
1980 nullptr /* no session */)) {
1981 fprintf(stderr, "Failed to connect client and server.\n");
1982 return nullptr;
1983 }
1984
1985 // Run the read loop to account for post-handshake tickets in TLS 1.3.
1986 SSL_read(client.get(), nullptr, 0);
1987
1988 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
1989
1990 if (!g_last_session) {
1991 fprintf(stderr, "Client did not receive a session.\n");
1992 return nullptr;
1993 }
1994 return std::move(g_last_session);
1995}
1996
1997static bool ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1998 SSL_SESSION *session,
1999 bool reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002000 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04002001 if (!ConnectClientAndServer(&client, &server, client_ctx,
2002 server_ctx, session)) {
2003 fprintf(stderr, "Failed to connect client and server.\n");
2004 return false;
2005 }
2006
2007 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2008 fprintf(stderr, "Client and server were inconsistent.\n");
2009 return false;
2010 }
2011
2012 bool was_reused = !!SSL_session_reused(client.get());
2013 if (was_reused != reused) {
2014 fprintf(stderr, "Session was%s reused, but we expected the opposite.\n",
2015 was_reused ? "" : " not");
2016 return false;
2017 }
2018
2019 return true;
2020}
2021
David Benjamin3c51d9b2016-11-01 17:50:42 -04002022static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
2023 SSL_CTX *server_ctx,
2024 SSL_SESSION *session) {
2025 g_last_session = nullptr;
2026 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
2027
2028 bssl::UniquePtr<SSL> client, server;
2029 if (!ConnectClientAndServer(&client, &server, client_ctx,
2030 server_ctx, session)) {
2031 fprintf(stderr, "Failed to connect client and server.\n");
2032 return nullptr;
2033 }
2034
2035 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
2036 fprintf(stderr, "Client and server were inconsistent.\n");
2037 return nullptr;
2038 }
2039
2040 if (!SSL_session_reused(client.get())) {
2041 fprintf(stderr, "Session was not reused.\n");
2042 return nullptr;
2043 }
2044
2045 // Run the read loop to account for post-handshake tickets in TLS 1.3.
2046 SSL_read(client.get(), nullptr, 0);
2047
2048 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
2049
2050 if (!g_last_session) {
2051 fprintf(stderr, "Client did not receive a renewed session.\n");
2052 return nullptr;
2053 }
2054 return std::move(g_last_session);
2055}
2056
David Benjamina933c382016-10-28 00:10:03 -04002057static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
2058 static const uint8_t kContext[] = {3};
2059
2060 if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
2061 return SSL_TLSEXT_ERR_ALERT_FATAL;
2062 }
2063
2064 return SSL_TLSEXT_ERR_OK;
2065}
2066
David Benjamin731058e2016-12-03 23:15:13 -05002067static int SwitchSessionIDContextEarly(const SSL_CLIENT_HELLO *client_hello) {
David Benjamina933c382016-10-28 00:10:03 -04002068 static const uint8_t kContext[] = {3};
2069
David Benjamin731058e2016-12-03 23:15:13 -05002070 if (!SSL_set_session_id_context(client_hello->ssl, kContext,
2071 sizeof(kContext))) {
David Benjamina933c382016-10-28 00:10:03 -04002072 return -1;
2073 }
2074
2075 return 1;
2076}
2077
David Benjamin0fef3052016-11-18 15:11:10 +09002078static bool TestSessionIDContext(bool is_dtls, const SSL_METHOD *method,
2079 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002080 bssl::UniquePtr<X509> cert = GetTestCertificate();
2081 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamina20e5352016-08-02 19:09:41 -04002082 if (!cert || !key) {
2083 return false;
2084 }
2085
2086 static const uint8_t kContext1[] = {1};
2087 static const uint8_t kContext2[] = {2};
2088
David Benjamin0fef3052016-11-18 15:11:10 +09002089 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2090 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2091 if (!server_ctx || !client_ctx ||
2092 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2093 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2094 !SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
2095 sizeof(kContext1)) ||
2096 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2097 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2098 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2099 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2100 return false;
2101 }
David Benjamina20e5352016-08-02 19:09:41 -04002102
David Benjamin0fef3052016-11-18 15:11:10 +09002103 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2104 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04002105
David Benjamin0fef3052016-11-18 15:11:10 +09002106 bssl::UniquePtr<SSL_SESSION> session =
2107 CreateClientSession(client_ctx.get(), server_ctx.get());
2108 if (!session) {
2109 fprintf(stderr, "Error getting session.\n");
2110 return false;
2111 }
David Benjamina20e5352016-08-02 19:09:41 -04002112
David Benjamin0fef3052016-11-18 15:11:10 +09002113 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2114 true /* expect session reused */)) {
2115 fprintf(stderr, "Error resuming session.\n");
2116 return false;
2117 }
David Benjamina20e5352016-08-02 19:09:41 -04002118
David Benjamin0fef3052016-11-18 15:11:10 +09002119 // Change the session ID context.
2120 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext2,
2121 sizeof(kContext2))) {
2122 return false;
2123 }
David Benjamina20e5352016-08-02 19:09:41 -04002124
David Benjamin0fef3052016-11-18 15:11:10 +09002125 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2126 false /* expect session not reused */)) {
2127 fprintf(stderr, "Error connecting with a different context.\n");
2128 return false;
2129 }
David Benjamina933c382016-10-28 00:10:03 -04002130
David Benjamin0fef3052016-11-18 15:11:10 +09002131 // Change the session ID context back and install an SNI callback to switch
2132 // it.
2133 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
2134 sizeof(kContext1))) {
2135 return false;
2136 }
David Benjamina933c382016-10-28 00:10:03 -04002137
David Benjamin0fef3052016-11-18 15:11:10 +09002138 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(),
2139 SwitchSessionIDContextSNI);
David Benjamina933c382016-10-28 00:10:03 -04002140
David Benjamin0fef3052016-11-18 15:11:10 +09002141 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2142 false /* expect session not reused */)) {
2143 fprintf(stderr, "Error connecting with a context switch on SNI callback.\n");
2144 return false;
2145 }
David Benjamina933c382016-10-28 00:10:03 -04002146
David Benjamin0fef3052016-11-18 15:11:10 +09002147 // Switch the session ID context with the early callback instead.
2148 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), nullptr);
2149 SSL_CTX_set_select_certificate_cb(server_ctx.get(),
2150 SwitchSessionIDContextEarly);
David Benjamina933c382016-10-28 00:10:03 -04002151
David Benjamin0fef3052016-11-18 15:11:10 +09002152 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2153 false /* expect session not reused */)) {
2154 fprintf(stderr,
2155 "Error connecting with a context switch on early callback.\n");
2156 return false;
David Benjamina20e5352016-08-02 19:09:41 -04002157 }
2158
2159 return true;
2160}
2161
David Benjamin721e8b72016-08-03 13:13:17 -04002162static timeval g_current_time;
2163
2164static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2165 *out_clock = g_current_time;
2166}
2167
David Benjamin17b30832017-01-28 14:00:32 -05002168static void FrozenTimeCallback(const SSL *ssl, timeval *out_clock) {
2169 out_clock->tv_sec = 1000;
2170 out_clock->tv_usec = 0;
2171}
2172
David Benjamin3c51d9b2016-11-01 17:50:42 -04002173static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
2174 EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
2175 int encrypt) {
2176 static const uint8_t kZeros[16] = {0};
2177
2178 if (encrypt) {
David Benjamin17cf2cb2016-12-13 01:07:13 -05002179 OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
David Benjamin3c51d9b2016-11-01 17:50:42 -04002180 RAND_bytes(iv, 16);
David Benjamin17cf2cb2016-12-13 01:07:13 -05002181 } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
David Benjamin3c51d9b2016-11-01 17:50:42 -04002182 return 0;
2183 }
2184
2185 if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
2186 !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
2187 return -1;
2188 }
2189
2190 // Returning two from the callback in decrypt mode renews the
2191 // session in TLS 1.2 and below.
2192 return encrypt ? 1 : 2;
2193}
2194
David Benjamin123db572016-11-03 16:59:25 -04002195static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
David Benjamin123db572016-11-03 16:59:25 -04002196 if (session->tlsext_ticklen < 16 + 16 + SHA256_DIGEST_LENGTH) {
2197 return false;
2198 }
2199
David Benjamin123db572016-11-03 16:59:25 -04002200 const uint8_t *ciphertext = session->tlsext_tick + 16 + 16;
2201 size_t len = session->tlsext_ticklen - 16 - 16 - SHA256_DIGEST_LENGTH;
2202 std::unique_ptr<uint8_t[]> plaintext(new uint8_t[len]);
2203
David Benjamin9b63f292016-11-15 00:44:05 -05002204#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
2205 // Fuzzer-mode tickets are unencrypted.
David Benjamin17cf2cb2016-12-13 01:07:13 -05002206 OPENSSL_memcpy(plaintext.get(), ciphertext, len);
David Benjamin9b63f292016-11-15 00:44:05 -05002207#else
2208 static const uint8_t kZeros[16] = {0};
2209 const uint8_t *iv = session->tlsext_tick + 16;
David Benjamin123db572016-11-03 16:59:25 -04002210 bssl::ScopedEVP_CIPHER_CTX ctx;
2211 int len1, len2;
2212 if (!EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
2213 !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext, len) ||
2214 !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
2215 return false;
2216 }
2217
2218 len = static_cast<size_t>(len1 + len2);
David Benjamin9b63f292016-11-15 00:44:05 -05002219#endif
David Benjamin123db572016-11-03 16:59:25 -04002220
Adam Langley46db7af2017-02-01 15:49:37 -08002221 bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
2222 if (!ssl_ctx) {
2223 return false;
2224 }
David Benjamin123db572016-11-03 16:59:25 -04002225 bssl::UniquePtr<SSL_SESSION> server_session(
Adam Langley46db7af2017-02-01 15:49:37 -08002226 SSL_SESSION_from_bytes(plaintext.get(), len, ssl_ctx.get()));
David Benjamin123db572016-11-03 16:59:25 -04002227 if (!server_session) {
2228 return false;
2229 }
2230
2231 *out = server_session->time;
2232 return true;
2233}
2234
David Benjamin0fef3052016-11-18 15:11:10 +09002235static bool TestSessionTimeout(bool is_dtls, const SSL_METHOD *method,
2236 uint16_t version) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002237 bssl::UniquePtr<X509> cert = GetTestCertificate();
2238 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin721e8b72016-08-03 13:13:17 -04002239 if (!cert || !key) {
2240 return false;
2241 }
2242
David Benjamin0fef3052016-11-18 15:11:10 +09002243 for (bool server_test : std::vector<bool>{false, true}) {
David Benjamin17b30832017-01-28 14:00:32 -05002244 static const time_t kStartTime = 1000;
David Benjamin0fef3052016-11-18 15:11:10 +09002245 g_current_time.tv_sec = kStartTime;
David Benjamin1b22f852016-10-27 16:36:32 -04002246
David Benjamin17b30832017-01-28 14:00:32 -05002247 // We are willing to use a longer lifetime for TLS 1.3 sessions as
2248 // resumptions still perform ECDHE.
2249 const time_t timeout = version == TLS1_3_VERSION
2250 ? SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT
2251 : SSL_DEFAULT_SESSION_TIMEOUT;
2252
David Benjamin0fef3052016-11-18 15:11:10 +09002253 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2254 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2255 if (!server_ctx || !client_ctx ||
2256 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2257 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2258 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2259 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2260 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2261 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2262 return false;
2263 }
2264
2265 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2266 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
2267
David Benjamin17b30832017-01-28 14:00:32 -05002268 // Both client and server must enforce session timeouts. We configure the
2269 // other side with a frozen clock so it never expires tickets.
David Benjamin0fef3052016-11-18 15:11:10 +09002270 if (server_test) {
David Benjamin17b30832017-01-28 14:00:32 -05002271 SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002272 SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
2273 } else {
2274 SSL_CTX_set_current_time_cb(client_ctx.get(), CurrentTimeCallback);
David Benjamin17b30832017-01-28 14:00:32 -05002275 SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
David Benjamin0fef3052016-11-18 15:11:10 +09002276 }
2277
2278 // Configure a ticket callback which renews tickets.
2279 SSL_CTX_set_tlsext_ticket_key_cb(server_ctx.get(), RenewTicketCallback);
2280
2281 bssl::UniquePtr<SSL_SESSION> session =
2282 CreateClientSession(client_ctx.get(), server_ctx.get());
2283 if (!session) {
2284 fprintf(stderr, "Error getting session.\n");
2285 return false;
2286 }
2287
2288 // Advance the clock just behind the timeout.
David Benjamin17b30832017-01-28 14:00:32 -05002289 g_current_time.tv_sec += timeout - 1;
David Benjamin0fef3052016-11-18 15:11:10 +09002290
2291 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2292 true /* expect session reused */)) {
2293 fprintf(stderr, "Error resuming session.\n");
2294 return false;
2295 }
2296
2297 // Advance the clock one more second.
2298 g_current_time.tv_sec++;
2299
2300 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2301 false /* expect session not reused */)) {
2302 fprintf(stderr, "Error resuming session.\n");
2303 return false;
2304 }
2305
2306 // Rewind the clock to before the session was minted.
2307 g_current_time.tv_sec = kStartTime - 1;
2308
2309 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2310 false /* expect session not reused */)) {
2311 fprintf(stderr, "Error resuming session.\n");
2312 return false;
2313 }
2314
2315 // SSL 3.0 cannot renew sessions.
2316 if (version == SSL3_VERSION) {
2317 continue;
2318 }
2319
2320 // Renew the session 10 seconds before expiration.
David Benjamin17b30832017-01-28 14:00:32 -05002321 time_t new_start_time = kStartTime + timeout - 10;
2322 g_current_time.tv_sec = new_start_time;
David Benjamin0fef3052016-11-18 15:11:10 +09002323 bssl::UniquePtr<SSL_SESSION> new_session =
2324 ExpectSessionRenewed(client_ctx.get(), server_ctx.get(), session.get());
2325 if (!new_session) {
2326 fprintf(stderr, "Error renewing session.\n");
2327 return false;
2328 }
2329
2330 // This new session is not the same object as before.
2331 if (session.get() == new_session.get()) {
2332 fprintf(stderr, "New and old sessions alias.\n");
2333 return false;
2334 }
2335
2336 // Check the sessions have timestamps measured from issuance.
2337 long session_time = 0;
2338 if (server_test) {
2339 if (!GetServerTicketTime(&session_time, new_session.get())) {
2340 fprintf(stderr, "Failed to decode session ticket.\n");
David Benjaminb2e2e322016-11-01 17:32:54 -04002341 return false;
2342 }
David Benjamin0fef3052016-11-18 15:11:10 +09002343 } else {
2344 session_time = new_session->time;
2345 }
David Benjamin721e8b72016-08-03 13:13:17 -04002346
David Benjamin0fef3052016-11-18 15:11:10 +09002347 if (session_time != g_current_time.tv_sec) {
2348 fprintf(stderr, "New session is not measured from issuance.\n");
2349 return false;
2350 }
David Benjamin721e8b72016-08-03 13:13:17 -04002351
David Benjamin17b30832017-01-28 14:00:32 -05002352 if (version == TLS1_3_VERSION) {
2353 // Renewal incorporates fresh key material in TLS 1.3, so we extend the
2354 // lifetime TLS 1.3.
2355 g_current_time.tv_sec = new_start_time + timeout - 1;
2356 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2357 new_session.get(),
2358 true /* expect session reused */)) {
2359 fprintf(stderr, "Error resuming renewed session.\n");
2360 return false;
2361 }
David Benjamin721e8b72016-08-03 13:13:17 -04002362
David Benjamin17b30832017-01-28 14:00:32 -05002363 // The new session expires after the new timeout.
2364 g_current_time.tv_sec = new_start_time + timeout + 1;
2365 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2366 new_session.get(),
2367 false /* expect session ot reused */)) {
2368 fprintf(stderr, "Renewed session's lifetime is too long.\n");
2369 return false;
2370 }
2371
2372 // Renew the session until it begins just past the auth timeout.
2373 time_t auth_end_time = kStartTime + SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
2374 while (new_start_time < auth_end_time - 1000) {
2375 // Get as close as possible to target start time.
2376 new_start_time =
2377 std::min(auth_end_time - 1000, new_start_time + timeout - 1);
2378 g_current_time.tv_sec = new_start_time;
2379 new_session = ExpectSessionRenewed(client_ctx.get(), server_ctx.get(),
2380 new_session.get());
2381 if (!new_session) {
2382 fprintf(stderr, "Error renewing session.\n");
2383 return false;
2384 }
2385 }
2386
2387 // Now the session's lifetime is bound by the auth timeout.
2388 g_current_time.tv_sec = auth_end_time - 1;
2389 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2390 new_session.get(),
2391 true /* expect session reused */)) {
2392 fprintf(stderr, "Error resuming renewed session.\n");
2393 return false;
2394 }
2395
2396 g_current_time.tv_sec = auth_end_time + 1;
2397 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2398 new_session.get(),
2399 false /* expect session ot reused */)) {
2400 fprintf(stderr, "Renewed session's lifetime is too long.\n");
2401 return false;
2402 }
2403 } else {
2404 // The new session is usable just before the old expiration.
2405 g_current_time.tv_sec = kStartTime + timeout - 1;
2406 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2407 new_session.get(),
2408 true /* expect session reused */)) {
2409 fprintf(stderr, "Error resuming renewed session.\n");
2410 return false;
2411 }
2412
2413 // Renewal does not extend the lifetime, so it is not usable beyond the
2414 // old expiration.
2415 g_current_time.tv_sec = kStartTime + timeout + 1;
2416 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(),
2417 new_session.get(),
2418 false /* expect session not reused */)) {
2419 fprintf(stderr, "Renewed session's lifetime is too long.\n");
2420 return false;
2421 }
David Benjamin1b22f852016-10-27 16:36:32 -04002422 }
David Benjamin721e8b72016-08-03 13:13:17 -04002423 }
2424
2425 return true;
2426}
2427
David Benjamin0fc37ef2016-08-17 15:29:46 -04002428static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
2429 SSL_CTX *ctx = reinterpret_cast<SSL_CTX*>(arg);
2430 SSL_set_SSL_CTX(ssl, ctx);
2431 return SSL_TLSEXT_ERR_OK;
2432}
2433
David Benjamin0fef3052016-11-18 15:11:10 +09002434static bool TestSNICallback(bool is_dtls, const SSL_METHOD *method,
2435 uint16_t version) {
2436 // SSL 3.0 lacks extensions.
2437 if (version == SSL3_VERSION) {
2438 return true;
2439 }
2440
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002441 bssl::UniquePtr<X509> cert = GetTestCertificate();
2442 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2443 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
2444 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
David Benjamin0fc37ef2016-08-17 15:29:46 -04002445 if (!cert || !key || !cert2 || !key2) {
2446 return false;
2447 }
2448
David Benjamin0fef3052016-11-18 15:11:10 +09002449 // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
2450 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002451
David Benjamin83a32122017-02-14 18:34:54 -05002452 static const uint8_t kSCTList[] = {0, 6, 0, 4, 5, 6, 7, 8};
2453 static const uint8_t kOCSPResponse[] = {1, 2, 3, 4};
2454
David Benjamin0fef3052016-11-18 15:11:10 +09002455 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2456 bssl::UniquePtr<SSL_CTX> server_ctx2(SSL_CTX_new(method));
2457 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2458 if (!server_ctx || !server_ctx2 || !client_ctx ||
2459 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2460 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2461 !SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()) ||
2462 !SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()) ||
David Benjamin83a32122017-02-14 18:34:54 -05002463 !SSL_CTX_set_signed_cert_timestamp_list(server_ctx2.get(), kSCTList,
2464 sizeof(kSCTList)) ||
2465 !SSL_CTX_set_ocsp_response(server_ctx2.get(), kOCSPResponse,
2466 sizeof(kOCSPResponse)) ||
David Benjamin0fef3052016-11-18 15:11:10 +09002467 // Historically signing preferences would be lost in some cases with the
2468 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2469 // this doesn't happen when |version| is TLS 1.2, configure the private
2470 // key to only sign SHA-256.
2471 !SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(), &kECDSAWithSHA256,
2472 1) ||
2473 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2474 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2475 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2476 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2477 !SSL_CTX_set_min_proto_version(server_ctx2.get(), version) ||
2478 !SSL_CTX_set_max_proto_version(server_ctx2.get(), version)) {
2479 return false;
2480 }
David Benjamin0fc37ef2016-08-17 15:29:46 -04002481
David Benjamin0fef3052016-11-18 15:11:10 +09002482 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), SwitchContext);
2483 SSL_CTX_set_tlsext_servername_arg(server_ctx.get(), server_ctx2.get());
David Benjamin0fc37ef2016-08-17 15:29:46 -04002484
David Benjamin83a32122017-02-14 18:34:54 -05002485 SSL_CTX_enable_signed_cert_timestamps(client_ctx.get());
2486 SSL_CTX_enable_ocsp_stapling(client_ctx.get());
2487
David Benjamin0fef3052016-11-18 15:11:10 +09002488 bssl::UniquePtr<SSL> client, server;
2489 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2490 server_ctx.get(), nullptr)) {
2491 fprintf(stderr, "Handshake failed.\n");
2492 return false;
2493 }
David Benjamin0fc37ef2016-08-17 15:29:46 -04002494
David Benjamin0fef3052016-11-18 15:11:10 +09002495 // The client should have received |cert2|.
2496 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client.get()));
2497 if (!peer || X509_cmp(peer.get(), cert2.get()) != 0) {
2498 fprintf(stderr, "Incorrect certificate received.\n");
2499 return false;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002500 }
2501
David Benjamin83a32122017-02-14 18:34:54 -05002502 // The client should have received |server_ctx2|'s SCT list.
2503 const uint8_t *data;
2504 size_t len;
2505 SSL_get0_signed_cert_timestamp_list(client.get(), &data, &len);
2506 if (Bytes(kSCTList) != Bytes(data, len)) {
2507 fprintf(stderr, "Incorrect SCT list received.\n");
2508 return false;
2509 }
2510
2511 // The client should have received |server_ctx2|'s OCSP response.
2512 SSL_get0_ocsp_response(client.get(), &data, &len);
2513 if (Bytes(kOCSPResponse) != Bytes(data, len)) {
2514 fprintf(stderr, "Incorrect OCSP response received.\n");
2515 return false;
2516 }
2517
David Benjamin0fc37ef2016-08-17 15:29:46 -04002518 return true;
2519}
2520
David Benjaminf0d8e222017-02-04 10:58:26 -05002521// Test that the early callback can swap the maximum version.
2522TEST(SSLTest, EarlyCallbackVersionSwitch) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002523 bssl::UniquePtr<X509> cert = GetTestCertificate();
2524 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2525 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2526 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002527 ASSERT_TRUE(cert);
2528 ASSERT_TRUE(key);
2529 ASSERT_TRUE(server_ctx);
2530 ASSERT_TRUE(client_ctx);
2531 ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
2532 ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
2533 ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
2534 ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
David Benjamin99620572016-08-30 00:35:36 -04002535
David Benjaminf0d8e222017-02-04 10:58:26 -05002536 SSL_CTX_set_select_certificate_cb(
2537 server_ctx.get(), [](const SSL_CLIENT_HELLO *client_hello) -> int {
2538 if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
2539 return -1;
2540 }
2541
2542 return 1;
2543 });
David Benjamin99620572016-08-30 00:35:36 -04002544
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002545 bssl::UniquePtr<SSL> client, server;
David Benjaminf0d8e222017-02-04 10:58:26 -05002546 ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
2547 server_ctx.get(), nullptr));
2548 EXPECT_EQ(TLS1_2_VERSION, SSL_version(client.get()));
David Benjamin99620572016-08-30 00:35:36 -04002549}
2550
David Benjaminf0d8e222017-02-04 10:58:26 -05002551TEST(SSLTest, SetVersion) {
David Benjamin2dc02042016-09-19 19:57:37 -04002552 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002553 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002554
David Benjaminf0d8e222017-02-04 10:58:26 -05002555 // Set valid TLS versions.
2556 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2557 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
2558 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2559 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002560
David Benjaminf0d8e222017-02-04 10:58:26 -05002561 // Invalid TLS versions are rejected.
2562 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2563 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x0200));
2564 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2565 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2566 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x0200));
2567 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002568
David Benjaminf0d8e222017-02-04 10:58:26 -05002569 // Zero is the default version.
2570 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
2571 EXPECT_EQ(TLS1_2_VERSION, ctx->max_version);
2572 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
2573 EXPECT_EQ(SSL3_VERSION, ctx->min_version);
David Benjamine34bcc92016-09-21 16:53:09 -04002574
David Benjamin2dc02042016-09-19 19:57:37 -04002575 ctx.reset(SSL_CTX_new(DTLS_method()));
David Benjaminf0d8e222017-02-04 10:58:26 -05002576 ASSERT_TRUE(ctx);
David Benjamin2dc02042016-09-19 19:57:37 -04002577
David Benjaminf0d8e222017-02-04 10:58:26 -05002578 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
2579 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION));
2580 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
2581 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION));
David Benjamin2dc02042016-09-19 19:57:37 -04002582
David Benjaminf0d8e222017-02-04 10:58:26 -05002583 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
2584 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2585 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2586 EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
2587 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
2588 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
2589 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
2590 EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
David Benjamin2dc02042016-09-19 19:57:37 -04002591
David Benjaminf0d8e222017-02-04 10:58:26 -05002592 EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
2593 EXPECT_EQ(TLS1_2_VERSION, ctx->max_version);
2594 EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
2595 EXPECT_EQ(TLS1_1_VERSION, ctx->min_version);
David Benjamin2dc02042016-09-19 19:57:37 -04002596}
2597
David Benjamin458334a2016-12-15 13:53:25 -05002598static const char *GetVersionName(uint16_t version) {
2599 switch (version) {
2600 case SSL3_VERSION:
2601 return "SSLv3";
2602 case TLS1_VERSION:
2603 return "TLSv1";
2604 case TLS1_1_VERSION:
2605 return "TLSv1.1";
2606 case TLS1_2_VERSION:
2607 return "TLSv1.2";
2608 case TLS1_3_VERSION:
2609 return "TLSv1.3";
2610 case DTLS1_VERSION:
2611 return "DTLSv1";
2612 case DTLS1_2_VERSION:
2613 return "DTLSv1.2";
2614 default:
2615 return "???";
2616 }
2617}
2618
David Benjamin0fef3052016-11-18 15:11:10 +09002619static bool TestVersion(bool is_dtls, const SSL_METHOD *method,
2620 uint16_t version) {
David Benjamincb18ac22016-09-27 14:09:15 -04002621 bssl::UniquePtr<X509> cert = GetTestCertificate();
2622 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2623 if (!cert || !key) {
2624 return false;
2625 }
2626
David Benjamin0fef3052016-11-18 15:11:10 +09002627 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2628 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2629 bssl::UniquePtr<SSL> client, server;
2630 if (!server_ctx || !client_ctx ||
2631 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2632 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2633 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2634 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2635 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2636 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2637 !ConnectClientAndServer(&client, &server, client_ctx.get(),
2638 server_ctx.get(), nullptr /* no session */)) {
2639 fprintf(stderr, "Failed to connect.\n");
2640 return false;
2641 }
David Benjamincb18ac22016-09-27 14:09:15 -04002642
David Benjamin0fef3052016-11-18 15:11:10 +09002643 if (SSL_version(client.get()) != version ||
2644 SSL_version(server.get()) != version) {
2645 fprintf(stderr, "Version mismatch. Got %04x and %04x, wanted %04x.\n",
2646 SSL_version(client.get()), SSL_version(server.get()), version);
2647 return false;
David Benjamincb18ac22016-09-27 14:09:15 -04002648 }
2649
David Benjamin458334a2016-12-15 13:53:25 -05002650 // Test the version name is reported as expected.
2651 const char *version_name = GetVersionName(version);
2652 if (strcmp(version_name, SSL_get_version(client.get())) != 0 ||
2653 strcmp(version_name, SSL_get_version(server.get())) != 0) {
2654 fprintf(stderr, "Version name mismatch. Got '%s' and '%s', wanted '%s'.\n",
2655 SSL_get_version(client.get()), SSL_get_version(server.get()),
2656 version_name);
2657 return false;
2658 }
2659
2660 // Test SSL_SESSION reports the same name.
2661 const char *client_name =
2662 SSL_SESSION_get_version(SSL_get_session(client.get()));
2663 const char *server_name =
2664 SSL_SESSION_get_version(SSL_get_session(server.get()));
2665 if (strcmp(version_name, client_name) != 0 ||
2666 strcmp(version_name, server_name) != 0) {
2667 fprintf(stderr,
2668 "Session version name mismatch. Got '%s' and '%s', wanted '%s'.\n",
2669 client_name, server_name, version_name);
2670 return false;
2671 }
2672
David Benjamincb18ac22016-09-27 14:09:15 -04002673 return true;
2674}
2675
David Benjamin9ef31f02016-10-31 18:01:13 -04002676// Tests that that |SSL_get_pending_cipher| is available during the ALPN
2677// selection callback.
David Benjamin0fef3052016-11-18 15:11:10 +09002678static bool TestALPNCipherAvailable(bool is_dtls, const SSL_METHOD *method,
2679 uint16_t version) {
2680 // SSL 3.0 lacks extensions.
2681 if (version == SSL3_VERSION) {
2682 return true;
2683 }
2684
David Benjamin9ef31f02016-10-31 18:01:13 -04002685 static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
2686
2687 bssl::UniquePtr<X509> cert = GetTestCertificate();
2688 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2689 if (!cert || !key) {
2690 return false;
2691 }
2692
David Benjamin0fef3052016-11-18 15:11:10 +09002693 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
2694 if (!ctx || !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
2695 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
2696 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
2697 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
2698 SSL_CTX_set_alpn_protos(ctx.get(), kALPNProtos, sizeof(kALPNProtos)) !=
2699 0) {
2700 return false;
2701 }
2702
2703 // The ALPN callback does not fail the handshake on error, so have the
2704 // callback write a boolean.
2705 std::pair<uint16_t, bool> callback_state(version, false);
2706 SSL_CTX_set_alpn_select_cb(
2707 ctx.get(),
2708 [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
2709 unsigned in_len, void *arg) -> int {
2710 auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
2711 if (SSL_get_pending_cipher(ssl) != nullptr &&
2712 SSL_version(ssl) == state->first) {
2713 state->second = true;
2714 }
2715 return SSL_TLSEXT_ERR_NOACK;
2716 },
2717 &callback_state);
2718
2719 bssl::UniquePtr<SSL> client, server;
2720 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2721 nullptr /* no session */)) {
2722 return false;
2723 }
2724
2725 if (!callback_state.second) {
2726 fprintf(stderr, "The pending cipher was not known in the ALPN callback.\n");
2727 return false;
2728 }
2729
2730 return true;
2731}
2732
David Benjaminb79cc842016-12-07 15:57:14 -05002733static bool TestSSLClearSessionResumption(bool is_dtls,
2734 const SSL_METHOD *method,
2735 uint16_t version) {
2736 // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
2737 // API pattern.
2738 if (version == TLS1_3_VERSION) {
2739 return true;
2740 }
2741
2742 bssl::UniquePtr<X509> cert = GetTestCertificate();
2743 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2744 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2745 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2746 if (!cert || !key || !server_ctx || !client_ctx ||
2747 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2748 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2749 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2750 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2751 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2752 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
2753 return false;
2754 }
2755
2756 // Connect a client and a server.
2757 bssl::UniquePtr<SSL> client, server;
2758 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2759 server_ctx.get(), nullptr /* no session */)) {
2760 return false;
2761 }
2762
2763 if (SSL_session_reused(client.get()) ||
2764 SSL_session_reused(server.get())) {
2765 fprintf(stderr, "Session unexpectedly reused.\n");
2766 return false;
2767 }
2768
2769 // Reset everything.
2770 if (!SSL_clear(client.get()) ||
2771 !SSL_clear(server.get())) {
2772 fprintf(stderr, "SSL_clear failed.\n");
2773 return false;
2774 }
2775
2776 // Attempt to connect a second time.
2777 if (!CompleteHandshakes(client.get(), server.get())) {
2778 fprintf(stderr, "Could not reuse SSL objects.\n");
2779 return false;
2780 }
2781
2782 // |SSL_clear| should implicitly offer the previous session to the server.
2783 if (!SSL_session_reused(client.get()) ||
2784 !SSL_session_reused(server.get())) {
2785 fprintf(stderr, "Session was not reused in second try.\n");
2786 return false;
2787 }
2788
2789 return true;
2790}
2791
David Benjamin1444c3a2016-12-20 17:23:11 -05002792static bool ChainsEqual(STACK_OF(X509) *chain,
2793 const std::vector<X509 *> &expected) {
2794 if (sk_X509_num(chain) != expected.size()) {
2795 return false;
2796 }
2797
2798 for (size_t i = 0; i < expected.size(); i++) {
2799 if (X509_cmp(sk_X509_value(chain, i), expected[i]) != 0) {
2800 return false;
2801 }
2802 }
2803
2804 return true;
2805}
2806
2807static bool TestAutoChain(bool is_dtls, const SSL_METHOD *method,
2808 uint16_t version) {
David Benjamin1444c3a2016-12-20 17:23:11 -05002809 bssl::UniquePtr<X509> cert = GetChainTestCertificate();
2810 bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
2811 bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
2812 if (!cert || !intermediate || !key) {
2813 return false;
2814 }
2815
2816 // Configure both client and server to accept any certificate. Add
2817 // |intermediate| to the cert store.
2818 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
2819 if (!ctx ||
2820 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
2821 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
2822 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
2823 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
2824 !X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx.get()),
2825 intermediate.get())) {
2826 return false;
2827 }
2828 SSL_CTX_set_verify(
2829 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
2830 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
2831
2832 // By default, the client and server should each only send the leaf.
2833 bssl::UniquePtr<SSL> client, server;
2834 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2835 nullptr /* no session */)) {
2836 return false;
2837 }
2838
2839 if (!ChainsEqual(SSL_get_peer_full_cert_chain(client.get()), {cert.get()})) {
2840 fprintf(stderr, "Client-received chain did not match.\n");
2841 return false;
2842 }
2843
2844 if (!ChainsEqual(SSL_get_peer_full_cert_chain(server.get()), {cert.get()})) {
2845 fprintf(stderr, "Server-received chain did not match.\n");
2846 return false;
2847 }
2848
2849 // If auto-chaining is enabled, then the intermediate is sent.
2850 SSL_CTX_clear_mode(ctx.get(), SSL_MODE_NO_AUTO_CHAIN);
2851 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2852 nullptr /* no session */)) {
2853 return false;
2854 }
2855
2856 if (!ChainsEqual(SSL_get_peer_full_cert_chain(client.get()),
2857 {cert.get(), intermediate.get()})) {
2858 fprintf(stderr, "Client-received chain did not match (auto-chaining).\n");
2859 return false;
2860 }
2861
2862 if (!ChainsEqual(SSL_get_peer_full_cert_chain(server.get()),
2863 {cert.get(), intermediate.get()})) {
2864 fprintf(stderr, "Server-received chain did not match (auto-chaining).\n");
2865 return false;
2866 }
2867
2868 // Auto-chaining does not override explicitly-configured intermediates.
2869 if (!SSL_CTX_add1_chain_cert(ctx.get(), cert.get()) ||
2870 !ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2871 nullptr /* no session */)) {
2872 return false;
2873 }
2874
2875 if (!ChainsEqual(SSL_get_peer_full_cert_chain(client.get()),
2876 {cert.get(), cert.get()})) {
2877 fprintf(stderr,
2878 "Client-received chain did not match (auto-chaining, explicit "
2879 "intermediate).\n");
2880 return false;
2881 }
2882
2883 if (!ChainsEqual(SSL_get_peer_full_cert_chain(server.get()),
2884 {cert.get(), cert.get()})) {
2885 fprintf(stderr,
2886 "Server-received chain did not match (auto-chaining, explicit "
2887 "intermediate).\n");
2888 return false;
2889 }
2890
2891 return true;
2892}
2893
David Benjamin48063c22017-01-01 23:56:36 -05002894static bool ExpectBadWriteRetry() {
2895 int err = ERR_get_error();
2896 if (ERR_GET_LIB(err) != ERR_LIB_SSL ||
2897 ERR_GET_REASON(err) != SSL_R_BAD_WRITE_RETRY) {
2898 char buf[ERR_ERROR_STRING_BUF_LEN];
2899 ERR_error_string_n(err, buf, sizeof(buf));
2900 fprintf(stderr, "Wanted SSL_R_BAD_WRITE_RETRY, got: %s.\n", buf);
2901 return false;
2902 }
2903
2904 if (ERR_peek_error() != 0) {
2905 fprintf(stderr, "Unexpected error following SSL_R_BAD_WRITE_RETRY.\n");
2906 return false;
2907 }
2908
2909 return true;
2910}
2911
2912static bool TestSSLWriteRetry(bool is_dtls, const SSL_METHOD *method,
2913 uint16_t version) {
2914 if (is_dtls) {
2915 return true;
2916 }
2917
2918 for (bool enable_partial_write : std::vector<bool>{false, true}) {
2919 // Connect a client and server.
2920 bssl::UniquePtr<X509> cert = GetTestCertificate();
2921 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2922 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
2923 bssl::UniquePtr<SSL> client, server;
2924 if (!cert || !key || !ctx ||
2925 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
2926 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
2927 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
2928 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
2929 !ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
2930 nullptr /* no session */)) {
2931 return false;
2932 }
2933
2934 if (enable_partial_write) {
2935 SSL_set_mode(client.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
2936 }
2937
2938 // Write without reading until the buffer is full and we have an unfinished
2939 // write. Keep a count so we may reread it again later. "hello!" will be
2940 // written in two chunks, "hello" and "!".
2941 char data[] = "hello!";
2942 static const int kChunkLen = 5; // The length of "hello".
2943 unsigned count = 0;
2944 for (;;) {
2945 int ret = SSL_write(client.get(), data, kChunkLen);
2946 if (ret <= 0) {
2947 int err = SSL_get_error(client.get(), ret);
2948 if (SSL_get_error(client.get(), ret) == SSL_ERROR_WANT_WRITE) {
2949 break;
2950 }
2951 fprintf(stderr, "SSL_write failed in unexpected way: %d\n", err);
2952 return false;
2953 }
2954
2955 if (ret != 5) {
2956 fprintf(stderr, "SSL_write wrote %d bytes, expected 5.\n", ret);
2957 return false;
2958 }
2959
2960 count++;
2961 }
2962
2963 // Retrying with the same parameters is legal.
2964 if (SSL_get_error(client.get(), SSL_write(client.get(), data, kChunkLen)) !=
2965 SSL_ERROR_WANT_WRITE) {
2966 fprintf(stderr, "SSL_write retry unexpectedly failed.\n");
2967 return false;
2968 }
2969
2970 // Retrying with the same buffer but shorter length is not legal.
2971 if (SSL_get_error(client.get(),
2972 SSL_write(client.get(), data, kChunkLen - 1)) !=
2973 SSL_ERROR_SSL ||
2974 !ExpectBadWriteRetry()) {
2975 fprintf(stderr, "SSL_write retry did not fail as expected.\n");
2976 return false;
2977 }
2978
2979 // Retrying with a different buffer pointer is not legal.
2980 char data2[] = "hello";
2981 if (SSL_get_error(client.get(), SSL_write(client.get(), data2,
2982 kChunkLen)) != SSL_ERROR_SSL ||
2983 !ExpectBadWriteRetry()) {
2984 fprintf(stderr, "SSL_write retry did not fail as expected.\n");
2985 return false;
2986 }
2987
2988 // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move.
2989 SSL_set_mode(client.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
2990 if (SSL_get_error(client.get(),
2991 SSL_write(client.get(), data2, kChunkLen)) !=
2992 SSL_ERROR_WANT_WRITE) {
2993 fprintf(stderr, "SSL_write retry unexpectedly failed.\n");
2994 return false;
2995 }
2996
2997 // |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| does not disable length checks.
2998 if (SSL_get_error(client.get(),
2999 SSL_write(client.get(), data2, kChunkLen - 1)) !=
3000 SSL_ERROR_SSL ||
3001 !ExpectBadWriteRetry()) {
3002 fprintf(stderr, "SSL_write retry did not fail as expected.\n");
3003 return false;
3004 }
3005
3006 // Retrying with a larger buffer is legal.
3007 if (SSL_get_error(client.get(),
3008 SSL_write(client.get(), data, kChunkLen + 1)) !=
3009 SSL_ERROR_WANT_WRITE) {
3010 fprintf(stderr, "SSL_write retry unexpectedly failed.\n");
3011 return false;
3012 }
3013
3014 // Drain the buffer.
3015 char buf[20];
3016 for (unsigned i = 0; i < count; i++) {
3017 if (SSL_read(server.get(), buf, sizeof(buf)) != kChunkLen ||
3018 OPENSSL_memcmp(buf, "hello", kChunkLen) != 0) {
3019 fprintf(stderr, "Failed to read initial records.\n");
3020 return false;
3021 }
3022 }
3023
3024 // Now that there is space, a retry with a larger buffer should flush the
3025 // pending record, skip over that many bytes of input (on assumption they
3026 // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE
3027 // is set, this will complete in two steps.
3028 char data3[] = "_____!";
3029 if (enable_partial_write) {
3030 if (SSL_write(client.get(), data3, kChunkLen + 1) != kChunkLen ||
3031 SSL_write(client.get(), data3 + kChunkLen, 1) != 1) {
3032 fprintf(stderr, "SSL_write retry failed.\n");
3033 return false;
3034 }
3035 } else if (SSL_write(client.get(), data3, kChunkLen + 1) != kChunkLen + 1) {
3036 fprintf(stderr, "SSL_write retry failed.\n");
3037 return false;
3038 }
3039
3040 // Check the last write was correct. The data will be spread over two
3041 // records, so SSL_read returns twice.
3042 if (SSL_read(server.get(), buf, sizeof(buf)) != kChunkLen ||
3043 OPENSSL_memcmp(buf, "hello", kChunkLen) != 0 ||
3044 SSL_read(server.get(), buf, sizeof(buf)) != 1 ||
3045 buf[0] != '!') {
3046 fprintf(stderr, "Failed to read write retry.\n");
3047 return false;
3048 }
3049 }
3050
3051 return true;
3052}
3053
David Benjamin0fef3052016-11-18 15:11:10 +09003054static bool ForEachVersion(bool (*test_func)(bool is_dtls,
3055 const SSL_METHOD *method,
3056 uint16_t version)) {
3057 static uint16_t kTLSVersions[] = {
David Benjamin3b584332017-01-24 22:47:18 -05003058 SSL3_VERSION,
3059 TLS1_VERSION,
3060 TLS1_1_VERSION,
3061 TLS1_2_VERSION,
3062// TLS 1.3 requires RSA-PSS, which is disabled for Android system builds.
3063#if !defined(BORINGSSL_ANDROID_SYSTEM)
3064 TLS1_3_VERSION,
3065#endif
David Benjamin0fef3052016-11-18 15:11:10 +09003066 };
3067
3068 static uint16_t kDTLSVersions[] = {
3069 DTLS1_VERSION, DTLS1_2_VERSION,
3070 };
3071
David Benjamin9ef31f02016-10-31 18:01:13 -04003072 for (uint16_t version : kTLSVersions) {
David Benjamin0fef3052016-11-18 15:11:10 +09003073 if (!test_func(false, TLS_method(), version)) {
3074 fprintf(stderr, "Test failed at TLS version %04x.\n", version);
David Benjamin9ef31f02016-10-31 18:01:13 -04003075 return false;
3076 }
David Benjamin0fef3052016-11-18 15:11:10 +09003077 }
David Benjamin9ef31f02016-10-31 18:01:13 -04003078
David Benjamin0fef3052016-11-18 15:11:10 +09003079 for (uint16_t version : kDTLSVersions) {
3080 if (!test_func(true, DTLS_method(), version)) {
3081 fprintf(stderr, "Test failed at DTLS version %04x.\n", version);
David Benjamin9ef31f02016-10-31 18:01:13 -04003082 return false;
3083 }
3084 }
3085
3086 return true;
3087}
3088
Adam Langleye1e78132017-01-31 15:24:31 -08003089TEST(SSLTest, AddChainCertHack) {
3090 // Ensure that we don't accidently break the hack that we have in place to
3091 // keep curl and serf happy when they use an |X509| even after transfering
3092 // ownership.
3093
3094 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3095 ASSERT_TRUE(ctx);
3096 X509 *cert = GetTestCertificate().release();
3097 ASSERT_TRUE(cert);
3098 SSL_CTX_add0_chain_cert(ctx.get(), cert);
3099
3100 // This should not trigger a use-after-free.
3101 X509_cmp(cert, cert);
3102}
3103
David Benjaminb2ff2622017-02-03 17:06:18 -05003104TEST(SSLTest, GetCertificate) {
3105 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3106 ASSERT_TRUE(ctx);
3107 bssl::UniquePtr<X509> cert = GetTestCertificate();
3108 ASSERT_TRUE(cert);
3109 ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
3110 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3111 ASSERT_TRUE(ssl);
3112
3113 X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
3114 ASSERT_TRUE(cert2);
3115 X509 *cert3 = SSL_get_certificate(ssl.get());
3116 ASSERT_TRUE(cert3);
3117
3118 // The old and new certificates must be identical.
3119 EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
3120 EXPECT_EQ(0, X509_cmp(cert.get(), cert3));
3121
3122 uint8_t *der = nullptr;
3123 long der_len = i2d_X509(cert.get(), &der);
3124 ASSERT_LT(0, der_len);
3125 bssl::UniquePtr<uint8_t> free_der(der);
3126
3127 uint8_t *der2 = nullptr;
3128 long der2_len = i2d_X509(cert2, &der2);
3129 ASSERT_LT(0, der2_len);
3130 bssl::UniquePtr<uint8_t> free_der2(der2);
3131
3132 uint8_t *der3 = nullptr;
3133 long der3_len = i2d_X509(cert3, &der3);
3134 ASSERT_LT(0, der3_len);
3135 bssl::UniquePtr<uint8_t> free_der3(der3);
3136
3137 // They must also encode identically.
David Benjamin7d7554b2017-02-04 11:48:59 -05003138 EXPECT_EQ(Bytes(der, der_len), Bytes(der2, der2_len));
3139 EXPECT_EQ(Bytes(der, der_len), Bytes(der3, der3_len));
David Benjaminb2ff2622017-02-03 17:06:18 -05003140}
3141
David Benjamin96628432017-01-19 19:05:47 -05003142// TODO(davidben): Convert this file to GTest properly.
3143TEST(SSLTest, AllTests) {
Adam Langley10f97f32016-07-12 08:09:33 -07003144 if (!TestCipherRules() ||
Alessandro Ghedini5fd18072016-09-28 21:04:25 +01003145 !TestCurveRules() ||
Adam Langley10f97f32016-07-12 08:09:33 -07003146 !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
3147 !TestSSL_SESSIONEncoding(kCustomSession) ||
3148 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
3149 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
3150 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
3151 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
David Benjamin10e664b2016-06-20 22:20:47 -04003152 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
Adam Langley10f97f32016-07-12 08:09:33 -07003153 !TestDefaultVersion(SSL3_VERSION, TLS1_2_VERSION, &TLS_method) ||
3154 !TestDefaultVersion(SSL3_VERSION, SSL3_VERSION, &SSLv3_method) ||
3155 !TestDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method) ||
3156 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method) ||
3157 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method) ||
3158 !TestDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method) ||
3159 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method) ||
3160 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method) ||
3161 !TestCipherGetRFCName() ||
Steven Valdeza833c352016-11-01 13:39:36 -04003162 // Test the padding extension at TLS 1.2.
3163 !TestPaddingExtension(TLS1_2_VERSION, TLS1_2_VERSION) ||
3164 // Test the padding extension at TLS 1.3 with a TLS 1.2 session, so there
3165 // will be no PSK binder after the padding extension.
3166 !TestPaddingExtension(TLS1_3_VERSION, TLS1_2_VERSION) ||
3167 // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
3168 // will be a PSK binder after the padding extension.
3169 !TestPaddingExtension(TLS1_3_VERSION, TLS1_3_DRAFT_VERSION) ||
Adam Langley10f97f32016-07-12 08:09:33 -07003170 !TestInternalSessionCache() ||
David Benjamin0fef3052016-11-18 15:11:10 +09003171 !ForEachVersion(TestSequenceNumber) ||
David Benjamin68f37b72016-11-18 15:14:42 +09003172 !ForEachVersion(TestOneSidedShutdown) ||
David Benjamin0fef3052016-11-18 15:11:10 +09003173 !ForEachVersion(TestGetPeerCertificate) ||
3174 !ForEachVersion(TestRetainOnlySHA256OfCerts) ||
David Benjamina20e5352016-08-02 19:09:41 -04003175 !TestClientHello() ||
David Benjamin0fef3052016-11-18 15:11:10 +09003176 !ForEachVersion(TestSessionIDContext) ||
3177 !ForEachVersion(TestSessionTimeout) ||
3178 !ForEachVersion(TestSNICallback) ||
David Benjamin0fef3052016-11-18 15:11:10 +09003179 !ForEachVersion(TestVersion) ||
David Benjaminb79cc842016-12-07 15:57:14 -05003180 !ForEachVersion(TestALPNCipherAvailable) ||
David Benjamin1444c3a2016-12-20 17:23:11 -05003181 !ForEachVersion(TestSSLClearSessionResumption) ||
David Benjamin48063c22017-01-01 23:56:36 -05003182 !ForEachVersion(TestAutoChain) ||
3183 !ForEachVersion(TestSSLWriteRetry)) {
David Benjamin96628432017-01-19 19:05:47 -05003184 ADD_FAILURE() << "Tests failed";
David Benjaminbb0a17c2014-09-20 15:35:39 -04003185 }
David Benjamin2e521212014-07-16 14:37:51 -04003186}