blob: 5c68f26a67608b29de9afea8790e55ac24f4fa24 [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 Benjamin751e8892014-10-19 00:59:36 -040024#include <openssl/base64.h>
25#include <openssl/bio.h>
David Benjamin7a1eefd2015-10-17 23:39:22 -040026#include <openssl/crypto.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040027#include <openssl/err.h>
David Benjaminde942382016-02-11 12:02:01 -050028#include <openssl/pem.h>
David Benjamin25490f22016-07-14 00:22:54 -040029#include <openssl/sha.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040030#include <openssl/ssl.h>
David Benjaminde942382016-02-11 12:02:01 -050031#include <openssl/x509.h>
David Benjaminbb0a17c2014-09-20 15:35:39 -040032
Steven Valdez87eab492016-06-27 16:34:59 -040033#include "internal.h"
Adam Langleyd2b5af52016-07-12 08:03:59 -070034#include "test/scoped_types.h"
Steven Valdezcb966542016-08-17 16:56:14 -040035#include "../crypto/internal.h"
Sigbjorn Vik2b23d242015-06-29 15:07:26 +020036#include "../crypto/test/test_util.h"
37
David Benjamin721e8b72016-08-03 13:13:17 -040038#if defined(OPENSSL_WINDOWS)
39/* Windows defines struct timeval in winsock2.h. */
40OPENSSL_MSVC_PRAGMA(warning(push, 3))
41#include <winsock2.h>
42OPENSSL_MSVC_PRAGMA(warning(pop))
43#else
44#include <sys/time.h>
45#endif
46
David Benjamin1d77e562015-03-22 17:22:08 -040047
48struct ExpectedCipher {
49 unsigned long id;
David Benjaminbb0a17c2014-09-20 15:35:39 -040050 int in_group_flag;
David Benjamin1d77e562015-03-22 17:22:08 -040051};
David Benjaminbb0a17c2014-09-20 15:35:39 -040052
David Benjamin1d77e562015-03-22 17:22:08 -040053struct CipherTest {
54 // The rule string to apply.
David Benjaminbb0a17c2014-09-20 15:35:39 -040055 const char *rule;
David Benjaminfb974e62015-12-16 19:34:22 -050056 // The list of expected ciphers, in order.
57 std::vector<ExpectedCipher> expected;
David Benjamin1d77e562015-03-22 17:22:08 -040058};
David Benjaminbb0a17c2014-09-20 15:35:39 -040059
David Benjaminfb974e62015-12-16 19:34:22 -050060static const CipherTest kCipherTests[] = {
61 // Selecting individual ciphers should work.
62 {
63 "ECDHE-ECDSA-CHACHA20-POLY1305:"
64 "ECDHE-RSA-CHACHA20-POLY1305:"
65 "ECDHE-ECDSA-AES128-GCM-SHA256:"
66 "ECDHE-RSA-AES128-GCM-SHA256",
67 {
68 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
69 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
70 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
71 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
72 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
73 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
74 },
75 },
76 // + reorders selected ciphers to the end, keeping their relative order.
77 {
78 "ECDHE-ECDSA-CHACHA20-POLY1305:"
79 "ECDHE-RSA-CHACHA20-POLY1305:"
80 "ECDHE-ECDSA-AES128-GCM-SHA256:"
81 "ECDHE-RSA-AES128-GCM-SHA256:"
82 "+aRSA",
83 {
84 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
85 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
86 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
87 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
88 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
89 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
90 },
91 },
92 // ! banishes ciphers from future selections.
93 {
94 "!aRSA:"
95 "ECDHE-ECDSA-CHACHA20-POLY1305:"
96 "ECDHE-RSA-CHACHA20-POLY1305:"
97 "ECDHE-ECDSA-AES128-GCM-SHA256:"
98 "ECDHE-RSA-AES128-GCM-SHA256",
99 {
100 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
101 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
102 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
103 },
104 },
105 // Multiple masks can be ANDed in a single rule.
106 {
107 "kRSA+AESGCM+AES128",
108 {
109 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
110 },
111 },
112 // - removes selected ciphers, but preserves their order for future
113 // selections. Select AES_128_GCM, but order the key exchanges RSA, DHE_RSA,
114 // ECDHE_RSA.
115 {
116 "ALL:-kECDHE:-kDHE:-kRSA:-ALL:"
117 "AESGCM+AES128+aRSA",
118 {
119 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
120 {TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, 0},
121 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
122 },
123 },
124 // Unknown selectors are no-ops.
125 {
126 "ECDHE-ECDSA-CHACHA20-POLY1305:"
127 "ECDHE-RSA-CHACHA20-POLY1305:"
128 "ECDHE-ECDSA-AES128-GCM-SHA256:"
129 "ECDHE-RSA-AES128-GCM-SHA256:"
130 "BOGUS1:-BOGUS2:+BOGUS3:!BOGUS4",
131 {
132 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
133 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
134 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
135 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
136 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
137 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
138 },
139 },
140 // Square brackets specify equi-preference groups.
141 {
142 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
143 "[ECDHE-RSA-CHACHA20-POLY1305]:"
144 "ECDHE-RSA-AES128-GCM-SHA256",
145 {
146 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
147 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 1},
148 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
149 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 1},
150 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
151 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
152 },
153 },
154 // @STRENGTH performs a stable strength-sort of the selected ciphers and
155 // only the selected ciphers.
156 {
157 // To simplify things, banish all but {ECDHE_RSA,RSA} x
158 // {CHACHA20,AES_256_CBC,AES_128_CBC,RC4} x SHA1.
159 "!kEDH:!AESGCM:!3DES:!SHA256:!MD5:!SHA384:"
160 // Order some ciphers backwards by strength.
161 "ALL:-CHACHA20:-AES256:-AES128:-RC4:-ALL:"
162 // Select ECDHE ones and sort them by strength. Ties should resolve
163 // based on the order above.
164 "kECDHE:@STRENGTH:-ALL:"
165 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
166 // by strength. Then RSA, backwards by strength.
167 "aRSA",
168 {
169 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
170 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
171 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
Matt Braithwaite9c8c4182016-08-24 14:36:54 -0700172#ifdef BORINGSSL_ENABLE_RC4_TLS
David Benjaminfb974e62015-12-16 19:34:22 -0500173 {TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA, 0},
Matt Braithwaite9c8c4182016-08-24 14:36:54 -0700174#endif
David Benjaminfb974e62015-12-16 19:34:22 -0500175 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
Matt Braithwaite9c8c4182016-08-24 14:36:54 -0700176#ifdef BORINGSSL_ENABLE_RC4_TLS
David Benjaminfb974e62015-12-16 19:34:22 -0500177 {SSL3_CK_RSA_RC4_128_SHA, 0},
Matt Braithwaite9c8c4182016-08-24 14:36:54 -0700178#endif
David Benjaminfb974e62015-12-16 19:34:22 -0500179 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
180 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
181 },
182 },
183 // Exact ciphers may not be used in multi-part rules; they are treated
184 // as unknown aliases.
185 {
186 "ECDHE-ECDSA-AES128-GCM-SHA256:"
187 "ECDHE-RSA-AES128-GCM-SHA256:"
188 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
189 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
190 {
191 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
192 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
193 },
194 },
195 // SSLv3 matches everything that existed before TLS 1.2.
196 {
197 "AES128-SHA:AES128-SHA256:!SSLv3",
198 {
199 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
200 },
201 },
202 // TLSv1.2 matches everything added in TLS 1.2.
203 {
204 "AES128-SHA:AES128-SHA256:!TLSv1.2",
205 {
206 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
207 },
208 },
209 // The two directives have no intersection.
210 {
211 "AES128-SHA:AES128-SHA256:!TLSv1.2+SSLv3",
212 {
213 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
214 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
215 },
216 },
217 // The shared name of the CHACHA20_POLY1305 variants behaves like a cipher
218 // name and not an alias. It may not be used in a multipart rule. (That the
219 // shared name works is covered by the standard tests.)
220 {
221 "ECDHE-ECDSA-CHACHA20-POLY1305:"
222 "ECDHE-RSA-CHACHA20-POLY1305:"
223 "!ECDHE-RSA-CHACHA20-POLY1305+RSA:"
224 "!ECDSA+ECDHE-ECDSA-CHACHA20-POLY1305",
225 {
226 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
227 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
228 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
229 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
230 },
231 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400232};
233
234static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400235 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400236 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
237 "RSA]",
238 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400239 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400240 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400241 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400242 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400243 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400244 "",
245 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400246 // COMPLEMENTOFDEFAULT is empty.
247 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400248 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400249 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400250 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400251 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
252 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
253 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
254 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400255};
256
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700257static const char *kMustNotIncludeNull[] = {
258 "ALL",
259 "DEFAULT",
260 "ALL:!eNULL",
261 "ALL:!NULL",
Matt Braithwaite9c8c4182016-08-24 14:36:54 -0700262#ifdef BORINGSSL_ENABLE_RC4_TLS
David Benjamind6e9eec2015-11-18 09:48:55 -0500263 "MEDIUM",
Matt Braithwaite9c8c4182016-08-24 14:36:54 -0700264#endif
David Benjamind6e9eec2015-11-18 09:48:55 -0500265 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700266 "FIPS",
267 "SHA",
268 "SHA1",
269 "RSA",
270 "SSLv3",
271 "TLSv1",
272 "TLSv1.2",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700273};
274
Matt Braithwaite053931e2016-05-25 12:06:05 -0700275static const char *kMustNotIncludeCECPQ1[] = {
276 "ALL",
277 "DEFAULT",
Matt Braithwaite9c8c4182016-08-24 14:36:54 -0700278#ifdef BORINGSSL_ENABLE_RC4_TLS
Matt Braithwaite053931e2016-05-25 12:06:05 -0700279 "MEDIUM",
Matt Braithwaite9c8c4182016-08-24 14:36:54 -0700280#endif
Matt Braithwaite053931e2016-05-25 12:06:05 -0700281 "HIGH",
282 "FIPS",
283 "SHA",
284 "SHA1",
285 "SHA256",
286 "SHA384",
287 "RSA",
288 "SSLv3",
289 "TLSv1",
290 "TLSv1.2",
291 "aRSA",
292 "RSA",
293 "aECDSA",
294 "ECDSA",
295 "AES",
296 "AES128",
297 "AES256",
298 "AESGCM",
299 "CHACHA20",
300};
301
David Benjamin1d77e562015-03-22 17:22:08 -0400302static void PrintCipherPreferenceList(ssl_cipher_preference_list_st *list) {
303 bool in_group = false;
304 for (size_t i = 0; i < sk_SSL_CIPHER_num(list->ciphers); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400305 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(list->ciphers, i);
306 if (!in_group && list->in_group_flags[i]) {
307 fprintf(stderr, "\t[\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400308 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400309 }
310 fprintf(stderr, "\t");
311 if (in_group) {
312 fprintf(stderr, " ");
313 }
314 fprintf(stderr, "%s\n", SSL_CIPHER_get_name(cipher));
315 if (in_group && !list->in_group_flags[i]) {
316 fprintf(stderr, "\t]\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400317 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400318 }
319 }
320}
321
David Benjaminfb974e62015-12-16 19:34:22 -0500322static bool TestCipherRule(const CipherTest &t) {
David Benjamin1d77e562015-03-22 17:22:08 -0400323 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
324 if (!ctx) {
325 return false;
David Benjamin65226252015-02-05 16:49:47 -0500326 }
327
David Benjaminfb974e62015-12-16 19:34:22 -0500328 if (!SSL_CTX_set_cipher_list(ctx.get(), t.rule)) {
329 fprintf(stderr, "Error testing cipher rule '%s'\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400330 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400331 }
332
David Benjamin1d77e562015-03-22 17:22:08 -0400333 // Compare the two lists.
David Benjaminfb974e62015-12-16 19:34:22 -0500334 if (sk_SSL_CIPHER_num(ctx->cipher_list->ciphers) != t.expected.size()) {
335 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
336 PrintCipherPreferenceList(ctx->cipher_list);
337 return false;
338 }
339
340 for (size_t i = 0; i < t.expected.size(); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400341 const SSL_CIPHER *cipher =
342 sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i);
David Benjaminfb974e62015-12-16 19:34:22 -0500343 if (t.expected[i].id != SSL_CIPHER_get_id(cipher) ||
344 t.expected[i].in_group_flag != ctx->cipher_list->in_group_flags[i]) {
345 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400346 PrintCipherPreferenceList(ctx->cipher_list);
347 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400348 }
349 }
350
David Benjamin1d77e562015-03-22 17:22:08 -0400351 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400352}
353
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700354static bool TestRuleDoesNotIncludeNull(const char *rule) {
355 ScopedSSL_CTX ctx(SSL_CTX_new(SSLv23_server_method()));
356 if (!ctx) {
357 return false;
358 }
359 if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
360 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
361 return false;
362 }
363 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
364 if (SSL_CIPHER_is_NULL(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
365 fprintf(stderr, "Error: cipher rule '%s' includes NULL\n",rule);
366 return false;
367 }
368 }
369 return true;
370}
371
Matt Braithwaite053931e2016-05-25 12:06:05 -0700372static bool TestRuleDoesNotIncludeCECPQ1(const char *rule) {
373 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
374 if (!ctx) {
375 return false;
376 }
377 if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
378 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
379 return false;
380 }
381 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
382 if (SSL_CIPHER_is_CECPQ1(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
383 fprintf(stderr, "Error: cipher rule '%s' includes CECPQ1\n",rule);
384 return false;
385 }
386 }
387 return true;
388}
389
David Benjamin1d77e562015-03-22 17:22:08 -0400390static bool TestCipherRules() {
David Benjaminfb974e62015-12-16 19:34:22 -0500391 for (const CipherTest &test : kCipherTests) {
392 if (!TestCipherRule(test)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400393 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400394 }
395 }
396
David Benjaminfb974e62015-12-16 19:34:22 -0500397 for (const char *rule : kBadRules) {
David Benjamin1d77e562015-03-22 17:22:08 -0400398 ScopedSSL_CTX ctx(SSL_CTX_new(SSLv23_server_method()));
399 if (!ctx) {
400 return false;
David Benjamin65226252015-02-05 16:49:47 -0500401 }
David Benjaminfb974e62015-12-16 19:34:22 -0500402 if (SSL_CTX_set_cipher_list(ctx.get(), rule)) {
403 fprintf(stderr, "Cipher rule '%s' unexpectedly succeeded\n", rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400404 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400405 }
406 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400407 }
408
David Benjaminfb974e62015-12-16 19:34:22 -0500409 for (const char *rule : kMustNotIncludeNull) {
410 if (!TestRuleDoesNotIncludeNull(rule)) {
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700411 return false;
412 }
413 }
414
Matt Braithwaite053931e2016-05-25 12:06:05 -0700415 for (const char *rule : kMustNotIncludeCECPQ1) {
416 if (!TestRuleDoesNotIncludeCECPQ1(rule)) {
417 return false;
418 }
419 }
420
David Benjamin1d77e562015-03-22 17:22:08 -0400421 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400422}
David Benjamin2e521212014-07-16 14:37:51 -0400423
Adam Langley10f97f32016-07-12 08:09:33 -0700424// kOpenSSLSession is a serialized SSL_SESSION generated from openssl
425// s_client -sess_out.
426static const char kOpenSSLSession[] =
427 "MIIFpQIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
428 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
429 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
430 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
431 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
432 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
433 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
434 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
435 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
436 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
437 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
438 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
439 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
440 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
441 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
442 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
443 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
444 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
445 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
446 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
447 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
448 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
449 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
450 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
451 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
452 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
453 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
454 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
455 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
456 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
457 "i4gv7Y5oliyn";
458
459// kCustomSession is a custom serialized SSL_SESSION generated by
460// filling in missing fields from |kOpenSSLSession|. This includes
461// providing |peer_sha256|, so |peer| is not serialized.
462static const char kCustomSession[] =
463 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
464 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
465 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
466 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
467 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
468 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
469 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
470 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
471
472// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
473static const char kBoringSSLSession[] =
474 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
475 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
476 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
477 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
478 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
479 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
480 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
481 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
482 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
483 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
484 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
485 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
486 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
487 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
488 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
489 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
490 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
491 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
492 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
493 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
494 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
495 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
496 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
497 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
498 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
499 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
500 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
501 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
502 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
503 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
504 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
505 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
506 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
507 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
508 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
509 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
510 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
511 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
512 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
513 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
514 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
515 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
516 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
517 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
518 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
519 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
520 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
521 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
522 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
523 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
524 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
525 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
526 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
527 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
528 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
529 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
530 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
531 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
532 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
533 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
534 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
535 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
536 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
537 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
538 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
539 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
540 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
541 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
542 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
543 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
544 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
545 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
546 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
547 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
548 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
549 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
550 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
551 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
552 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
553 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
554 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
555 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
556 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
557 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
558 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
559 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
560 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
561 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
562 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
563 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
564 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
565 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
566 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
567 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
568 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
569
570// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
571// the final (optional) element of |kCustomSession| with tag number 30.
572static const char kBadSessionExtraField[] =
573 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
574 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
575 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
576 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
577 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
578 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
579 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
580 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
581
582// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
583// the version of |kCustomSession| with 2.
584static const char kBadSessionVersion[] =
585 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
586 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
587 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
588 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
589 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
590 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
591 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
592 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
593
594// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
595// appended.
596static const char kBadSessionTrailingData[] =
597 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
598 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
599 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
600 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
601 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
602 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
603 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
604 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
605
David Benjamin1d77e562015-03-22 17:22:08 -0400606static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400607 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400608 if (!EVP_DecodedLength(&len, strlen(in))) {
609 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400610 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400611 }
612
David Benjamin1d77e562015-03-22 17:22:08 -0400613 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800614 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400615 strlen(in))) {
616 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400617 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400618 }
David Benjamin1d77e562015-03-22 17:22:08 -0400619 out->resize(len);
620 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400621}
622
David Benjamin1d77e562015-03-22 17:22:08 -0400623static bool TestSSL_SESSIONEncoding(const char *input_b64) {
David Benjamin751e8892014-10-19 00:59:36 -0400624 const uint8_t *cptr;
625 uint8_t *ptr;
David Benjamin751e8892014-10-19 00:59:36 -0400626
David Benjamin1d77e562015-03-22 17:22:08 -0400627 // Decode the input.
628 std::vector<uint8_t> input;
629 if (!DecodeBase64(&input, input_b64)) {
630 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400631 }
632
David Benjamin1d77e562015-03-22 17:22:08 -0400633 // Verify the SSL_SESSION decodes.
David Benjaminef14b2d2015-11-11 14:01:27 -0800634 ScopedSSL_SESSION session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminfd67aa82015-06-15 19:41:48 -0400635 if (!session) {
636 fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400637 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400638 }
639
David Benjamin1d77e562015-03-22 17:22:08 -0400640 // Verify the SSL_SESSION encoding round-trips.
641 size_t encoded_len;
Adam Langley10f97f32016-07-12 08:09:33 -0700642 ScopedOpenSSLBytes encoded;
David Benjamin1d77e562015-03-22 17:22:08 -0400643 uint8_t *encoded_raw;
644 if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
David Benjamin3cac4502014-10-21 01:46:30 -0400645 fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400646 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400647 }
David Benjamin1d77e562015-03-22 17:22:08 -0400648 encoded.reset(encoded_raw);
649 if (encoded_len != input.size() ||
David Benjaminef14b2d2015-11-11 14:01:27 -0800650 memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin3cac4502014-10-21 01:46:30 -0400651 fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
Sigbjorn Vik2b23d242015-06-29 15:07:26 +0200652 hexdump(stderr, "Before: ", input.data(), input.size());
653 hexdump(stderr, "After: ", encoded_raw, encoded_len);
David Benjamin1d77e562015-03-22 17:22:08 -0400654 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400655 }
David Benjamin3cac4502014-10-21 01:46:30 -0400656
David Benjaminfd67aa82015-06-15 19:41:48 -0400657 // Verify the SSL_SESSION also decodes with the legacy API.
David Benjaminef14b2d2015-11-11 14:01:27 -0800658 cptr = input.data();
David Benjaminfd67aa82015-06-15 19:41:48 -0400659 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
David Benjaminef14b2d2015-11-11 14:01:27 -0800660 if (!session || cptr != input.data() + input.size()) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400661 fprintf(stderr, "d2i_SSL_SESSION failed\n");
662 return false;
663 }
664
David Benjamin1d77e562015-03-22 17:22:08 -0400665 // Verify the SSL_SESSION encoding round-trips via the legacy API.
666 int len = i2d_SSL_SESSION(session.get(), NULL);
667 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400668 fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400669 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400670 }
671
David Benjamin1d77e562015-03-22 17:22:08 -0400672 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
673 if (!encoded) {
David Benjamin751e8892014-10-19 00:59:36 -0400674 fprintf(stderr, "malloc failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400675 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400676 }
David Benjamin1d77e562015-03-22 17:22:08 -0400677
678 ptr = encoded.get();
679 len = i2d_SSL_SESSION(session.get(), &ptr);
680 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400681 fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400682 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400683 }
David Benjamin1d77e562015-03-22 17:22:08 -0400684 if (ptr != encoded.get() + input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400685 fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400686 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400687 }
David Benjaminef14b2d2015-11-11 14:01:27 -0800688 if (memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin751e8892014-10-19 00:59:36 -0400689 fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400690 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400691 }
692
David Benjamin1d77e562015-03-22 17:22:08 -0400693 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400694}
695
David Benjaminf297e022015-05-28 19:55:29 -0400696static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
697 std::vector<uint8_t> input;
698 if (!DecodeBase64(&input, input_b64)) {
699 return false;
700 }
701
702 // Verify that the SSL_SESSION fails to decode.
David Benjaminef14b2d2015-11-11 14:01:27 -0800703 ScopedSSL_SESSION session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminf297e022015-05-28 19:55:29 -0400704 if (session) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400705 fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
David Benjaminf297e022015-05-28 19:55:29 -0400706 return false;
707 }
708 ERR_clear_error();
709 return true;
710}
711
David Benjamin10e664b2016-06-20 22:20:47 -0400712static bool TestDefaultVersion(uint16_t min_version, uint16_t max_version,
David Benjamin1d77e562015-03-22 17:22:08 -0400713 const SSL_METHOD *(*method)(void)) {
714 ScopedSSL_CTX ctx(SSL_CTX_new(method()));
715 if (!ctx) {
716 return false;
David Benjamin82c9e902014-12-12 15:55:27 -0500717 }
David Benjaminb6a0a512016-06-21 10:33:21 -0400718 if (ctx->min_version != min_version || ctx->max_version != max_version) {
719 fprintf(stderr, "Got min %04x, max %04x; wanted min %04x, max %04x\n",
720 ctx->min_version, ctx->max_version, min_version, max_version);
721 return false;
722 }
723 return true;
David Benjamin82c9e902014-12-12 15:55:27 -0500724}
725
David Benjamin1d77e562015-03-22 17:22:08 -0400726static bool CipherGetRFCName(std::string *out, uint16_t value) {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500727 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(value);
728 if (cipher == NULL) {
David Benjamin1d77e562015-03-22 17:22:08 -0400729 return false;
David Benjamin65226252015-02-05 16:49:47 -0500730 }
Adam Langley10f97f32016-07-12 08:09:33 -0700731 ScopedOpenSSLString rfc_name(SSL_CIPHER_get_rfc_name(cipher));
David Benjamin3fa65f02015-05-15 19:11:57 -0400732 if (!rfc_name) {
733 return false;
734 }
David Benjamin67be0482015-04-20 16:19:00 -0400735 out->assign(rfc_name.get());
David Benjamin1d77e562015-03-22 17:22:08 -0400736 return true;
David Benjamin65226252015-02-05 16:49:47 -0500737}
738
739typedef struct {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500740 int id;
David Benjamin65226252015-02-05 16:49:47 -0500741 const char *rfc_name;
742} CIPHER_RFC_NAME_TEST;
743
744static const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500745 { SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA" },
Matt Braithwaite9c8c4182016-08-24 14:36:54 -0700746#ifdef BORINGSSL_ENABLE_RC4_TLS
David Benjamin2bdb35c2015-02-21 11:03:06 -0500747 { SSL3_CK_RSA_RC4_128_MD5, "TLS_RSA_WITH_RC4_MD5" },
Matt Braithwaite9c8c4182016-08-24 14:36:54 -0700748#endif
David Benjamin2bdb35c2015-02-21 11:03:06 -0500749 { TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA" },
David Benjamin2bdb35c2015-02-21 11:03:06 -0500750 { TLS1_CK_DHE_RSA_WITH_AES_256_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA" },
751 { TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
752 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256" },
David Benjamin2bdb35c2015-02-21 11:03:06 -0500753 { TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
754 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" },
755 { TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
756 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384" },
757 { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
758 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" },
759 { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
760 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" },
761 { TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
762 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" },
Matt Braithwaite9c8c4182016-08-24 14:36:54 -0700763#ifdef BORINGSSL_ENABLE_RC4_TLS
David Benjamin2bdb35c2015-02-21 11:03:06 -0500764 { TLS1_CK_PSK_WITH_RC4_128_SHA, "TLS_PSK_WITH_RC4_SHA" },
Matt Braithwaite9c8c4182016-08-24 14:36:54 -0700765#endif
Adam Langley85bc5602015-06-09 09:54:04 -0700766 { TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
767 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA" },
David Benjamin13414b32015-12-09 23:02:39 -0500768 { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
769 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
David Benjamin1d77e562015-03-22 17:22:08 -0400770 // These names are non-standard:
Brian Smith271777f2015-10-03 13:53:33 -1000771 { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD,
David Benjamin2bdb35c2015-02-21 11:03:06 -0500772 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
Brian Smith271777f2015-10-03 13:53:33 -1000773 { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD,
David Benjamin2bdb35c2015-02-21 11:03:06 -0500774 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" },
David Benjamin65226252015-02-05 16:49:47 -0500775};
776
David Benjamin1d77e562015-03-22 17:22:08 -0400777static bool TestCipherGetRFCName(void) {
778 for (size_t i = 0;
Steven Valdezcb966542016-08-17 16:56:14 -0400779 i < OPENSSL_ARRAY_SIZE(kCipherRFCNameTests); i++) {
David Benjamin65226252015-02-05 16:49:47 -0500780 const CIPHER_RFC_NAME_TEST *test = &kCipherRFCNameTests[i];
David Benjamin1d77e562015-03-22 17:22:08 -0400781 std::string rfc_name;
782 if (!CipherGetRFCName(&rfc_name, test->id & 0xffff)) {
783 fprintf(stderr, "SSL_CIPHER_get_rfc_name failed\n");
784 return false;
David Benjamin65226252015-02-05 16:49:47 -0500785 }
David Benjamin1d77e562015-03-22 17:22:08 -0400786 if (rfc_name != test->rfc_name) {
David Benjamin65226252015-02-05 16:49:47 -0500787 fprintf(stderr, "SSL_CIPHER_get_rfc_name: got '%s', wanted '%s'\n",
David Benjamin1d77e562015-03-22 17:22:08 -0400788 rfc_name.c_str(), test->rfc_name);
789 return false;
David Benjamin65226252015-02-05 16:49:47 -0500790 }
David Benjamin65226252015-02-05 16:49:47 -0500791 }
David Benjamin1d77e562015-03-22 17:22:08 -0400792 return true;
David Benjamin65226252015-02-05 16:49:47 -0500793}
794
David Benjamin422fe082015-07-21 22:03:43 -0400795// CreateSessionWithTicket returns a sample |SSL_SESSION| with the ticket
796// replaced for one of length |ticket_len| or nullptr on failure.
797static ScopedSSL_SESSION CreateSessionWithTicket(size_t ticket_len) {
798 std::vector<uint8_t> der;
799 if (!DecodeBase64(&der, kOpenSSLSession)) {
800 return nullptr;
801 }
David Benjaminef14b2d2015-11-11 14:01:27 -0800802 ScopedSSL_SESSION session(SSL_SESSION_from_bytes(der.data(), der.size()));
David Benjamin422fe082015-07-21 22:03:43 -0400803 if (!session) {
804 return nullptr;
805 }
806
807 // Swap out the ticket for a garbage one.
808 OPENSSL_free(session->tlsext_tick);
809 session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len));
810 if (session->tlsext_tick == nullptr) {
811 return nullptr;
812 }
813 memset(session->tlsext_tick, 'a', ticket_len);
814 session->tlsext_ticklen = ticket_len;
David Benjamin1269ddd2015-10-18 15:18:55 -0400815
816 // Fix up the timeout.
817 session->time = time(NULL);
David Benjamin422fe082015-07-21 22:03:43 -0400818 return session;
819}
820
David Benjaminafc64de2016-07-19 17:12:41 +0200821static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
822 ScopedBIO bio(BIO_new(BIO_s_mem()));
823 if (!bio) {
824 return false;
825 }
826 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -0400827 BIO_up_ref(bio.get());
828 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +0200829 int ret = SSL_connect(ssl);
830 if (ret > 0) {
831 // SSL_connect should fail without a BIO to write to.
832 return false;
833 }
834 ERR_clear_error();
835
836 const uint8_t *client_hello;
837 size_t client_hello_len;
838 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
839 return false;
840 }
841 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
842 return true;
843}
844
David Benjamin422fe082015-07-21 22:03:43 -0400845// GetClientHelloLen creates a client SSL connection with a ticket of length
846// |ticket_len| and records the ClientHello. It returns the length of the
847// ClientHello, not including the record header, on success and zero on error.
848static size_t GetClientHelloLen(size_t ticket_len) {
849 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
850 ScopedSSL_SESSION session = CreateSessionWithTicket(ticket_len);
851 if (!ctx || !session) {
852 return 0;
853 }
854 ScopedSSL ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +0200855 if (!ssl || !SSL_set_session(ssl.get(), session.get())) {
David Benjamin422fe082015-07-21 22:03:43 -0400856 return 0;
857 }
David Benjaminafc64de2016-07-19 17:12:41 +0200858 std::vector<uint8_t> client_hello;
859 if (!GetClientHello(ssl.get(), &client_hello) ||
860 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -0400861 return 0;
862 }
David Benjaminafc64de2016-07-19 17:12:41 +0200863 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -0400864}
865
866struct PaddingTest {
867 size_t input_len, padded_len;
868};
869
870static const PaddingTest kPaddingTests[] = {
871 // ClientHellos of length below 0x100 do not require padding.
872 {0xfe, 0xfe},
873 {0xff, 0xff},
874 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
875 {0x100, 0x200},
876 {0x123, 0x200},
877 {0x1fb, 0x200},
878 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
879 // padding extension takes a minimum of four bytes plus one required content
880 // byte. (To work around yet more server bugs, we avoid empty final
881 // extensions.)
882 {0x1fc, 0x201},
883 {0x1fd, 0x202},
884 {0x1fe, 0x203},
885 {0x1ff, 0x204},
886 // Finally, larger ClientHellos need no padding.
887 {0x200, 0x200},
888 {0x201, 0x201},
889};
890
891static bool TestPaddingExtension() {
892 // Sample a baseline length.
893 size_t base_len = GetClientHelloLen(1);
894 if (base_len == 0) {
895 return false;
896 }
897
898 for (const PaddingTest &test : kPaddingTests) {
899 if (base_len > test.input_len) {
900 fprintf(stderr, "Baseline ClientHello too long.\n");
901 return false;
902 }
903
904 size_t padded_len = GetClientHelloLen(1 + test.input_len - base_len);
905 if (padded_len != test.padded_len) {
906 fprintf(stderr, "%u-byte ClientHello padded to %u bytes, not %u.\n",
907 static_cast<unsigned>(test.input_len),
908 static_cast<unsigned>(padded_len),
909 static_cast<unsigned>(test.padded_len));
910 return false;
911 }
912 }
913 return true;
914}
915
David Benjamin1d128f32015-09-08 17:41:40 -0400916// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
917// before configuring as a server.
918static bool TestClientCAList() {
919 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
920 if (!ctx) {
921 return false;
922 }
923 ScopedSSL ssl(SSL_new(ctx.get()));
924 if (!ssl) {
925 return false;
926 }
927
928 STACK_OF(X509_NAME) *stack = sk_X509_NAME_new_null();
929 if (stack == nullptr) {
930 return false;
931 }
932 // |SSL_set_client_CA_list| takes ownership.
933 SSL_set_client_CA_list(ssl.get(), stack);
934
935 return SSL_get_client_CA_list(ssl.get()) == stack;
936}
937
David Benjamin0f653952015-10-18 14:28:01 -0400938static void AppendSession(SSL_SESSION *session, void *arg) {
939 std::vector<SSL_SESSION*> *out =
940 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
941 out->push_back(session);
942}
943
944// ExpectCache returns true if |ctx|'s session cache consists of |expected|, in
945// order.
946static bool ExpectCache(SSL_CTX *ctx,
947 const std::vector<SSL_SESSION*> &expected) {
948 // Check the linked list.
949 SSL_SESSION *ptr = ctx->session_cache_head;
950 for (SSL_SESSION *session : expected) {
951 if (ptr != session) {
952 return false;
953 }
954 // TODO(davidben): This is an absurd way to denote the end of the list.
955 if (ptr->next ==
956 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
957 ptr = nullptr;
958 } else {
959 ptr = ptr->next;
960 }
961 }
962 if (ptr != nullptr) {
963 return false;
964 }
965
966 // Check the hash table.
967 std::vector<SSL_SESSION*> actual, expected_copy;
968 lh_SSL_SESSION_doall_arg(SSL_CTX_sessions(ctx), AppendSession, &actual);
969 expected_copy = expected;
970
971 std::sort(actual.begin(), actual.end());
972 std::sort(expected_copy.begin(), expected_copy.end());
973
974 return actual == expected_copy;
975}
976
977static ScopedSSL_SESSION CreateTestSession(uint32_t number) {
978 ScopedSSL_SESSION ret(SSL_SESSION_new());
979 if (!ret) {
980 return nullptr;
981 }
982
983 ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
984 memset(ret->session_id, 0, ret->session_id_length);
985 memcpy(ret->session_id, &number, sizeof(number));
986 return ret;
987}
988
David Benjamin0f653952015-10-18 14:28:01 -0400989// Test that the internal session cache behaves as expected.
990static bool TestInternalSessionCache() {
991 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
992 if (!ctx) {
993 return false;
994 }
995
996 // Prepare 10 test sessions.
David Benjamin4f6acaf2015-11-21 03:00:50 -0500997 std::vector<ScopedSSL_SESSION> sessions;
David Benjamin0f653952015-10-18 14:28:01 -0400998 for (int i = 0; i < 10; i++) {
999 ScopedSSL_SESSION session = CreateTestSession(i);
1000 if (!session) {
1001 return false;
1002 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001003 sessions.push_back(std::move(session));
David Benjamin0f653952015-10-18 14:28:01 -04001004 }
1005
1006 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1007
1008 // Insert all the test sessions.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001009 for (const auto &session : sessions) {
1010 if (!SSL_CTX_add_session(ctx.get(), session.get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001011 return false;
1012 }
1013 }
1014
1015 // Only the last five should be in the list.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001016 std::vector<SSL_SESSION*> expected = {
1017 sessions[9].get(),
1018 sessions[8].get(),
1019 sessions[7].get(),
1020 sessions[6].get(),
1021 sessions[5].get(),
1022 };
David Benjamin0f653952015-10-18 14:28:01 -04001023 if (!ExpectCache(ctx.get(), expected)) {
1024 return false;
1025 }
1026
1027 // Inserting an element already in the cache should fail.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001028 if (SSL_CTX_add_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001029 !ExpectCache(ctx.get(), expected)) {
1030 return false;
1031 }
1032
1033 // Although collisions should be impossible (256-bit session IDs), the cache
1034 // must handle them gracefully.
1035 ScopedSSL_SESSION collision(CreateTestSession(7));
1036 if (!collision || !SSL_CTX_add_session(ctx.get(), collision.get())) {
1037 return false;
1038 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001039 expected = {
1040 collision.get(),
1041 sessions[9].get(),
1042 sessions[8].get(),
1043 sessions[6].get(),
1044 sessions[5].get(),
1045 };
David Benjamin0f653952015-10-18 14:28:01 -04001046 if (!ExpectCache(ctx.get(), expected)) {
1047 return false;
1048 }
1049
1050 // Removing sessions behaves correctly.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001051 if (!SSL_CTX_remove_session(ctx.get(), sessions[6].get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001052 return false;
1053 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001054 expected = {
1055 collision.get(),
1056 sessions[9].get(),
1057 sessions[8].get(),
1058 sessions[5].get(),
1059 };
David Benjamin0f653952015-10-18 14:28:01 -04001060 if (!ExpectCache(ctx.get(), expected)) {
1061 return false;
1062 }
1063
1064 // Removing sessions requires an exact match.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001065 if (SSL_CTX_remove_session(ctx.get(), sessions[0].get()) ||
1066 SSL_CTX_remove_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001067 !ExpectCache(ctx.get(), expected)) {
1068 return false;
1069 }
1070
1071 return true;
1072}
1073
David Benjaminde942382016-02-11 12:02:01 -05001074static uint16_t EpochFromSequence(uint64_t seq) {
1075 return static_cast<uint16_t>(seq >> 48);
1076}
1077
1078static ScopedX509 GetTestCertificate() {
1079 static const char kCertPEM[] =
1080 "-----BEGIN CERTIFICATE-----\n"
1081 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1082 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1083 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1084 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1085 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1086 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1087 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1088 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1089 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1090 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1091 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1092 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1093 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1094 "-----END CERTIFICATE-----\n";
Steven Valdezd8eea142016-02-24 14:00:22 -05001095 ScopedBIO bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
David Benjaminde942382016-02-11 12:02:01 -05001096 return ScopedX509(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
1097}
1098
1099static ScopedEVP_PKEY GetTestKey() {
1100 static const char kKeyPEM[] =
1101 "-----BEGIN RSA PRIVATE KEY-----\n"
1102 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1103 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1104 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1105 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1106 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1107 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1108 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1109 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1110 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1111 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1112 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1113 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1114 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1115 "-----END RSA PRIVATE KEY-----\n";
Steven Valdezd8eea142016-02-24 14:00:22 -05001116 ScopedBIO bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
David Benjaminde942382016-02-11 12:02:01 -05001117 return ScopedEVP_PKEY(
1118 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1119}
1120
David Benjamin0fc37ef2016-08-17 15:29:46 -04001121static ScopedX509 GetECDSATestCertificate() {
1122 static const char kCertPEM[] =
1123 "-----BEGIN CERTIFICATE-----\n"
1124 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1125 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1126 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1127 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1128 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1129 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1130 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1131 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1132 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1133 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1134 "-----END CERTIFICATE-----\n";
1135 ScopedBIO bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1136 return ScopedX509(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
1137}
1138
1139static ScopedEVP_PKEY GetECDSATestKey() {
1140 static const char kKeyPEM[] =
1141 "-----BEGIN PRIVATE KEY-----\n"
1142 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1143 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1144 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1145 "-----END PRIVATE KEY-----\n";
1146 ScopedBIO bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1147 return ScopedEVP_PKEY(
1148 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1149}
1150
David Benjamin686bb192016-05-10 15:15:41 -04001151static bool ConnectClientAndServer(ScopedSSL *out_client, ScopedSSL *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001152 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1153 SSL_SESSION *session) {
David Benjamin686bb192016-05-10 15:15:41 -04001154 ScopedSSL client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001155 if (!client || !server) {
1156 return false;
1157 }
1158 SSL_set_connect_state(client.get());
1159 SSL_set_accept_state(server.get());
1160
David Benjamina20e5352016-08-02 19:09:41 -04001161 SSL_set_session(client.get(), session);
1162
David Benjaminde942382016-02-11 12:02:01 -05001163 BIO *bio1, *bio2;
1164 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1165 return false;
1166 }
1167 // SSL_set_bio takes ownership.
1168 SSL_set_bio(client.get(), bio1, bio1);
1169 SSL_set_bio(server.get(), bio2, bio2);
1170
1171 // Drive both their handshakes to completion.
1172 for (;;) {
1173 int client_ret = SSL_do_handshake(client.get());
1174 int client_err = SSL_get_error(client.get(), client_ret);
1175 if (client_err != SSL_ERROR_NONE &&
1176 client_err != SSL_ERROR_WANT_READ &&
1177 client_err != SSL_ERROR_WANT_WRITE) {
1178 fprintf(stderr, "Client error: %d\n", client_err);
1179 return false;
1180 }
1181
1182 int server_ret = SSL_do_handshake(server.get());
1183 int server_err = SSL_get_error(server.get(), server_ret);
1184 if (server_err != SSL_ERROR_NONE &&
1185 server_err != SSL_ERROR_WANT_READ &&
1186 server_err != SSL_ERROR_WANT_WRITE) {
1187 fprintf(stderr, "Server error: %d\n", server_err);
1188 return false;
1189 }
1190
1191 if (client_ret == 1 && server_ret == 1) {
1192 break;
1193 }
1194 }
1195
David Benjamin686bb192016-05-10 15:15:41 -04001196 *out_client = std::move(client);
1197 *out_server = std::move(server);
1198 return true;
1199}
1200
1201static bool TestSequenceNumber(bool dtls) {
1202 ScopedSSL_CTX client_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
1203 ScopedSSL_CTX server_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
1204 if (!client_ctx || !server_ctx) {
1205 return false;
1206 }
1207
1208 ScopedX509 cert = GetTestCertificate();
1209 ScopedEVP_PKEY key = GetTestKey();
1210 if (!cert || !key ||
1211 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1212 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1213 return false;
1214 }
1215
1216 ScopedSSL client, server;
1217 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001218 server_ctx.get(), nullptr /* no session */)) {
David Benjamin686bb192016-05-10 15:15:41 -04001219 return false;
1220 }
1221
David Benjaminde942382016-02-11 12:02:01 -05001222 uint64_t client_read_seq = SSL_get_read_sequence(client.get());
1223 uint64_t client_write_seq = SSL_get_write_sequence(client.get());
1224 uint64_t server_read_seq = SSL_get_read_sequence(server.get());
1225 uint64_t server_write_seq = SSL_get_write_sequence(server.get());
1226
1227 if (dtls) {
1228 // Both client and server must be at epoch 1.
1229 if (EpochFromSequence(client_read_seq) != 1 ||
1230 EpochFromSequence(client_write_seq) != 1 ||
1231 EpochFromSequence(server_read_seq) != 1 ||
1232 EpochFromSequence(server_write_seq) != 1) {
1233 fprintf(stderr, "Bad epochs.\n");
1234 return false;
1235 }
1236
1237 // The next record to be written should exceed the largest received.
1238 if (client_write_seq <= server_read_seq ||
1239 server_write_seq <= client_read_seq) {
1240 fprintf(stderr, "Inconsistent sequence numbers.\n");
1241 return false;
1242 }
1243 } else {
1244 // The next record to be written should equal the next to be received.
1245 if (client_write_seq != server_read_seq ||
1246 server_write_seq != client_write_seq) {
1247 fprintf(stderr, "Inconsistent sequence numbers.\n");
1248 return false;
1249 }
1250 }
1251
1252 // Send a record from client to server.
1253 uint8_t byte = 0;
1254 if (SSL_write(client.get(), &byte, 1) != 1 ||
1255 SSL_read(server.get(), &byte, 1) != 1) {
1256 fprintf(stderr, "Could not send byte.\n");
1257 return false;
1258 }
1259
1260 // The client write and server read sequence numbers should have incremented.
1261 if (client_write_seq + 1 != SSL_get_write_sequence(client.get()) ||
1262 server_read_seq + 1 != SSL_get_read_sequence(server.get())) {
1263 fprintf(stderr, "Sequence numbers did not increment.\n");\
1264 return false;
1265 }
1266
1267 return true;
1268}
1269
David Benjamin686bb192016-05-10 15:15:41 -04001270static bool TestOneSidedShutdown() {
1271 ScopedSSL_CTX client_ctx(SSL_CTX_new(TLS_method()));
1272 ScopedSSL_CTX server_ctx(SSL_CTX_new(TLS_method()));
1273 if (!client_ctx || !server_ctx) {
1274 return false;
1275 }
1276
1277 ScopedX509 cert = GetTestCertificate();
1278 ScopedEVP_PKEY key = GetTestKey();
1279 if (!cert || !key ||
1280 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1281 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1282 return false;
1283 }
1284
1285 ScopedSSL client, server;
1286 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001287 server_ctx.get(), nullptr /* no session */)) {
David Benjamin686bb192016-05-10 15:15:41 -04001288 return false;
1289 }
1290
1291 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1292 // one side has shut down.
1293 if (SSL_shutdown(client.get()) != 0) {
1294 fprintf(stderr, "Could not shutdown.\n");
1295 return false;
1296 }
1297
1298 // Reading from the server should consume the EOF.
1299 uint8_t byte;
1300 if (SSL_read(server.get(), &byte, 1) != 0 ||
1301 SSL_get_error(server.get(), 0) != SSL_ERROR_ZERO_RETURN) {
1302 fprintf(stderr, "Connection was not shut down cleanly.\n");
1303 return false;
1304 }
1305
1306 // However, the server may continue to write data and then shut down the
1307 // connection.
1308 byte = 42;
1309 if (SSL_write(server.get(), &byte, 1) != 1 ||
1310 SSL_read(client.get(), &byte, 1) != 1 ||
1311 byte != 42) {
1312 fprintf(stderr, "Could not send byte.\n");
1313 return false;
1314 }
1315
1316 // The server may then shutdown the connection.
1317 if (SSL_shutdown(server.get()) != 1 ||
1318 SSL_shutdown(client.get()) != 1) {
1319 fprintf(stderr, "Could not complete shutdown.\n");
1320 return false;
1321 }
1322
1323 return true;
1324}
Steven Valdez87eab492016-06-27 16:34:59 -04001325static bool TestSessionDuplication() {
1326 ScopedSSL_CTX client_ctx(SSL_CTX_new(TLS_method()));
1327 ScopedSSL_CTX server_ctx(SSL_CTX_new(TLS_method()));
1328 if (!client_ctx || !server_ctx) {
1329 return false;
1330 }
1331
1332 ScopedX509 cert = GetTestCertificate();
1333 ScopedEVP_PKEY key = GetTestKey();
1334 if (!cert || !key ||
1335 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1336 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1337 return false;
1338 }
1339
1340 ScopedSSL client, server;
1341 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001342 server_ctx.get(), nullptr /* no session */)) {
Steven Valdez87eab492016-06-27 16:34:59 -04001343 return false;
1344 }
1345
1346 SSL_SESSION *session0 = SSL_get_session(client.get());
Steven Valdez4aa154e2016-07-29 14:32:55 -04001347 ScopedSSL_SESSION session1(SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL));
Steven Valdez87eab492016-06-27 16:34:59 -04001348 if (!session1) {
David Benjamin4501bd52016-08-01 13:39:41 -04001349 return false;
Steven Valdez87eab492016-06-27 16:34:59 -04001350 }
David Benjamin4501bd52016-08-01 13:39:41 -04001351
Steven Valdez87eab492016-06-27 16:34:59 -04001352 uint8_t *s0_bytes, *s1_bytes;
1353 size_t s0_len, s1_len;
1354
1355 if (!SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len)) {
1356 return false;
1357 }
1358 ScopedOpenSSLBytes free_s0(s0_bytes);
1359
1360 if (!SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len)) {
1361 return false;
1362 }
1363 ScopedOpenSSLBytes free_s1(s1_bytes);
1364
1365 return s0_len == s1_len && memcmp(s0_bytes, s1_bytes, s0_len) == 0;
1366}
David Benjamin686bb192016-05-10 15:15:41 -04001367
David Benjamin5c0fb882016-06-14 14:03:51 -04001368static bool ExpectFDs(const SSL *ssl, int rfd, int wfd) {
1369 if (SSL_get_rfd(ssl) != rfd || SSL_get_wfd(ssl) != wfd) {
1370 fprintf(stderr, "Got fds %d and %d, wanted %d and %d.\n", SSL_get_rfd(ssl),
1371 SSL_get_wfd(ssl), rfd, wfd);
1372 return false;
1373 }
1374
1375 // The wrapper BIOs are always equal when fds are equal, even if set
1376 // individually.
1377 if (rfd == wfd && SSL_get_rbio(ssl) != SSL_get_wbio(ssl)) {
1378 fprintf(stderr, "rbio and wbio did not match.\n");
1379 return false;
1380 }
1381
1382 return true;
1383}
1384
1385static bool TestSetFD() {
1386 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
1387 if (!ctx) {
1388 return false;
1389 }
1390
1391 // Test setting different read and write FDs.
1392 ScopedSSL ssl(SSL_new(ctx.get()));
1393 if (!ssl ||
1394 !SSL_set_rfd(ssl.get(), 1) ||
1395 !SSL_set_wfd(ssl.get(), 2) ||
1396 !ExpectFDs(ssl.get(), 1, 2)) {
1397 return false;
1398 }
1399
1400 // Test setting the same FD.
1401 ssl.reset(SSL_new(ctx.get()));
1402 if (!ssl ||
1403 !SSL_set_fd(ssl.get(), 1) ||
1404 !ExpectFDs(ssl.get(), 1, 1)) {
1405 return false;
1406 }
1407
1408 // Test setting the same FD one side at a time.
1409 ssl.reset(SSL_new(ctx.get()));
1410 if (!ssl ||
1411 !SSL_set_rfd(ssl.get(), 1) ||
1412 !SSL_set_wfd(ssl.get(), 1) ||
1413 !ExpectFDs(ssl.get(), 1, 1)) {
1414 return false;
1415 }
1416
1417 // Test setting the same FD in the other order.
1418 ssl.reset(SSL_new(ctx.get()));
1419 if (!ssl ||
1420 !SSL_set_wfd(ssl.get(), 1) ||
1421 !SSL_set_rfd(ssl.get(), 1) ||
1422 !ExpectFDs(ssl.get(), 1, 1)) {
1423 return false;
1424 }
1425
David Benjamin5c0fb882016-06-14 14:03:51 -04001426 // Test changing the read FD partway through.
1427 ssl.reset(SSL_new(ctx.get()));
1428 if (!ssl ||
1429 !SSL_set_fd(ssl.get(), 1) ||
1430 !SSL_set_rfd(ssl.get(), 2) ||
1431 !ExpectFDs(ssl.get(), 2, 1)) {
1432 return false;
1433 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001434
1435 // Test changing the write FD partway through.
1436 ssl.reset(SSL_new(ctx.get()));
1437 if (!ssl ||
1438 !SSL_set_fd(ssl.get(), 1) ||
1439 !SSL_set_wfd(ssl.get(), 2) ||
1440 !ExpectFDs(ssl.get(), 1, 2)) {
1441 return false;
1442 }
1443
1444 // Test a no-op change to the read FD partway through.
1445 ssl.reset(SSL_new(ctx.get()));
1446 if (!ssl ||
1447 !SSL_set_fd(ssl.get(), 1) ||
1448 !SSL_set_rfd(ssl.get(), 1) ||
1449 !ExpectFDs(ssl.get(), 1, 1)) {
1450 return false;
1451 }
1452
1453 // Test a no-op change to the write FD partway through.
1454 ssl.reset(SSL_new(ctx.get()));
1455 if (!ssl ||
1456 !SSL_set_fd(ssl.get(), 1) ||
1457 !SSL_set_wfd(ssl.get(), 1) ||
1458 !ExpectFDs(ssl.get(), 1, 1)) {
1459 return false;
1460 }
1461
1462 // ASan builds will implicitly test that the internal |BIO| reference-counting
1463 // is correct.
1464
1465 return true;
1466}
1467
David Benjamin4501bd52016-08-01 13:39:41 -04001468static bool TestSetBIO() {
1469 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
1470 if (!ctx) {
1471 return false;
1472 }
1473
1474 ScopedSSL ssl(SSL_new(ctx.get()));
1475 ScopedBIO bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
1476 bio3(BIO_new(BIO_s_mem()));
1477 if (!ssl || !bio1 || !bio2 || !bio3) {
1478 return false;
1479 }
1480
1481 // SSL_set_bio takes one reference when the parameters are the same.
1482 BIO_up_ref(bio1.get());
1483 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1484
1485 // Repeating the call does nothing.
1486 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1487
1488 // It takes one reference each when the parameters are different.
1489 BIO_up_ref(bio2.get());
1490 BIO_up_ref(bio3.get());
1491 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1492
1493 // Repeating the call does nothing.
1494 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1495
1496 // It takes one reference when changing only wbio.
1497 BIO_up_ref(bio1.get());
1498 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1499
1500 // It takes one reference when changing only rbio and the two are different.
1501 BIO_up_ref(bio3.get());
1502 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1503
1504 // If setting wbio to rbio, it takes no additional references.
1505 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1506
1507 // From there, wbio may be switched to something else.
1508 BIO_up_ref(bio1.get());
1509 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1510
1511 // If setting rbio to wbio, it takes no additional references.
1512 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1513
1514 // From there, rbio may be switched to something else, but, for historical
1515 // reasons, it takes a reference to both parameters.
1516 BIO_up_ref(bio1.get());
1517 BIO_up_ref(bio2.get());
1518 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1519
1520 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1521 // is correct.
1522 return true;
1523}
1524
David Benjamin25490f22016-07-14 00:22:54 -04001525static uint16_t kVersions[] = {
1526 SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION, TLS1_2_VERSION, TLS1_3_VERSION,
1527};
1528
1529static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1530
David Benjaminadd5e522016-07-14 00:33:24 -04001531static bool TestGetPeerCertificate() {
1532 ScopedX509 cert = GetTestCertificate();
1533 ScopedEVP_PKEY key = GetTestKey();
1534 if (!cert || !key) {
1535 return false;
1536 }
1537
1538 for (uint16_t version : kVersions) {
1539 // Configure both client and server to accept any certificate.
1540 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
1541 if (!ctx ||
1542 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1543 !SSL_CTX_use_PrivateKey(ctx.get(), key.get())) {
1544 return false;
1545 }
1546 SSL_CTX_set_min_version(ctx.get(), version);
1547 SSL_CTX_set_max_version(ctx.get(), version);
1548 SSL_CTX_set_verify(
1549 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1550 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1551
1552 ScopedSSL client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001553 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1554 nullptr /* no session */)) {
David Benjaminadd5e522016-07-14 00:33:24 -04001555 return false;
1556 }
1557
1558 // Client and server should both see the leaf certificate.
1559 ScopedX509 peer(SSL_get_peer_certificate(server.get()));
1560 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1561 fprintf(stderr, "%x: Server peer certificate did not match.\n", version);
1562 return false;
1563 }
1564
1565 peer.reset(SSL_get_peer_certificate(client.get()));
1566 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1567 fprintf(stderr, "%x: Client peer certificate did not match.\n", version);
1568 return false;
1569 }
1570
1571 // However, for historical reasons, the chain includes the leaf on the
1572 // client, but does not on the server.
1573 if (sk_X509_num(SSL_get_peer_cert_chain(client.get())) != 1) {
1574 fprintf(stderr, "%x: Client peer chain was incorrect.\n", version);
1575 return false;
1576 }
1577
1578 if (sk_X509_num(SSL_get_peer_cert_chain(server.get())) != 0) {
1579 fprintf(stderr, "%x: Server peer chain was incorrect.\n", version);
1580 return false;
1581 }
1582 }
1583
1584 return true;
1585}
1586
David Benjamin25490f22016-07-14 00:22:54 -04001587static bool TestRetainOnlySHA256OfCerts() {
1588 ScopedX509 cert = GetTestCertificate();
1589 ScopedEVP_PKEY key = GetTestKey();
1590 if (!cert || !key) {
1591 return false;
1592 }
1593
1594 uint8_t *cert_der = NULL;
1595 int cert_der_len = i2d_X509(cert.get(), &cert_der);
1596 if (cert_der_len < 0) {
1597 return false;
1598 }
1599 ScopedOpenSSLBytes free_cert_der(cert_der);
1600
1601 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1602 SHA256(cert_der, cert_der_len, cert_sha256);
1603
1604 for (uint16_t version : kVersions) {
1605 // Configure both client and server to accept any certificate, but the
1606 // server must retain only the SHA-256 of the peer.
1607 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
1608 if (!ctx ||
1609 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1610 !SSL_CTX_use_PrivateKey(ctx.get(), key.get())) {
1611 return false;
1612 }
1613 SSL_CTX_set_min_version(ctx.get(), version);
1614 SSL_CTX_set_max_version(ctx.get(), version);
1615 SSL_CTX_set_verify(
1616 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1617 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1618 SSL_CTX_set_retain_only_sha256_of_client_certs(ctx.get(), 1);
1619
1620 ScopedSSL client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001621 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1622 nullptr /* no session */)) {
David Benjamin25490f22016-07-14 00:22:54 -04001623 return false;
1624 }
1625
1626 // The peer certificate has been dropped.
1627 ScopedX509 peer(SSL_get_peer_certificate(server.get()));
1628 if (peer) {
1629 fprintf(stderr, "%x: Peer certificate was retained.\n", version);
1630 return false;
1631 }
1632
1633 SSL_SESSION *session = SSL_get_session(server.get());
1634 if (!session->peer_sha256_valid) {
1635 fprintf(stderr, "%x: peer_sha256_valid was not set.\n", version);
1636 return false;
1637 }
1638
1639 if (memcmp(cert_sha256, session->peer_sha256, SHA256_DIGEST_LENGTH) != 0) {
1640 fprintf(stderr, "%x: peer_sha256 did not match.\n", version);
1641 return false;
1642 }
1643 }
1644
1645 return true;
1646}
1647
David Benjaminafc64de2016-07-19 17:12:41 +02001648static bool ClientHelloMatches(uint16_t version, const uint8_t *expected,
1649 size_t expected_len) {
1650 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
1651 if (!ctx) {
1652 return false;
1653 }
1654 SSL_CTX_set_max_version(ctx.get(), version);
1655 // Our default cipher list varies by CPU capabilities, so manually place the
1656 // ChaCha20 ciphers in front.
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001657 if (!SSL_CTX_set_cipher_list(ctx.get(), "!RC4:CHACHA20:ALL")) {
David Benjaminafc64de2016-07-19 17:12:41 +02001658 return false;
1659 }
1660 ScopedSSL ssl(SSL_new(ctx.get()));
1661 if (!ssl) {
1662 return false;
1663 }
1664 std::vector<uint8_t> client_hello;
1665 if (!GetClientHello(ssl.get(), &client_hello)) {
1666 return false;
1667 }
1668
1669 // Zero the client_random.
1670 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
1671 1 + 3 + // handshake message header
1672 2; // client_version
1673 if (client_hello.size() < kRandomOffset + SSL3_RANDOM_SIZE) {
1674 fprintf(stderr, "ClientHello for version %04x too short.\n", version);
1675 return false;
1676 }
1677 memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
1678
1679 if (client_hello.size() != expected_len ||
1680 memcmp(client_hello.data(), expected, expected_len) != 0) {
1681 fprintf(stderr, "ClientHello for version %04x did not match:\n", version);
1682 fprintf(stderr, "Got:\n\t");
1683 for (size_t i = 0; i < client_hello.size(); i++) {
1684 fprintf(stderr, "0x%02x, ", client_hello[i]);
1685 }
1686 fprintf(stderr, "\nWanted:\n\t");
1687 for (size_t i = 0; i < expected_len; i++) {
1688 fprintf(stderr, "0x%02x, ", expected[i]);
1689 }
1690 fprintf(stderr, "\n");
1691 return false;
1692 }
1693
1694 return true;
1695}
1696
1697// Tests that our ClientHellos do not change unexpectedly.
1698static bool TestClientHello() {
1699 static const uint8_t kSSL3ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001700 0x16,
1701 0x03, 0x00,
1702 0x00, 0x3f,
1703 0x01,
1704 0x00, 0x00, 0x3b,
1705 0x03, 0x00,
1706 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1707 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1708 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1709 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1710 0x00,
1711 0x00, 0x14,
1712 0xc0, 0x09,
1713 0xc0, 0x13,
1714 0x00, 0x33,
1715 0xc0, 0x0a,
1716 0xc0, 0x14,
1717 0x00, 0x39,
1718 0x00, 0x2f,
1719 0x00, 0x35,
1720 0x00, 0x0a,
1721 0x00, 0xff, 0x01, 0x00,
David Benjaminafc64de2016-07-19 17:12:41 +02001722 };
1723 if (!ClientHelloMatches(SSL3_VERSION, kSSL3ClientHello,
1724 sizeof(kSSL3ClientHello))) {
1725 return false;
1726 }
1727
1728 static const uint8_t kTLS1ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001729 0x16,
1730 0x03, 0x01,
1731 0x00, 0x5e,
1732 0x01,
1733 0x00, 0x00, 0x5a,
1734 0x03, 0x01,
1735 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1736 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1737 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1738 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1739 0x00,
1740 0x00, 0x12,
1741 0xc0, 0x09,
1742 0xc0, 0x13,
1743 0x00, 0x33,
1744 0xc0, 0x0a,
1745 0xc0, 0x14,
1746 0x00, 0x39,
1747 0x00, 0x2f,
1748 0x00, 0x35,
1749 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001750 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1751 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1752 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1753 };
1754 if (!ClientHelloMatches(TLS1_VERSION, kTLS1ClientHello,
1755 sizeof(kTLS1ClientHello))) {
1756 return false;
1757 }
1758
1759 static const uint8_t kTLS11ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001760 0x16,
1761 0x03, 0x01,
1762 0x00, 0x5e,
1763 0x01,
1764 0x00, 0x00, 0x5a,
1765 0x03, 0x02,
1766 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1767 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1768 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1769 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1770 0x00,
1771 0x00, 0x12,
1772 0xc0, 0x09,
1773 0xc0, 0x13,
1774 0x00, 0x33,
1775 0xc0, 0x0a,
1776 0xc0, 0x14,
1777 0x00, 0x39,
1778 0x00, 0x2f,
1779 0x00, 0x35,
1780 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001781 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1782 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1783 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1784 };
1785 if (!ClientHelloMatches(TLS1_1_VERSION, kTLS11ClientHello,
1786 sizeof(kTLS11ClientHello))) {
1787 return false;
1788 }
1789
1790 static const uint8_t kTLS12ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001791 0x16,
1792 0x03, 0x01,
1793 0x00, 0x9c,
1794 0x01,
1795 0x00, 0x00, 0x98,
1796 0x03, 0x03,
1797 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1798 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1799 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1800 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1801 0x00,
1802 0x00, 0x3a,
1803 0xcc, 0xa9,
1804 0xcc, 0xa8,
1805 0xcc, 0x14,
1806 0xcc, 0x13,
1807 0xc0, 0x2b,
1808 0xc0, 0x2f,
1809 0x00, 0x9e,
1810 0xc0, 0x2c,
1811 0xc0, 0x30,
1812 0x00, 0x9f,
1813 0xc0, 0x09,
1814 0xc0, 0x23,
1815 0xc0, 0x13,
1816 0xc0, 0x27,
1817 0x00, 0x33,
1818 0x00, 0x67,
1819 0xc0, 0x0a,
1820 0xc0, 0x24,
1821 0xc0, 0x14,
1822 0xc0, 0x28,
1823 0x00, 0x39,
1824 0x00, 0x6b,
1825 0x00, 0x9c,
1826 0x00, 0x9d,
1827 0x00, 0x2f,
1828 0x00, 0x3c,
1829 0x00, 0x35,
1830 0x00, 0x3d,
1831 0x00, 0x0a,
1832 0x01, 0x00, 0x00, 0x35, 0xff, 0x01, 0x00, 0x01,
David Benjaminafc64de2016-07-19 17:12:41 +02001833 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
1834 0x12, 0x00, 0x10, 0x06, 0x01, 0x06, 0x03, 0x05, 0x01, 0x05, 0x03, 0x04,
1835 0x01, 0x04, 0x03, 0x02, 0x01, 0x02, 0x03, 0x00, 0x0b, 0x00, 0x02, 0x01,
1836 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00,
1837 0x18,
1838 };
1839 if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
1840 sizeof(kTLS12ClientHello))) {
1841 return false;
1842 }
1843
1844 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
1845 // implementation has settled enough that it won't change.
1846
1847 return true;
1848}
1849
David Benjamina20e5352016-08-02 19:09:41 -04001850static ScopedSSL_SESSION g_last_session;
1851
1852static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
1853 // Save the most recent session.
1854 g_last_session.reset(session);
1855 return 1;
1856}
1857
1858static ScopedSSL_SESSION CreateClientSession(SSL_CTX *client_ctx,
1859 SSL_CTX *server_ctx) {
1860 g_last_session = nullptr;
1861 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
1862
1863 // Connect client and server to get a session.
1864 ScopedSSL client, server;
1865 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
1866 nullptr /* no session */)) {
1867 fprintf(stderr, "Failed to connect client and server.\n");
1868 return nullptr;
1869 }
1870
1871 // Run the read loop to account for post-handshake tickets in TLS 1.3.
1872 SSL_read(client.get(), nullptr, 0);
1873
1874 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
1875
1876 if (!g_last_session) {
1877 fprintf(stderr, "Client did not receive a session.\n");
1878 return nullptr;
1879 }
1880 return std::move(g_last_session);
1881}
1882
1883static bool ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1884 SSL_SESSION *session,
1885 bool reused) {
1886 ScopedSSL client, server;
1887 if (!ConnectClientAndServer(&client, &server, client_ctx,
1888 server_ctx, session)) {
1889 fprintf(stderr, "Failed to connect client and server.\n");
1890 return false;
1891 }
1892
1893 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
1894 fprintf(stderr, "Client and server were inconsistent.\n");
1895 return false;
1896 }
1897
1898 bool was_reused = !!SSL_session_reused(client.get());
1899 if (was_reused != reused) {
1900 fprintf(stderr, "Session was%s reused, but we expected the opposite.\n",
1901 was_reused ? "" : " not");
1902 return false;
1903 }
1904
1905 return true;
1906}
1907
1908static bool TestSessionIDContext() {
1909 ScopedX509 cert = GetTestCertificate();
1910 ScopedEVP_PKEY key = GetTestKey();
1911 if (!cert || !key) {
1912 return false;
1913 }
1914
1915 static const uint8_t kContext1[] = {1};
1916 static const uint8_t kContext2[] = {2};
1917
1918 for (uint16_t version : kVersions) {
David Benjamina20e5352016-08-02 19:09:41 -04001919 ScopedSSL_CTX server_ctx(SSL_CTX_new(TLS_method()));
1920 ScopedSSL_CTX client_ctx(SSL_CTX_new(TLS_method()));
1921 if (!server_ctx || !client_ctx ||
1922 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1923 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
1924 !SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
1925 sizeof(kContext1))) {
1926 return false;
1927 }
1928
1929 SSL_CTX_set_min_version(client_ctx.get(), version);
1930 SSL_CTX_set_max_version(client_ctx.get(), version);
1931 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
1932
1933 SSL_CTX_set_min_version(server_ctx.get(), version);
1934 SSL_CTX_set_max_version(server_ctx.get(), version);
1935 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
1936
1937 ScopedSSL_SESSION session =
1938 CreateClientSession(client_ctx.get(), server_ctx.get());
1939 if (!session) {
1940 fprintf(stderr, "Error getting session (version = %04x).\n", version);
1941 return false;
1942 }
1943
1944 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1945 true /* expect session reused */)) {
1946 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
1947 return false;
1948 }
1949
1950 // Change the session ID context.
1951 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext2,
1952 sizeof(kContext2))) {
1953 return false;
1954 }
1955
1956 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1957 false /* expect session not reused */)) {
1958 fprintf(stderr,
1959 "Error connection with different context (version = %04x).\n",
1960 version);
1961 return false;
1962 }
1963 }
1964
1965 return true;
1966}
1967
David Benjamin721e8b72016-08-03 13:13:17 -04001968static timeval g_current_time;
1969
1970static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
1971 *out_clock = g_current_time;
1972}
1973
1974static bool TestSessionTimeout() {
1975 ScopedX509 cert = GetTestCertificate();
1976 ScopedEVP_PKEY key = GetTestKey();
1977 if (!cert || !key) {
1978 return false;
1979 }
1980
1981 for (uint16_t version : kVersions) {
David Benjamin721e8b72016-08-03 13:13:17 -04001982 ScopedSSL_CTX server_ctx(SSL_CTX_new(TLS_method()));
1983 ScopedSSL_CTX client_ctx(SSL_CTX_new(TLS_method()));
1984 if (!server_ctx || !client_ctx ||
1985 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1986 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1987 return false;
1988 }
1989
1990 SSL_CTX_set_min_version(client_ctx.get(), version);
1991 SSL_CTX_set_max_version(client_ctx.get(), version);
1992 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
1993
1994 SSL_CTX_set_min_version(server_ctx.get(), version);
1995 SSL_CTX_set_max_version(server_ctx.get(), version);
1996 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
1997 SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
1998
1999 ScopedSSL_SESSION session =
2000 CreateClientSession(client_ctx.get(), server_ctx.get());
2001 if (!session) {
2002 fprintf(stderr, "Error getting session (version = %04x).\n", version);
2003 return false;
2004 }
2005
2006 // Advance the clock just behind the timeout.
2007 g_current_time.tv_sec += SSL_DEFAULT_SESSION_TIMEOUT;
2008
2009 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2010 true /* expect session reused */)) {
2011 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
2012 return false;
2013 }
2014
2015 // Advance the clock one more second.
2016 g_current_time.tv_sec++;
2017
2018 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2019 false /* expect session not reused */)) {
2020 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
2021 return false;
2022 }
2023 }
2024
2025 return true;
2026}
2027
David Benjamin0fc37ef2016-08-17 15:29:46 -04002028static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
2029 SSL_CTX *ctx = reinterpret_cast<SSL_CTX*>(arg);
2030 SSL_set_SSL_CTX(ssl, ctx);
2031 return SSL_TLSEXT_ERR_OK;
2032}
2033
2034static bool TestSNICallback() {
2035 ScopedX509 cert = GetTestCertificate();
2036 ScopedEVP_PKEY key = GetTestKey();
2037 ScopedX509 cert2 = GetECDSATestCertificate();
2038 ScopedEVP_PKEY key2 = GetECDSATestKey();
2039 if (!cert || !key || !cert2 || !key2) {
2040 return false;
2041 }
2042
2043 // At each version, test that switching the |SSL_CTX| at the SNI callback
2044 // behaves correctly.
2045 for (uint16_t version : kVersions) {
2046 if (version == SSL3_VERSION) {
2047 continue;
2048 }
2049
2050 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
2051
2052 ScopedSSL_CTX server_ctx(SSL_CTX_new(TLS_method()));
2053 ScopedSSL_CTX server_ctx2(SSL_CTX_new(TLS_method()));
2054 ScopedSSL_CTX client_ctx(SSL_CTX_new(TLS_method()));
2055 if (!server_ctx || !server_ctx2 || !client_ctx ||
2056 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2057 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2058 !SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()) ||
2059 !SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()) ||
2060 // Historically signing preferences would be lost in some cases with the
2061 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2062 // this doesn't happen when |version| is TLS 1.2, configure the private
2063 // key to only sign SHA-256.
2064 !SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
2065 &kECDSAWithSHA256, 1)) {
2066 return false;
2067 }
2068
2069 SSL_CTX_set_min_version(client_ctx.get(), version);
2070 SSL_CTX_set_max_version(client_ctx.get(), version);
2071 SSL_CTX_set_min_version(server_ctx.get(), version);
2072 SSL_CTX_set_max_version(server_ctx.get(), version);
2073 SSL_CTX_set_min_version(server_ctx2.get(), version);
2074 SSL_CTX_set_max_version(server_ctx2.get(), version);
2075
2076 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), SwitchContext);
2077 SSL_CTX_set_tlsext_servername_arg(server_ctx.get(), server_ctx2.get());
2078
2079 ScopedSSL client, server;
2080 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2081 server_ctx.get(), nullptr)) {
2082 fprintf(stderr, "Handshake failed at version %04x.\n", version);
2083 return false;
2084 }
2085
2086 // The client should have received |cert2|.
2087 ScopedX509 peer(SSL_get_peer_certificate(client.get()));
2088 if (!peer ||
2089 X509_cmp(peer.get(), cert2.get()) != 0) {
2090 fprintf(stderr, "Incorrect certificate received at version %04x.\n",
2091 version);
2092 return false;
2093 }
2094 }
2095
2096 return true;
2097}
2098
David Benjamin1d128f32015-09-08 17:41:40 -04002099int main() {
David Benjamin7a1eefd2015-10-17 23:39:22 -04002100 CRYPTO_library_init();
David Benjaminbb0a17c2014-09-20 15:35:39 -04002101
Adam Langley10f97f32016-07-12 08:09:33 -07002102 if (!TestCipherRules() ||
2103 !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
2104 !TestSSL_SESSIONEncoding(kCustomSession) ||
2105 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
2106 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
2107 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
2108 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
David Benjamin10e664b2016-06-20 22:20:47 -04002109 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
Adam Langley10f97f32016-07-12 08:09:33 -07002110 !TestDefaultVersion(SSL3_VERSION, TLS1_2_VERSION, &TLS_method) ||
2111 !TestDefaultVersion(SSL3_VERSION, SSL3_VERSION, &SSLv3_method) ||
2112 !TestDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method) ||
2113 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method) ||
2114 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method) ||
2115 !TestDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method) ||
2116 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method) ||
2117 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method) ||
2118 !TestCipherGetRFCName() ||
2119 !TestPaddingExtension() ||
2120 !TestClientCAList() ||
2121 !TestInternalSessionCache() ||
2122 !TestSequenceNumber(false /* TLS */) ||
2123 !TestSequenceNumber(true /* DTLS */) ||
2124 !TestOneSidedShutdown() ||
Steven Valdez87eab492016-06-27 16:34:59 -04002125 !TestSessionDuplication() ||
David Benjamin25490f22016-07-14 00:22:54 -04002126 !TestSetFD() ||
David Benjamin4501bd52016-08-01 13:39:41 -04002127 !TestSetBIO() ||
David Benjaminadd5e522016-07-14 00:33:24 -04002128 !TestGetPeerCertificate() ||
David Benjaminafc64de2016-07-19 17:12:41 +02002129 !TestRetainOnlySHA256OfCerts() ||
David Benjamina20e5352016-08-02 19:09:41 -04002130 !TestClientHello() ||
David Benjamin721e8b72016-08-03 13:13:17 -04002131 !TestSessionIDContext() ||
David Benjamin0fc37ef2016-08-17 15:29:46 -04002132 !TestSessionTimeout() ||
2133 !TestSNICallback()) {
Brian Smith83a82982015-04-09 16:21:10 -10002134 ERR_print_errors_fp(stderr);
David Benjaminbb0a17c2014-09-20 15:35:39 -04002135 return 1;
2136 }
2137
David Benjamin2e521212014-07-16 14:37:51 -04002138 printf("PASS\n");
2139 return 0;
2140}