blob: 564f0c5ffa4fd4f520abf0653059804abeb8e218 [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"
Steven Valdezcb966542016-08-17 16:56:14 -040034#include "../crypto/internal.h"
Sigbjorn Vik2b23d242015-06-29 15:07:26 +020035#include "../crypto/test/test_util.h"
36
David Benjamin721e8b72016-08-03 13:13:17 -040037#if defined(OPENSSL_WINDOWS)
38/* Windows defines struct timeval in winsock2.h. */
39OPENSSL_MSVC_PRAGMA(warning(push, 3))
40#include <winsock2.h>
41OPENSSL_MSVC_PRAGMA(warning(pop))
42#else
43#include <sys/time.h>
44#endif
45
David Benjamin1d77e562015-03-22 17:22:08 -040046
47struct ExpectedCipher {
48 unsigned long id;
David Benjaminbb0a17c2014-09-20 15:35:39 -040049 int in_group_flag;
David Benjamin1d77e562015-03-22 17:22:08 -040050};
David Benjaminbb0a17c2014-09-20 15:35:39 -040051
David Benjamin1d77e562015-03-22 17:22:08 -040052struct CipherTest {
53 // The rule string to apply.
David Benjaminbb0a17c2014-09-20 15:35:39 -040054 const char *rule;
David Benjaminfb974e62015-12-16 19:34:22 -050055 // The list of expected ciphers, in order.
56 std::vector<ExpectedCipher> expected;
David Benjamin1d77e562015-03-22 17:22:08 -040057};
David Benjaminbb0a17c2014-09-20 15:35:39 -040058
David Benjaminfb974e62015-12-16 19:34:22 -050059static const CipherTest kCipherTests[] = {
60 // Selecting individual ciphers should work.
61 {
62 "ECDHE-ECDSA-CHACHA20-POLY1305:"
63 "ECDHE-RSA-CHACHA20-POLY1305:"
64 "ECDHE-ECDSA-AES128-GCM-SHA256:"
65 "ECDHE-RSA-AES128-GCM-SHA256",
66 {
67 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
68 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
69 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
70 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
71 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
72 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
73 },
74 },
75 // + reorders selected ciphers to the end, keeping their relative order.
76 {
77 "ECDHE-ECDSA-CHACHA20-POLY1305:"
78 "ECDHE-RSA-CHACHA20-POLY1305:"
79 "ECDHE-ECDSA-AES128-GCM-SHA256:"
80 "ECDHE-RSA-AES128-GCM-SHA256:"
81 "+aRSA",
82 {
83 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
84 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
85 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
86 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
87 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
88 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
89 },
90 },
91 // ! banishes ciphers from future selections.
92 {
93 "!aRSA:"
94 "ECDHE-ECDSA-CHACHA20-POLY1305:"
95 "ECDHE-RSA-CHACHA20-POLY1305:"
96 "ECDHE-ECDSA-AES128-GCM-SHA256:"
97 "ECDHE-RSA-AES128-GCM-SHA256",
98 {
99 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
100 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
101 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
102 },
103 },
104 // Multiple masks can be ANDed in a single rule.
105 {
106 "kRSA+AESGCM+AES128",
107 {
108 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
109 },
110 },
111 // - removes selected ciphers, but preserves their order for future
112 // selections. Select AES_128_GCM, but order the key exchanges RSA, DHE_RSA,
113 // ECDHE_RSA.
114 {
115 "ALL:-kECDHE:-kDHE:-kRSA:-ALL:"
116 "AESGCM+AES128+aRSA",
117 {
118 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
119 {TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, 0},
120 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
121 },
122 },
123 // Unknown selectors are no-ops.
124 {
125 "ECDHE-ECDSA-CHACHA20-POLY1305:"
126 "ECDHE-RSA-CHACHA20-POLY1305:"
127 "ECDHE-ECDSA-AES128-GCM-SHA256:"
128 "ECDHE-RSA-AES128-GCM-SHA256:"
129 "BOGUS1:-BOGUS2:+BOGUS3:!BOGUS4",
130 {
131 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
132 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
133 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
134 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
135 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
136 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
137 },
138 },
139 // Square brackets specify equi-preference groups.
140 {
141 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
142 "[ECDHE-RSA-CHACHA20-POLY1305]:"
143 "ECDHE-RSA-AES128-GCM-SHA256",
144 {
145 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
146 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 1},
147 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
148 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 1},
149 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
150 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
151 },
152 },
153 // @STRENGTH performs a stable strength-sort of the selected ciphers and
154 // only the selected ciphers.
155 {
156 // To simplify things, banish all but {ECDHE_RSA,RSA} x
157 // {CHACHA20,AES_256_CBC,AES_128_CBC,RC4} x SHA1.
158 "!kEDH:!AESGCM:!3DES:!SHA256:!MD5:!SHA384:"
159 // Order some ciphers backwards by strength.
160 "ALL:-CHACHA20:-AES256:-AES128:-RC4:-ALL:"
161 // Select ECDHE ones and sort them by strength. Ties should resolve
162 // based on the order above.
163 "kECDHE:@STRENGTH:-ALL:"
164 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
165 // by strength. Then RSA, backwards by strength.
166 "aRSA",
167 {
168 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
169 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
170 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
Matt Braithwaite9c8c4182016-08-24 14:36:54 -0700171#ifdef BORINGSSL_ENABLE_RC4_TLS
David Benjaminfb974e62015-12-16 19:34:22 -0500172 {TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA, 0},
Matt Braithwaite9c8c4182016-08-24 14:36:54 -0700173#endif
David Benjaminfb974e62015-12-16 19:34:22 -0500174 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
Matt Braithwaite9c8c4182016-08-24 14:36:54 -0700175#ifdef BORINGSSL_ENABLE_RC4_TLS
David Benjaminfb974e62015-12-16 19:34:22 -0500176 {SSL3_CK_RSA_RC4_128_SHA, 0},
Matt Braithwaite9c8c4182016-08-24 14:36:54 -0700177#endif
David Benjaminfb974e62015-12-16 19:34:22 -0500178 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
179 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
180 },
181 },
182 // Exact ciphers may not be used in multi-part rules; they are treated
183 // as unknown aliases.
184 {
185 "ECDHE-ECDSA-AES128-GCM-SHA256:"
186 "ECDHE-RSA-AES128-GCM-SHA256:"
187 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
188 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
189 {
190 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
191 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
192 },
193 },
194 // SSLv3 matches everything that existed before TLS 1.2.
195 {
196 "AES128-SHA:AES128-SHA256:!SSLv3",
197 {
198 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
199 },
200 },
201 // TLSv1.2 matches everything added in TLS 1.2.
202 {
203 "AES128-SHA:AES128-SHA256:!TLSv1.2",
204 {
205 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
206 },
207 },
208 // The two directives have no intersection.
209 {
210 "AES128-SHA:AES128-SHA256:!TLSv1.2+SSLv3",
211 {
212 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
213 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
214 },
215 },
216 // The shared name of the CHACHA20_POLY1305 variants behaves like a cipher
217 // name and not an alias. It may not be used in a multipart rule. (That the
218 // shared name works is covered by the standard tests.)
219 {
220 "ECDHE-ECDSA-CHACHA20-POLY1305:"
221 "ECDHE-RSA-CHACHA20-POLY1305:"
222 "!ECDHE-RSA-CHACHA20-POLY1305+RSA:"
223 "!ECDSA+ECDHE-ECDSA-CHACHA20-POLY1305",
224 {
225 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
226 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
227 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
228 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
229 },
230 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400231};
232
233static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400234 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400235 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
236 "RSA]",
237 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400238 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400239 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400240 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400241 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400242 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400243 "",
244 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400245 // COMPLEMENTOFDEFAULT is empty.
246 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400247 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400248 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400249 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400250 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
251 "[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]:@STRENGTH",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400254};
255
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700256static const char *kMustNotIncludeNull[] = {
257 "ALL",
258 "DEFAULT",
259 "ALL:!eNULL",
260 "ALL:!NULL",
Matt Braithwaite9c8c4182016-08-24 14:36:54 -0700261#ifdef BORINGSSL_ENABLE_RC4_TLS
David Benjamind6e9eec2015-11-18 09:48:55 -0500262 "MEDIUM",
Matt Braithwaite9c8c4182016-08-24 14:36:54 -0700263#endif
David Benjamind6e9eec2015-11-18 09:48:55 -0500264 "HIGH",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700265 "FIPS",
266 "SHA",
267 "SHA1",
268 "RSA",
269 "SSLv3",
270 "TLSv1",
271 "TLSv1.2",
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700272};
273
Matt Braithwaite053931e2016-05-25 12:06:05 -0700274static const char *kMustNotIncludeCECPQ1[] = {
275 "ALL",
276 "DEFAULT",
Matt Braithwaite9c8c4182016-08-24 14:36:54 -0700277#ifdef BORINGSSL_ENABLE_RC4_TLS
Matt Braithwaite053931e2016-05-25 12:06:05 -0700278 "MEDIUM",
Matt Braithwaite9c8c4182016-08-24 14:36:54 -0700279#endif
Matt Braithwaite053931e2016-05-25 12:06:05 -0700280 "HIGH",
281 "FIPS",
282 "SHA",
283 "SHA1",
284 "SHA256",
285 "SHA384",
286 "RSA",
287 "SSLv3",
288 "TLSv1",
289 "TLSv1.2",
290 "aRSA",
291 "RSA",
292 "aECDSA",
293 "ECDSA",
294 "AES",
295 "AES128",
296 "AES256",
297 "AESGCM",
298 "CHACHA20",
299};
300
David Benjamin1d77e562015-03-22 17:22:08 -0400301static void PrintCipherPreferenceList(ssl_cipher_preference_list_st *list) {
302 bool in_group = false;
303 for (size_t i = 0; i < sk_SSL_CIPHER_num(list->ciphers); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400304 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(list->ciphers, i);
305 if (!in_group && list->in_group_flags[i]) {
306 fprintf(stderr, "\t[\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400307 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400308 }
309 fprintf(stderr, "\t");
310 if (in_group) {
311 fprintf(stderr, " ");
312 }
313 fprintf(stderr, "%s\n", SSL_CIPHER_get_name(cipher));
314 if (in_group && !list->in_group_flags[i]) {
315 fprintf(stderr, "\t]\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400316 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400317 }
318 }
319}
320
David Benjaminfb974e62015-12-16 19:34:22 -0500321static bool TestCipherRule(const CipherTest &t) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700322 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400323 if (!ctx) {
324 return false;
David Benjamin65226252015-02-05 16:49:47 -0500325 }
326
David Benjaminfb974e62015-12-16 19:34:22 -0500327 if (!SSL_CTX_set_cipher_list(ctx.get(), t.rule)) {
328 fprintf(stderr, "Error testing cipher rule '%s'\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400329 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400330 }
331
David Benjamin1d77e562015-03-22 17:22:08 -0400332 // Compare the two lists.
David Benjaminfb974e62015-12-16 19:34:22 -0500333 if (sk_SSL_CIPHER_num(ctx->cipher_list->ciphers) != t.expected.size()) {
334 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
335 PrintCipherPreferenceList(ctx->cipher_list);
336 return false;
337 }
338
339 for (size_t i = 0; i < t.expected.size(); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400340 const SSL_CIPHER *cipher =
341 sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i);
David Benjaminfb974e62015-12-16 19:34:22 -0500342 if (t.expected[i].id != SSL_CIPHER_get_id(cipher) ||
343 t.expected[i].in_group_flag != ctx->cipher_list->in_group_flags[i]) {
344 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400345 PrintCipherPreferenceList(ctx->cipher_list);
346 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400347 }
348 }
349
David Benjamin1d77e562015-03-22 17:22:08 -0400350 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400351}
352
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700353static bool TestRuleDoesNotIncludeNull(const char *rule) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700354 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700355 if (!ctx) {
356 return false;
357 }
358 if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
359 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
360 return false;
361 }
362 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
363 if (SSL_CIPHER_is_NULL(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
364 fprintf(stderr, "Error: cipher rule '%s' includes NULL\n",rule);
365 return false;
366 }
367 }
368 return true;
369}
370
Matt Braithwaite053931e2016-05-25 12:06:05 -0700371static bool TestRuleDoesNotIncludeCECPQ1(const char *rule) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700372 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Matt Braithwaite053931e2016-05-25 12:06:05 -0700373 if (!ctx) {
374 return false;
375 }
376 if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
377 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
378 return false;
379 }
380 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
381 if (SSL_CIPHER_is_CECPQ1(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
382 fprintf(stderr, "Error: cipher rule '%s' includes CECPQ1\n",rule);
383 return false;
384 }
385 }
386 return true;
387}
388
David Benjamin1d77e562015-03-22 17:22:08 -0400389static bool TestCipherRules() {
David Benjaminfb974e62015-12-16 19:34:22 -0500390 for (const CipherTest &test : kCipherTests) {
391 if (!TestCipherRule(test)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400392 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400393 }
394 }
395
David Benjaminfb974e62015-12-16 19:34:22 -0500396 for (const char *rule : kBadRules) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700397 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400398 if (!ctx) {
399 return false;
David Benjamin65226252015-02-05 16:49:47 -0500400 }
David Benjaminfb974e62015-12-16 19:34:22 -0500401 if (SSL_CTX_set_cipher_list(ctx.get(), rule)) {
402 fprintf(stderr, "Cipher rule '%s' unexpectedly succeeded\n", rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400403 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400404 }
405 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400406 }
407
David Benjaminfb974e62015-12-16 19:34:22 -0500408 for (const char *rule : kMustNotIncludeNull) {
409 if (!TestRuleDoesNotIncludeNull(rule)) {
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700410 return false;
411 }
412 }
413
Matt Braithwaite053931e2016-05-25 12:06:05 -0700414 for (const char *rule : kMustNotIncludeCECPQ1) {
415 if (!TestRuleDoesNotIncludeCECPQ1(rule)) {
416 return false;
417 }
418 }
419
David Benjamin1d77e562015-03-22 17:22:08 -0400420 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400421}
David Benjamin2e521212014-07-16 14:37:51 -0400422
Adam Langley10f97f32016-07-12 08:09:33 -0700423// kOpenSSLSession is a serialized SSL_SESSION generated from openssl
424// s_client -sess_out.
425static const char kOpenSSLSession[] =
426 "MIIFpQIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
427 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
428 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
429 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
430 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
431 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
432 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
433 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
434 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
435 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
436 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
437 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
438 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
439 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
440 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
441 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
442 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
443 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
444 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
445 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
446 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
447 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
448 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
449 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
450 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
451 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
452 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
453 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
454 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
455 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
456 "i4gv7Y5oliyn";
457
458// kCustomSession is a custom serialized SSL_SESSION generated by
459// filling in missing fields from |kOpenSSLSession|. This includes
460// providing |peer_sha256|, so |peer| is not serialized.
461static const char kCustomSession[] =
462 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
463 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
464 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
465 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
466 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
467 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
468 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
469 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
470
471// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
472static const char kBoringSSLSession[] =
473 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
474 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
475 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
476 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
477 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
478 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
479 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
480 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
481 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
482 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
483 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
484 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
485 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
486 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
487 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
488 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
489 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
490 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
491 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
492 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
493 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
494 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
495 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
496 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
497 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
498 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
499 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
500 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
501 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
502 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
503 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
504 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
505 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
506 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
507 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
508 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
509 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
510 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
511 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
512 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
513 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
514 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
515 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
516 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
517 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
518 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
519 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
520 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
521 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
522 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
523 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
524 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
525 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
526 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
527 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
528 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
529 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
530 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
531 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
532 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
533 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
534 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
535 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
536 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
537 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
538 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
539 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
540 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
541 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
542 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
543 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
544 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
545 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
546 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
547 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
548 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
549 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
550 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
551 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
552 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
553 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
554 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
555 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
556 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
557 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
558 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
559 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
560 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
561 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
562 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
563 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
564 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
565 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
566 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
567 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
568
569// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
570// the final (optional) element of |kCustomSession| with tag number 30.
571static const char kBadSessionExtraField[] =
572 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
573 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
574 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
575 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
576 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
577 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
578 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
579 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
580
581// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
582// the version of |kCustomSession| with 2.
583static const char kBadSessionVersion[] =
584 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
585 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
586 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
587 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
588 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
589 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
590 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
591 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
592
593// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
594// appended.
595static const char kBadSessionTrailingData[] =
596 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
597 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
598 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
599 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
600 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
601 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
602 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
603 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
604
David Benjamin1d77e562015-03-22 17:22:08 -0400605static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400606 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400607 if (!EVP_DecodedLength(&len, strlen(in))) {
608 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400609 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400610 }
611
David Benjamin1d77e562015-03-22 17:22:08 -0400612 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800613 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400614 strlen(in))) {
615 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400616 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400617 }
David Benjamin1d77e562015-03-22 17:22:08 -0400618 out->resize(len);
619 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400620}
621
David Benjamin1d77e562015-03-22 17:22:08 -0400622static bool TestSSL_SESSIONEncoding(const char *input_b64) {
David Benjamin751e8892014-10-19 00:59:36 -0400623 const uint8_t *cptr;
624 uint8_t *ptr;
David Benjamin751e8892014-10-19 00:59:36 -0400625
David Benjamin1d77e562015-03-22 17:22:08 -0400626 // Decode the input.
627 std::vector<uint8_t> input;
628 if (!DecodeBase64(&input, input_b64)) {
629 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400630 }
631
David Benjamin1d77e562015-03-22 17:22:08 -0400632 // Verify the SSL_SESSION decodes.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700633 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminfd67aa82015-06-15 19:41:48 -0400634 if (!session) {
635 fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400636 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400637 }
638
David Benjamin1d77e562015-03-22 17:22:08 -0400639 // Verify the SSL_SESSION encoding round-trips.
640 size_t encoded_len;
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700641 bssl::UniquePtr<uint8_t> encoded;
David Benjamin1d77e562015-03-22 17:22:08 -0400642 uint8_t *encoded_raw;
643 if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
David Benjamin3cac4502014-10-21 01:46:30 -0400644 fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400645 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400646 }
David Benjamin1d77e562015-03-22 17:22:08 -0400647 encoded.reset(encoded_raw);
648 if (encoded_len != input.size() ||
David Benjaminef14b2d2015-11-11 14:01:27 -0800649 memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin3cac4502014-10-21 01:46:30 -0400650 fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
Sigbjorn Vik2b23d242015-06-29 15:07:26 +0200651 hexdump(stderr, "Before: ", input.data(), input.size());
652 hexdump(stderr, "After: ", encoded_raw, encoded_len);
David Benjamin1d77e562015-03-22 17:22:08 -0400653 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400654 }
David Benjamin3cac4502014-10-21 01:46:30 -0400655
David Benjaminfd67aa82015-06-15 19:41:48 -0400656 // Verify the SSL_SESSION also decodes with the legacy API.
David Benjaminef14b2d2015-11-11 14:01:27 -0800657 cptr = input.data();
David Benjaminfd67aa82015-06-15 19:41:48 -0400658 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
David Benjaminef14b2d2015-11-11 14:01:27 -0800659 if (!session || cptr != input.data() + input.size()) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400660 fprintf(stderr, "d2i_SSL_SESSION failed\n");
661 return false;
662 }
663
David Benjamin1d77e562015-03-22 17:22:08 -0400664 // Verify the SSL_SESSION encoding round-trips via the legacy API.
665 int len = i2d_SSL_SESSION(session.get(), NULL);
666 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400667 fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400668 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400669 }
670
David Benjamin1d77e562015-03-22 17:22:08 -0400671 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
672 if (!encoded) {
David Benjamin751e8892014-10-19 00:59:36 -0400673 fprintf(stderr, "malloc failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400674 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400675 }
David Benjamin1d77e562015-03-22 17:22:08 -0400676
677 ptr = encoded.get();
678 len = i2d_SSL_SESSION(session.get(), &ptr);
679 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400680 fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400681 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400682 }
David Benjamin1d77e562015-03-22 17:22:08 -0400683 if (ptr != encoded.get() + input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400684 fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400685 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400686 }
David Benjaminef14b2d2015-11-11 14:01:27 -0800687 if (memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin751e8892014-10-19 00:59:36 -0400688 fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400689 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400690 }
691
David Benjamin1d77e562015-03-22 17:22:08 -0400692 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400693}
694
David Benjaminf297e022015-05-28 19:55:29 -0400695static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
696 std::vector<uint8_t> input;
697 if (!DecodeBase64(&input, input_b64)) {
698 return false;
699 }
700
701 // Verify that the SSL_SESSION fails to decode.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700702 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminf297e022015-05-28 19:55:29 -0400703 if (session) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400704 fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
David Benjaminf297e022015-05-28 19:55:29 -0400705 return false;
706 }
707 ERR_clear_error();
708 return true;
709}
710
David Benjamin10e664b2016-06-20 22:20:47 -0400711static bool TestDefaultVersion(uint16_t min_version, uint16_t max_version,
David Benjamin1d77e562015-03-22 17:22:08 -0400712 const SSL_METHOD *(*method)(void)) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700713 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400714 if (!ctx) {
715 return false;
David Benjamin82c9e902014-12-12 15:55:27 -0500716 }
David Benjaminb6a0a512016-06-21 10:33:21 -0400717 if (ctx->min_version != min_version || ctx->max_version != max_version) {
718 fprintf(stderr, "Got min %04x, max %04x; wanted min %04x, max %04x\n",
719 ctx->min_version, ctx->max_version, min_version, max_version);
720 return false;
721 }
722 return true;
David Benjamin82c9e902014-12-12 15:55:27 -0500723}
724
David Benjamin1d77e562015-03-22 17:22:08 -0400725static bool CipherGetRFCName(std::string *out, uint16_t value) {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500726 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(value);
727 if (cipher == NULL) {
David Benjamin1d77e562015-03-22 17:22:08 -0400728 return false;
David Benjamin65226252015-02-05 16:49:47 -0500729 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700730 bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
David Benjamin3fa65f02015-05-15 19:11:57 -0400731 if (!rfc_name) {
732 return false;
733 }
David Benjamin67be0482015-04-20 16:19:00 -0400734 out->assign(rfc_name.get());
David Benjamin1d77e562015-03-22 17:22:08 -0400735 return true;
David Benjamin65226252015-02-05 16:49:47 -0500736}
737
738typedef struct {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500739 int id;
David Benjamin65226252015-02-05 16:49:47 -0500740 const char *rfc_name;
741} CIPHER_RFC_NAME_TEST;
742
743static const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500744 { SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA" },
Matt Braithwaite9c8c4182016-08-24 14:36:54 -0700745#ifdef BORINGSSL_ENABLE_RC4_TLS
David Benjamin2bdb35c2015-02-21 11:03:06 -0500746 { SSL3_CK_RSA_RC4_128_MD5, "TLS_RSA_WITH_RC4_MD5" },
Matt Braithwaite9c8c4182016-08-24 14:36:54 -0700747#endif
David Benjamin2bdb35c2015-02-21 11:03:06 -0500748 { TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA" },
David Benjamin2bdb35c2015-02-21 11:03:06 -0500749 { TLS1_CK_DHE_RSA_WITH_AES_256_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA" },
750 { TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
751 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256" },
David Benjamin2bdb35c2015-02-21 11:03:06 -0500752 { TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
753 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" },
754 { TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
755 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384" },
756 { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
757 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" },
758 { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
759 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" },
760 { TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
761 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" },
Matt Braithwaite9c8c4182016-08-24 14:36:54 -0700762#ifdef BORINGSSL_ENABLE_RC4_TLS
David Benjamin2bdb35c2015-02-21 11:03:06 -0500763 { TLS1_CK_PSK_WITH_RC4_128_SHA, "TLS_PSK_WITH_RC4_SHA" },
Matt Braithwaite9c8c4182016-08-24 14:36:54 -0700764#endif
Adam Langley85bc5602015-06-09 09:54:04 -0700765 { TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
766 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA" },
David Benjamin13414b32015-12-09 23:02:39 -0500767 { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
768 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
David Benjamin1d77e562015-03-22 17:22:08 -0400769 // These names are non-standard:
Brian Smith271777f2015-10-03 13:53:33 -1000770 { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD,
David Benjamin2bdb35c2015-02-21 11:03:06 -0500771 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
Brian Smith271777f2015-10-03 13:53:33 -1000772 { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD,
David Benjamin2bdb35c2015-02-21 11:03:06 -0500773 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" },
David Benjamin65226252015-02-05 16:49:47 -0500774};
775
David Benjamin1d77e562015-03-22 17:22:08 -0400776static bool TestCipherGetRFCName(void) {
777 for (size_t i = 0;
Steven Valdezcb966542016-08-17 16:56:14 -0400778 i < OPENSSL_ARRAY_SIZE(kCipherRFCNameTests); i++) {
David Benjamin65226252015-02-05 16:49:47 -0500779 const CIPHER_RFC_NAME_TEST *test = &kCipherRFCNameTests[i];
David Benjamin1d77e562015-03-22 17:22:08 -0400780 std::string rfc_name;
781 if (!CipherGetRFCName(&rfc_name, test->id & 0xffff)) {
782 fprintf(stderr, "SSL_CIPHER_get_rfc_name failed\n");
783 return false;
David Benjamin65226252015-02-05 16:49:47 -0500784 }
David Benjamin1d77e562015-03-22 17:22:08 -0400785 if (rfc_name != test->rfc_name) {
David Benjamin65226252015-02-05 16:49:47 -0500786 fprintf(stderr, "SSL_CIPHER_get_rfc_name: got '%s', wanted '%s'\n",
David Benjamin1d77e562015-03-22 17:22:08 -0400787 rfc_name.c_str(), test->rfc_name);
788 return false;
David Benjamin65226252015-02-05 16:49:47 -0500789 }
David Benjamin65226252015-02-05 16:49:47 -0500790 }
David Benjamin1d77e562015-03-22 17:22:08 -0400791 return true;
David Benjamin65226252015-02-05 16:49:47 -0500792}
793
David Benjamin422fe082015-07-21 22:03:43 -0400794// CreateSessionWithTicket returns a sample |SSL_SESSION| with the ticket
795// replaced for one of length |ticket_len| or nullptr on failure.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700796static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -0400797 std::vector<uint8_t> der;
798 if (!DecodeBase64(&der, kOpenSSLSession)) {
799 return nullptr;
800 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700801 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(der.data(), der.size()));
David Benjamin422fe082015-07-21 22:03:43 -0400802 if (!session) {
803 return nullptr;
804 }
805
806 // Swap out the ticket for a garbage one.
807 OPENSSL_free(session->tlsext_tick);
808 session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len));
809 if (session->tlsext_tick == nullptr) {
810 return nullptr;
811 }
812 memset(session->tlsext_tick, 'a', ticket_len);
813 session->tlsext_ticklen = ticket_len;
David Benjamin1269ddd2015-10-18 15:18:55 -0400814
815 // Fix up the timeout.
816 session->time = time(NULL);
David Benjamin422fe082015-07-21 22:03:43 -0400817 return session;
818}
819
David Benjaminafc64de2016-07-19 17:12:41 +0200820static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700821 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +0200822 if (!bio) {
823 return false;
824 }
825 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -0400826 BIO_up_ref(bio.get());
827 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +0200828 int ret = SSL_connect(ssl);
829 if (ret > 0) {
830 // SSL_connect should fail without a BIO to write to.
831 return false;
832 }
833 ERR_clear_error();
834
835 const uint8_t *client_hello;
836 size_t client_hello_len;
837 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
838 return false;
839 }
840 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
841 return true;
842}
843
David Benjamin422fe082015-07-21 22:03:43 -0400844// GetClientHelloLen creates a client SSL connection with a ticket of length
845// |ticket_len| and records the ClientHello. It returns the length of the
846// ClientHello, not including the record header, on success and zero on error.
847static size_t GetClientHelloLen(size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700848 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
849 bssl::UniquePtr<SSL_SESSION> session = CreateSessionWithTicket(ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -0400850 if (!ctx || !session) {
851 return 0;
852 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700853 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +0200854 if (!ssl || !SSL_set_session(ssl.get(), session.get())) {
David Benjamin422fe082015-07-21 22:03:43 -0400855 return 0;
856 }
David Benjaminafc64de2016-07-19 17:12:41 +0200857 std::vector<uint8_t> client_hello;
858 if (!GetClientHello(ssl.get(), &client_hello) ||
859 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -0400860 return 0;
861 }
David Benjaminafc64de2016-07-19 17:12:41 +0200862 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -0400863}
864
865struct PaddingTest {
866 size_t input_len, padded_len;
867};
868
869static const PaddingTest kPaddingTests[] = {
870 // ClientHellos of length below 0x100 do not require padding.
871 {0xfe, 0xfe},
872 {0xff, 0xff},
873 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
874 {0x100, 0x200},
875 {0x123, 0x200},
876 {0x1fb, 0x200},
877 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
878 // padding extension takes a minimum of four bytes plus one required content
879 // byte. (To work around yet more server bugs, we avoid empty final
880 // extensions.)
881 {0x1fc, 0x201},
882 {0x1fd, 0x202},
883 {0x1fe, 0x203},
884 {0x1ff, 0x204},
885 // Finally, larger ClientHellos need no padding.
886 {0x200, 0x200},
887 {0x201, 0x201},
888};
889
890static bool TestPaddingExtension() {
891 // Sample a baseline length.
892 size_t base_len = GetClientHelloLen(1);
893 if (base_len == 0) {
894 return false;
895 }
896
897 for (const PaddingTest &test : kPaddingTests) {
898 if (base_len > test.input_len) {
899 fprintf(stderr, "Baseline ClientHello too long.\n");
900 return false;
901 }
902
903 size_t padded_len = GetClientHelloLen(1 + test.input_len - base_len);
904 if (padded_len != test.padded_len) {
905 fprintf(stderr, "%u-byte ClientHello padded to %u bytes, not %u.\n",
906 static_cast<unsigned>(test.input_len),
907 static_cast<unsigned>(padded_len),
908 static_cast<unsigned>(test.padded_len));
909 return false;
910 }
911 }
912 return true;
913}
914
David Benjamin1d128f32015-09-08 17:41:40 -0400915// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
916// before configuring as a server.
917static bool TestClientCAList() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700918 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin1d128f32015-09-08 17:41:40 -0400919 if (!ctx) {
920 return false;
921 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700922 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjamin1d128f32015-09-08 17:41:40 -0400923 if (!ssl) {
924 return false;
925 }
926
927 STACK_OF(X509_NAME) *stack = sk_X509_NAME_new_null();
928 if (stack == nullptr) {
929 return false;
930 }
931 // |SSL_set_client_CA_list| takes ownership.
932 SSL_set_client_CA_list(ssl.get(), stack);
933
934 return SSL_get_client_CA_list(ssl.get()) == stack;
935}
936
David Benjamin0f653952015-10-18 14:28:01 -0400937static void AppendSession(SSL_SESSION *session, void *arg) {
938 std::vector<SSL_SESSION*> *out =
939 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
940 out->push_back(session);
941}
942
943// ExpectCache returns true if |ctx|'s session cache consists of |expected|, in
944// order.
945static bool ExpectCache(SSL_CTX *ctx,
946 const std::vector<SSL_SESSION*> &expected) {
947 // Check the linked list.
948 SSL_SESSION *ptr = ctx->session_cache_head;
949 for (SSL_SESSION *session : expected) {
950 if (ptr != session) {
951 return false;
952 }
953 // TODO(davidben): This is an absurd way to denote the end of the list.
954 if (ptr->next ==
955 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
956 ptr = nullptr;
957 } else {
958 ptr = ptr->next;
959 }
960 }
961 if (ptr != nullptr) {
962 return false;
963 }
964
965 // Check the hash table.
966 std::vector<SSL_SESSION*> actual, expected_copy;
967 lh_SSL_SESSION_doall_arg(SSL_CTX_sessions(ctx), AppendSession, &actual);
968 expected_copy = expected;
969
970 std::sort(actual.begin(), actual.end());
971 std::sort(expected_copy.begin(), expected_copy.end());
972
973 return actual == expected_copy;
974}
975
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700976static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
977 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new());
David Benjamin0f653952015-10-18 14:28:01 -0400978 if (!ret) {
979 return nullptr;
980 }
981
982 ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
983 memset(ret->session_id, 0, ret->session_id_length);
984 memcpy(ret->session_id, &number, sizeof(number));
985 return ret;
986}
987
David Benjamin0f653952015-10-18 14:28:01 -0400988// Test that the internal session cache behaves as expected.
989static bool TestInternalSessionCache() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700990 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin0f653952015-10-18 14:28:01 -0400991 if (!ctx) {
992 return false;
993 }
994
995 // Prepare 10 test sessions.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700996 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
David Benjamin0f653952015-10-18 14:28:01 -0400997 for (int i = 0; i < 10; i++) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700998 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
David Benjamin0f653952015-10-18 14:28:01 -0400999 if (!session) {
1000 return false;
1001 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001002 sessions.push_back(std::move(session));
David Benjamin0f653952015-10-18 14:28:01 -04001003 }
1004
1005 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1006
1007 // Insert all the test sessions.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001008 for (const auto &session : sessions) {
1009 if (!SSL_CTX_add_session(ctx.get(), session.get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001010 return false;
1011 }
1012 }
1013
1014 // Only the last five should be in the list.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001015 std::vector<SSL_SESSION*> expected = {
1016 sessions[9].get(),
1017 sessions[8].get(),
1018 sessions[7].get(),
1019 sessions[6].get(),
1020 sessions[5].get(),
1021 };
David Benjamin0f653952015-10-18 14:28:01 -04001022 if (!ExpectCache(ctx.get(), expected)) {
1023 return false;
1024 }
1025
1026 // Inserting an element already in the cache should fail.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001027 if (SSL_CTX_add_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001028 !ExpectCache(ctx.get(), expected)) {
1029 return false;
1030 }
1031
1032 // Although collisions should be impossible (256-bit session IDs), the cache
1033 // must handle them gracefully.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001034 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
David Benjamin0f653952015-10-18 14:28:01 -04001035 if (!collision || !SSL_CTX_add_session(ctx.get(), collision.get())) {
1036 return false;
1037 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001038 expected = {
1039 collision.get(),
1040 sessions[9].get(),
1041 sessions[8].get(),
1042 sessions[6].get(),
1043 sessions[5].get(),
1044 };
David Benjamin0f653952015-10-18 14:28:01 -04001045 if (!ExpectCache(ctx.get(), expected)) {
1046 return false;
1047 }
1048
1049 // Removing sessions behaves correctly.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001050 if (!SSL_CTX_remove_session(ctx.get(), sessions[6].get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001051 return false;
1052 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001053 expected = {
1054 collision.get(),
1055 sessions[9].get(),
1056 sessions[8].get(),
1057 sessions[5].get(),
1058 };
David Benjamin0f653952015-10-18 14:28:01 -04001059 if (!ExpectCache(ctx.get(), expected)) {
1060 return false;
1061 }
1062
1063 // Removing sessions requires an exact match.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001064 if (SSL_CTX_remove_session(ctx.get(), sessions[0].get()) ||
1065 SSL_CTX_remove_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001066 !ExpectCache(ctx.get(), expected)) {
1067 return false;
1068 }
1069
1070 return true;
1071}
1072
David Benjaminde942382016-02-11 12:02:01 -05001073static uint16_t EpochFromSequence(uint64_t seq) {
1074 return static_cast<uint16_t>(seq >> 48);
1075}
1076
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001077static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001078 static const char kCertPEM[] =
1079 "-----BEGIN CERTIFICATE-----\n"
1080 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1081 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1082 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1083 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1084 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1085 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1086 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1087 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1088 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1089 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1090 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1091 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1092 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1093 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001094 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1095 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjaminde942382016-02-11 12:02:01 -05001096}
1097
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001098static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001099 static const char kKeyPEM[] =
1100 "-----BEGIN RSA PRIVATE KEY-----\n"
1101 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1102 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1103 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1104 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1105 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1106 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1107 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1108 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1109 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1110 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1111 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1112 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1113 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1114 "-----END RSA PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001115 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1116 return bssl::UniquePtr<EVP_PKEY>(
David Benjaminde942382016-02-11 12:02:01 -05001117 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1118}
1119
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001120static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001121 static const char kCertPEM[] =
1122 "-----BEGIN CERTIFICATE-----\n"
1123 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1124 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1125 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1126 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1127 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1128 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1129 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1130 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1131 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1132 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1133 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001134 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1135 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjamin0fc37ef2016-08-17 15:29:46 -04001136}
1137
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001138static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001139 static const char kKeyPEM[] =
1140 "-----BEGIN PRIVATE KEY-----\n"
1141 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1142 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1143 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1144 "-----END PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001145 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1146 return bssl::UniquePtr<EVP_PKEY>(
David Benjamin0fc37ef2016-08-17 15:29:46 -04001147 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1148}
1149
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001150static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001151 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1152 SSL_SESSION *session) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001153 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001154 if (!client || !server) {
1155 return false;
1156 }
1157 SSL_set_connect_state(client.get());
1158 SSL_set_accept_state(server.get());
1159
David Benjamina20e5352016-08-02 19:09:41 -04001160 SSL_set_session(client.get(), session);
1161
David Benjaminde942382016-02-11 12:02:01 -05001162 BIO *bio1, *bio2;
1163 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1164 return false;
1165 }
1166 // SSL_set_bio takes ownership.
1167 SSL_set_bio(client.get(), bio1, bio1);
1168 SSL_set_bio(server.get(), bio2, bio2);
1169
1170 // Drive both their handshakes to completion.
1171 for (;;) {
1172 int client_ret = SSL_do_handshake(client.get());
1173 int client_err = SSL_get_error(client.get(), client_ret);
1174 if (client_err != SSL_ERROR_NONE &&
1175 client_err != SSL_ERROR_WANT_READ &&
1176 client_err != SSL_ERROR_WANT_WRITE) {
1177 fprintf(stderr, "Client error: %d\n", client_err);
1178 return false;
1179 }
1180
1181 int server_ret = SSL_do_handshake(server.get());
1182 int server_err = SSL_get_error(server.get(), server_ret);
1183 if (server_err != SSL_ERROR_NONE &&
1184 server_err != SSL_ERROR_WANT_READ &&
1185 server_err != SSL_ERROR_WANT_WRITE) {
1186 fprintf(stderr, "Server error: %d\n", server_err);
1187 return false;
1188 }
1189
1190 if (client_ret == 1 && server_ret == 1) {
1191 break;
1192 }
1193 }
1194
David Benjamin686bb192016-05-10 15:15:41 -04001195 *out_client = std::move(client);
1196 *out_server = std::move(server);
1197 return true;
1198}
1199
1200static bool TestSequenceNumber(bool dtls) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001201 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
1202 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
David Benjamin686bb192016-05-10 15:15:41 -04001203 if (!client_ctx || !server_ctx) {
1204 return false;
1205 }
1206
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001207 bssl::UniquePtr<X509> cert = GetTestCertificate();
1208 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin686bb192016-05-10 15:15:41 -04001209 if (!cert || !key ||
1210 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1211 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1212 return false;
1213 }
1214
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001215 bssl::UniquePtr<SSL> client, server;
David Benjamin686bb192016-05-10 15:15:41 -04001216 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001217 server_ctx.get(), nullptr /* no session */)) {
David Benjamin686bb192016-05-10 15:15:41 -04001218 return false;
1219 }
1220
David Benjaminde942382016-02-11 12:02:01 -05001221 uint64_t client_read_seq = SSL_get_read_sequence(client.get());
1222 uint64_t client_write_seq = SSL_get_write_sequence(client.get());
1223 uint64_t server_read_seq = SSL_get_read_sequence(server.get());
1224 uint64_t server_write_seq = SSL_get_write_sequence(server.get());
1225
1226 if (dtls) {
1227 // Both client and server must be at epoch 1.
1228 if (EpochFromSequence(client_read_seq) != 1 ||
1229 EpochFromSequence(client_write_seq) != 1 ||
1230 EpochFromSequence(server_read_seq) != 1 ||
1231 EpochFromSequence(server_write_seq) != 1) {
1232 fprintf(stderr, "Bad epochs.\n");
1233 return false;
1234 }
1235
1236 // The next record to be written should exceed the largest received.
1237 if (client_write_seq <= server_read_seq ||
1238 server_write_seq <= client_read_seq) {
1239 fprintf(stderr, "Inconsistent sequence numbers.\n");
1240 return false;
1241 }
1242 } else {
1243 // The next record to be written should equal the next to be received.
1244 if (client_write_seq != server_read_seq ||
1245 server_write_seq != client_write_seq) {
1246 fprintf(stderr, "Inconsistent sequence numbers.\n");
1247 return false;
1248 }
1249 }
1250
1251 // Send a record from client to server.
1252 uint8_t byte = 0;
1253 if (SSL_write(client.get(), &byte, 1) != 1 ||
1254 SSL_read(server.get(), &byte, 1) != 1) {
1255 fprintf(stderr, "Could not send byte.\n");
1256 return false;
1257 }
1258
1259 // The client write and server read sequence numbers should have incremented.
1260 if (client_write_seq + 1 != SSL_get_write_sequence(client.get()) ||
1261 server_read_seq + 1 != SSL_get_read_sequence(server.get())) {
1262 fprintf(stderr, "Sequence numbers did not increment.\n");\
1263 return false;
1264 }
1265
1266 return true;
1267}
1268
David Benjamin686bb192016-05-10 15:15:41 -04001269static bool TestOneSidedShutdown() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001270 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1271 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjamin686bb192016-05-10 15:15:41 -04001272 if (!client_ctx || !server_ctx) {
1273 return false;
1274 }
1275
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001276 bssl::UniquePtr<X509> cert = GetTestCertificate();
1277 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin686bb192016-05-10 15:15:41 -04001278 if (!cert || !key ||
1279 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1280 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1281 return false;
1282 }
1283
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001284 bssl::UniquePtr<SSL> client, server;
David Benjamin686bb192016-05-10 15:15:41 -04001285 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001286 server_ctx.get(), nullptr /* no session */)) {
David Benjamin686bb192016-05-10 15:15:41 -04001287 return false;
1288 }
1289
1290 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1291 // one side has shut down.
1292 if (SSL_shutdown(client.get()) != 0) {
1293 fprintf(stderr, "Could not shutdown.\n");
1294 return false;
1295 }
1296
1297 // Reading from the server should consume the EOF.
1298 uint8_t byte;
1299 if (SSL_read(server.get(), &byte, 1) != 0 ||
1300 SSL_get_error(server.get(), 0) != SSL_ERROR_ZERO_RETURN) {
1301 fprintf(stderr, "Connection was not shut down cleanly.\n");
1302 return false;
1303 }
1304
1305 // However, the server may continue to write data and then shut down the
1306 // connection.
1307 byte = 42;
1308 if (SSL_write(server.get(), &byte, 1) != 1 ||
1309 SSL_read(client.get(), &byte, 1) != 1 ||
1310 byte != 42) {
1311 fprintf(stderr, "Could not send byte.\n");
1312 return false;
1313 }
1314
1315 // The server may then shutdown the connection.
1316 if (SSL_shutdown(server.get()) != 1 ||
1317 SSL_shutdown(client.get()) != 1) {
1318 fprintf(stderr, "Could not complete shutdown.\n");
1319 return false;
1320 }
1321
1322 return true;
1323}
Steven Valdez87eab492016-06-27 16:34:59 -04001324static bool TestSessionDuplication() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001325 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1326 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
Steven Valdez87eab492016-06-27 16:34:59 -04001327 if (!client_ctx || !server_ctx) {
1328 return false;
1329 }
1330
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001331 bssl::UniquePtr<X509> cert = GetTestCertificate();
1332 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
Steven Valdez87eab492016-06-27 16:34:59 -04001333 if (!cert || !key ||
1334 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1335 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1336 return false;
1337 }
1338
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001339 bssl::UniquePtr<SSL> client, server;
Steven Valdez87eab492016-06-27 16:34:59 -04001340 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001341 server_ctx.get(), nullptr /* no session */)) {
Steven Valdez87eab492016-06-27 16:34:59 -04001342 return false;
1343 }
1344
1345 SSL_SESSION *session0 = SSL_get_session(client.get());
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001346 bssl::UniquePtr<SSL_SESSION> session1(SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL));
Steven Valdez87eab492016-06-27 16:34:59 -04001347 if (!session1) {
David Benjamin4501bd52016-08-01 13:39:41 -04001348 return false;
Steven Valdez87eab492016-06-27 16:34:59 -04001349 }
David Benjamin4501bd52016-08-01 13:39:41 -04001350
Steven Valdez84b5c002016-08-25 16:30:58 -04001351 session1->not_resumable = 0;
1352
Steven Valdez87eab492016-06-27 16:34:59 -04001353 uint8_t *s0_bytes, *s1_bytes;
1354 size_t s0_len, s1_len;
1355
1356 if (!SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len)) {
1357 return false;
1358 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001359 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001360
1361 if (!SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len)) {
1362 return false;
1363 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001364 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001365
1366 return s0_len == s1_len && memcmp(s0_bytes, s1_bytes, s0_len) == 0;
1367}
David Benjamin686bb192016-05-10 15:15:41 -04001368
David Benjamin5c0fb882016-06-14 14:03:51 -04001369static bool ExpectFDs(const SSL *ssl, int rfd, int wfd) {
1370 if (SSL_get_rfd(ssl) != rfd || SSL_get_wfd(ssl) != wfd) {
1371 fprintf(stderr, "Got fds %d and %d, wanted %d and %d.\n", SSL_get_rfd(ssl),
1372 SSL_get_wfd(ssl), rfd, wfd);
1373 return false;
1374 }
1375
1376 // The wrapper BIOs are always equal when fds are equal, even if set
1377 // individually.
1378 if (rfd == wfd && SSL_get_rbio(ssl) != SSL_get_wbio(ssl)) {
1379 fprintf(stderr, "rbio and wbio did not match.\n");
1380 return false;
1381 }
1382
1383 return true;
1384}
1385
1386static bool TestSetFD() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001387 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin5c0fb882016-06-14 14:03:51 -04001388 if (!ctx) {
1389 return false;
1390 }
1391
1392 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001393 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjamin5c0fb882016-06-14 14:03:51 -04001394 if (!ssl ||
1395 !SSL_set_rfd(ssl.get(), 1) ||
1396 !SSL_set_wfd(ssl.get(), 2) ||
1397 !ExpectFDs(ssl.get(), 1, 2)) {
1398 return false;
1399 }
1400
1401 // Test setting the same FD.
1402 ssl.reset(SSL_new(ctx.get()));
1403 if (!ssl ||
1404 !SSL_set_fd(ssl.get(), 1) ||
1405 !ExpectFDs(ssl.get(), 1, 1)) {
1406 return false;
1407 }
1408
1409 // Test setting the same FD one side at a time.
1410 ssl.reset(SSL_new(ctx.get()));
1411 if (!ssl ||
1412 !SSL_set_rfd(ssl.get(), 1) ||
1413 !SSL_set_wfd(ssl.get(), 1) ||
1414 !ExpectFDs(ssl.get(), 1, 1)) {
1415 return false;
1416 }
1417
1418 // Test setting the same FD in the other order.
1419 ssl.reset(SSL_new(ctx.get()));
1420 if (!ssl ||
1421 !SSL_set_wfd(ssl.get(), 1) ||
1422 !SSL_set_rfd(ssl.get(), 1) ||
1423 !ExpectFDs(ssl.get(), 1, 1)) {
1424 return false;
1425 }
1426
David Benjamin5c0fb882016-06-14 14:03:51 -04001427 // Test changing the read FD partway through.
1428 ssl.reset(SSL_new(ctx.get()));
1429 if (!ssl ||
1430 !SSL_set_fd(ssl.get(), 1) ||
1431 !SSL_set_rfd(ssl.get(), 2) ||
1432 !ExpectFDs(ssl.get(), 2, 1)) {
1433 return false;
1434 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001435
1436 // Test changing the write FD partway through.
1437 ssl.reset(SSL_new(ctx.get()));
1438 if (!ssl ||
1439 !SSL_set_fd(ssl.get(), 1) ||
1440 !SSL_set_wfd(ssl.get(), 2) ||
1441 !ExpectFDs(ssl.get(), 1, 2)) {
1442 return false;
1443 }
1444
1445 // Test a no-op change to the read FD partway through.
1446 ssl.reset(SSL_new(ctx.get()));
1447 if (!ssl ||
1448 !SSL_set_fd(ssl.get(), 1) ||
1449 !SSL_set_rfd(ssl.get(), 1) ||
1450 !ExpectFDs(ssl.get(), 1, 1)) {
1451 return false;
1452 }
1453
1454 // Test a no-op change to the write FD partway through.
1455 ssl.reset(SSL_new(ctx.get()));
1456 if (!ssl ||
1457 !SSL_set_fd(ssl.get(), 1) ||
1458 !SSL_set_wfd(ssl.get(), 1) ||
1459 !ExpectFDs(ssl.get(), 1, 1)) {
1460 return false;
1461 }
1462
1463 // ASan builds will implicitly test that the internal |BIO| reference-counting
1464 // is correct.
1465
1466 return true;
1467}
1468
David Benjamin4501bd52016-08-01 13:39:41 -04001469static bool TestSetBIO() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001470 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin4501bd52016-08-01 13:39:41 -04001471 if (!ctx) {
1472 return false;
1473 }
1474
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001475 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1476 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04001477 bio3(BIO_new(BIO_s_mem()));
1478 if (!ssl || !bio1 || !bio2 || !bio3) {
1479 return false;
1480 }
1481
1482 // SSL_set_bio takes one reference when the parameters are the same.
1483 BIO_up_ref(bio1.get());
1484 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1485
1486 // Repeating the call does nothing.
1487 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1488
1489 // It takes one reference each when the parameters are different.
1490 BIO_up_ref(bio2.get());
1491 BIO_up_ref(bio3.get());
1492 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1493
1494 // Repeating the call does nothing.
1495 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1496
1497 // It takes one reference when changing only wbio.
1498 BIO_up_ref(bio1.get());
1499 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1500
1501 // It takes one reference when changing only rbio and the two are different.
1502 BIO_up_ref(bio3.get());
1503 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1504
1505 // If setting wbio to rbio, it takes no additional references.
1506 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1507
1508 // From there, wbio may be switched to something else.
1509 BIO_up_ref(bio1.get());
1510 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1511
1512 // If setting rbio to wbio, it takes no additional references.
1513 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1514
1515 // From there, rbio may be switched to something else, but, for historical
1516 // reasons, it takes a reference to both parameters.
1517 BIO_up_ref(bio1.get());
1518 BIO_up_ref(bio2.get());
1519 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1520
1521 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1522 // is correct.
1523 return true;
1524}
1525
David Benjamin25490f22016-07-14 00:22:54 -04001526static uint16_t kVersions[] = {
1527 SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION, TLS1_2_VERSION, TLS1_3_VERSION,
1528};
1529
1530static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1531
David Benjaminadd5e522016-07-14 00:33:24 -04001532static bool TestGetPeerCertificate() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001533 bssl::UniquePtr<X509> cert = GetTestCertificate();
1534 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminadd5e522016-07-14 00:33:24 -04001535 if (!cert || !key) {
1536 return false;
1537 }
1538
1539 for (uint16_t version : kVersions) {
1540 // Configure both client and server to accept any certificate.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001541 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminadd5e522016-07-14 00:33:24 -04001542 if (!ctx ||
1543 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1544 !SSL_CTX_use_PrivateKey(ctx.get(), key.get())) {
1545 return false;
1546 }
1547 SSL_CTX_set_min_version(ctx.get(), version);
1548 SSL_CTX_set_max_version(ctx.get(), version);
1549 SSL_CTX_set_verify(
1550 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1551 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1552
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001553 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001554 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1555 nullptr /* no session */)) {
David Benjaminadd5e522016-07-14 00:33:24 -04001556 return false;
1557 }
1558
1559 // Client and server should both see the leaf certificate.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001560 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04001561 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1562 fprintf(stderr, "%x: Server peer certificate did not match.\n", version);
1563 return false;
1564 }
1565
1566 peer.reset(SSL_get_peer_certificate(client.get()));
1567 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1568 fprintf(stderr, "%x: Client peer certificate did not match.\n", version);
1569 return false;
1570 }
1571
1572 // However, for historical reasons, the chain includes the leaf on the
1573 // client, but does not on the server.
1574 if (sk_X509_num(SSL_get_peer_cert_chain(client.get())) != 1) {
1575 fprintf(stderr, "%x: Client peer chain was incorrect.\n", version);
1576 return false;
1577 }
1578
1579 if (sk_X509_num(SSL_get_peer_cert_chain(server.get())) != 0) {
1580 fprintf(stderr, "%x: Server peer chain was incorrect.\n", version);
1581 return false;
1582 }
1583 }
1584
1585 return true;
1586}
1587
David Benjamin25490f22016-07-14 00:22:54 -04001588static bool TestRetainOnlySHA256OfCerts() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001589 bssl::UniquePtr<X509> cert = GetTestCertificate();
1590 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin25490f22016-07-14 00:22:54 -04001591 if (!cert || !key) {
1592 return false;
1593 }
1594
1595 uint8_t *cert_der = NULL;
1596 int cert_der_len = i2d_X509(cert.get(), &cert_der);
1597 if (cert_der_len < 0) {
1598 return false;
1599 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001600 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04001601
1602 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1603 SHA256(cert_der, cert_der_len, cert_sha256);
1604
1605 for (uint16_t version : kVersions) {
1606 // Configure both client and server to accept any certificate, but the
1607 // server must retain only the SHA-256 of the peer.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001608 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin25490f22016-07-14 00:22:54 -04001609 if (!ctx ||
1610 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1611 !SSL_CTX_use_PrivateKey(ctx.get(), key.get())) {
1612 return false;
1613 }
1614 SSL_CTX_set_min_version(ctx.get(), version);
1615 SSL_CTX_set_max_version(ctx.get(), version);
1616 SSL_CTX_set_verify(
1617 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1618 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1619 SSL_CTX_set_retain_only_sha256_of_client_certs(ctx.get(), 1);
1620
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001621 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001622 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1623 nullptr /* no session */)) {
David Benjamin25490f22016-07-14 00:22:54 -04001624 return false;
1625 }
1626
1627 // The peer certificate has been dropped.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001628 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
David Benjamin25490f22016-07-14 00:22:54 -04001629 if (peer) {
1630 fprintf(stderr, "%x: Peer certificate was retained.\n", version);
1631 return false;
1632 }
1633
1634 SSL_SESSION *session = SSL_get_session(server.get());
1635 if (!session->peer_sha256_valid) {
1636 fprintf(stderr, "%x: peer_sha256_valid was not set.\n", version);
1637 return false;
1638 }
1639
1640 if (memcmp(cert_sha256, session->peer_sha256, SHA256_DIGEST_LENGTH) != 0) {
1641 fprintf(stderr, "%x: peer_sha256 did not match.\n", version);
1642 return false;
1643 }
1644 }
1645
1646 return true;
1647}
1648
David Benjaminafc64de2016-07-19 17:12:41 +02001649static bool ClientHelloMatches(uint16_t version, const uint8_t *expected,
1650 size_t expected_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001651 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminafc64de2016-07-19 17:12:41 +02001652 if (!ctx) {
1653 return false;
1654 }
1655 SSL_CTX_set_max_version(ctx.get(), version);
1656 // Our default cipher list varies by CPU capabilities, so manually place the
1657 // ChaCha20 ciphers in front.
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001658 if (!SSL_CTX_set_cipher_list(ctx.get(), "!RC4:CHACHA20:ALL")) {
David Benjaminafc64de2016-07-19 17:12:41 +02001659 return false;
1660 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001661 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +02001662 if (!ssl) {
1663 return false;
1664 }
1665 std::vector<uint8_t> client_hello;
1666 if (!GetClientHello(ssl.get(), &client_hello)) {
1667 return false;
1668 }
1669
1670 // Zero the client_random.
1671 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
1672 1 + 3 + // handshake message header
1673 2; // client_version
1674 if (client_hello.size() < kRandomOffset + SSL3_RANDOM_SIZE) {
1675 fprintf(stderr, "ClientHello for version %04x too short.\n", version);
1676 return false;
1677 }
1678 memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
1679
1680 if (client_hello.size() != expected_len ||
1681 memcmp(client_hello.data(), expected, expected_len) != 0) {
1682 fprintf(stderr, "ClientHello for version %04x did not match:\n", version);
1683 fprintf(stderr, "Got:\n\t");
1684 for (size_t i = 0; i < client_hello.size(); i++) {
1685 fprintf(stderr, "0x%02x, ", client_hello[i]);
1686 }
1687 fprintf(stderr, "\nWanted:\n\t");
1688 for (size_t i = 0; i < expected_len; i++) {
1689 fprintf(stderr, "0x%02x, ", expected[i]);
1690 }
1691 fprintf(stderr, "\n");
1692 return false;
1693 }
1694
1695 return true;
1696}
1697
1698// Tests that our ClientHellos do not change unexpectedly.
1699static bool TestClientHello() {
1700 static const uint8_t kSSL3ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001701 0x16,
1702 0x03, 0x00,
1703 0x00, 0x3f,
1704 0x01,
1705 0x00, 0x00, 0x3b,
1706 0x03, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1711 0x00,
1712 0x00, 0x14,
1713 0xc0, 0x09,
1714 0xc0, 0x13,
1715 0x00, 0x33,
1716 0xc0, 0x0a,
1717 0xc0, 0x14,
1718 0x00, 0x39,
1719 0x00, 0x2f,
1720 0x00, 0x35,
1721 0x00, 0x0a,
1722 0x00, 0xff, 0x01, 0x00,
David Benjaminafc64de2016-07-19 17:12:41 +02001723 };
1724 if (!ClientHelloMatches(SSL3_VERSION, kSSL3ClientHello,
1725 sizeof(kSSL3ClientHello))) {
1726 return false;
1727 }
1728
1729 static const uint8_t kTLS1ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001730 0x16,
1731 0x03, 0x01,
1732 0x00, 0x5e,
1733 0x01,
1734 0x00, 0x00, 0x5a,
1735 0x03, 0x01,
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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1740 0x00,
1741 0x00, 0x12,
1742 0xc0, 0x09,
1743 0xc0, 0x13,
1744 0x00, 0x33,
1745 0xc0, 0x0a,
1746 0xc0, 0x14,
1747 0x00, 0x39,
1748 0x00, 0x2f,
1749 0x00, 0x35,
1750 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001751 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1752 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1753 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1754 };
1755 if (!ClientHelloMatches(TLS1_VERSION, kTLS1ClientHello,
1756 sizeof(kTLS1ClientHello))) {
1757 return false;
1758 }
1759
1760 static const uint8_t kTLS11ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001761 0x16,
1762 0x03, 0x01,
1763 0x00, 0x5e,
1764 0x01,
1765 0x00, 0x00, 0x5a,
1766 0x03, 0x02,
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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1771 0x00,
1772 0x00, 0x12,
1773 0xc0, 0x09,
1774 0xc0, 0x13,
1775 0x00, 0x33,
1776 0xc0, 0x0a,
1777 0xc0, 0x14,
1778 0x00, 0x39,
1779 0x00, 0x2f,
1780 0x00, 0x35,
1781 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001782 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1783 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1784 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1785 };
1786 if (!ClientHelloMatches(TLS1_1_VERSION, kTLS11ClientHello,
1787 sizeof(kTLS11ClientHello))) {
1788 return false;
1789 }
1790
1791 static const uint8_t kTLS12ClientHello[] = {
David Benjamin57e929f2016-08-30 00:30:38 -04001792 0x16, 0x03, 0x01, 0x00, 0xa2, 0x01, 0x00, 0x00, 0x9e, 0x03, 0x03, 0x00,
1793 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1794 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1795 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0xcc, 0xa9,
1796 0xcc, 0xa8, 0xcc, 0x14, 0xcc, 0x13, 0xc0, 0x2b, 0xc0, 0x2f, 0x00, 0x9e,
1797 0xc0, 0x2c, 0xc0, 0x30, 0x00, 0x9f, 0xc0, 0x09, 0xc0, 0x23, 0xc0, 0x13,
1798 0xc0, 0x27, 0x00, 0x33, 0x00, 0x67, 0xc0, 0x0a, 0xc0, 0x24, 0xc0, 0x14,
1799 0xc0, 0x28, 0x00, 0x39, 0x00, 0x6b, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
1800 0x00, 0x3c, 0x00, 0x35, 0x00, 0x3d, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x3b,
1801 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00,
1802 0x00, 0x00, 0x0d, 0x00, 0x18, 0x00, 0x16, 0x07, 0x02, 0x06, 0x01, 0x06,
1803 0x03, 0x07, 0x01, 0x05, 0x01, 0x05, 0x03, 0x07, 0x00, 0x04, 0x01, 0x04,
1804 0x03, 0x02, 0x01, 0x02, 0x03, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1805 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
David Benjaminafc64de2016-07-19 17:12:41 +02001806 };
1807 if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
1808 sizeof(kTLS12ClientHello))) {
1809 return false;
1810 }
1811
1812 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
1813 // implementation has settled enough that it won't change.
1814
1815 return true;
1816}
1817
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001818static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04001819
1820static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
1821 // Save the most recent session.
1822 g_last_session.reset(session);
1823 return 1;
1824}
1825
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001826static bssl::UniquePtr<SSL_SESSION> CreateClientSession(SSL_CTX *client_ctx,
David Benjamina20e5352016-08-02 19:09:41 -04001827 SSL_CTX *server_ctx) {
1828 g_last_session = nullptr;
1829 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
1830
1831 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001832 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001833 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
1834 nullptr /* no session */)) {
1835 fprintf(stderr, "Failed to connect client and server.\n");
1836 return nullptr;
1837 }
1838
1839 // Run the read loop to account for post-handshake tickets in TLS 1.3.
1840 SSL_read(client.get(), nullptr, 0);
1841
1842 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
1843
1844 if (!g_last_session) {
1845 fprintf(stderr, "Client did not receive a session.\n");
1846 return nullptr;
1847 }
1848 return std::move(g_last_session);
1849}
1850
1851static bool ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1852 SSL_SESSION *session,
1853 bool reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001854 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001855 if (!ConnectClientAndServer(&client, &server, client_ctx,
1856 server_ctx, session)) {
1857 fprintf(stderr, "Failed to connect client and server.\n");
1858 return false;
1859 }
1860
1861 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
1862 fprintf(stderr, "Client and server were inconsistent.\n");
1863 return false;
1864 }
1865
1866 bool was_reused = !!SSL_session_reused(client.get());
1867 if (was_reused != reused) {
1868 fprintf(stderr, "Session was%s reused, but we expected the opposite.\n",
1869 was_reused ? "" : " not");
1870 return false;
1871 }
1872
1873 return true;
1874}
1875
1876static bool TestSessionIDContext() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001877 bssl::UniquePtr<X509> cert = GetTestCertificate();
1878 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamina20e5352016-08-02 19:09:41 -04001879 if (!cert || !key) {
1880 return false;
1881 }
1882
1883 static const uint8_t kContext1[] = {1};
1884 static const uint8_t kContext2[] = {2};
1885
1886 for (uint16_t version : kVersions) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001887 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
1888 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamina20e5352016-08-02 19:09:41 -04001889 if (!server_ctx || !client_ctx ||
1890 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1891 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
1892 !SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
1893 sizeof(kContext1))) {
1894 return false;
1895 }
1896
1897 SSL_CTX_set_min_version(client_ctx.get(), version);
1898 SSL_CTX_set_max_version(client_ctx.get(), version);
1899 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
1900
1901 SSL_CTX_set_min_version(server_ctx.get(), version);
1902 SSL_CTX_set_max_version(server_ctx.get(), version);
1903 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
1904
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001905 bssl::UniquePtr<SSL_SESSION> session =
David Benjamina20e5352016-08-02 19:09:41 -04001906 CreateClientSession(client_ctx.get(), server_ctx.get());
1907 if (!session) {
1908 fprintf(stderr, "Error getting session (version = %04x).\n", version);
1909 return false;
1910 }
1911
1912 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1913 true /* expect session reused */)) {
1914 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
1915 return false;
1916 }
1917
1918 // Change the session ID context.
1919 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext2,
1920 sizeof(kContext2))) {
1921 return false;
1922 }
1923
1924 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1925 false /* expect session not reused */)) {
1926 fprintf(stderr,
1927 "Error connection with different context (version = %04x).\n",
1928 version);
1929 return false;
1930 }
1931 }
1932
1933 return true;
1934}
1935
David Benjamin721e8b72016-08-03 13:13:17 -04001936static timeval g_current_time;
1937
1938static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
1939 *out_clock = g_current_time;
1940}
1941
1942static bool TestSessionTimeout() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001943 bssl::UniquePtr<X509> cert = GetTestCertificate();
1944 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin721e8b72016-08-03 13:13:17 -04001945 if (!cert || !key) {
1946 return false;
1947 }
1948
1949 for (uint16_t version : kVersions) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001950 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
1951 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin721e8b72016-08-03 13:13:17 -04001952 if (!server_ctx || !client_ctx ||
1953 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1954 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1955 return false;
1956 }
1957
1958 SSL_CTX_set_min_version(client_ctx.get(), version);
1959 SSL_CTX_set_max_version(client_ctx.get(), version);
1960 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
1961
1962 SSL_CTX_set_min_version(server_ctx.get(), version);
1963 SSL_CTX_set_max_version(server_ctx.get(), version);
1964 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
1965 SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
1966
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001967 bssl::UniquePtr<SSL_SESSION> session =
David Benjamin721e8b72016-08-03 13:13:17 -04001968 CreateClientSession(client_ctx.get(), server_ctx.get());
1969 if (!session) {
1970 fprintf(stderr, "Error getting session (version = %04x).\n", version);
1971 return false;
1972 }
1973
1974 // Advance the clock just behind the timeout.
1975 g_current_time.tv_sec += SSL_DEFAULT_SESSION_TIMEOUT;
1976
1977 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1978 true /* expect session reused */)) {
1979 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
1980 return false;
1981 }
1982
1983 // Advance the clock one more second.
1984 g_current_time.tv_sec++;
1985
1986 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1987 false /* expect session not reused */)) {
1988 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
1989 return false;
1990 }
1991 }
1992
1993 return true;
1994}
1995
David Benjamin0fc37ef2016-08-17 15:29:46 -04001996static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
1997 SSL_CTX *ctx = reinterpret_cast<SSL_CTX*>(arg);
1998 SSL_set_SSL_CTX(ssl, ctx);
1999 return SSL_TLSEXT_ERR_OK;
2000}
2001
2002static bool TestSNICallback() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002003 bssl::UniquePtr<X509> cert = GetTestCertificate();
2004 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2005 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
2006 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
David Benjamin0fc37ef2016-08-17 15:29:46 -04002007 if (!cert || !key || !cert2 || !key2) {
2008 return false;
2009 }
2010
2011 // At each version, test that switching the |SSL_CTX| at the SNI callback
2012 // behaves correctly.
2013 for (uint16_t version : kVersions) {
2014 if (version == SSL3_VERSION) {
2015 continue;
2016 }
2017
2018 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
2019
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002020 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2021 bssl::UniquePtr<SSL_CTX> server_ctx2(SSL_CTX_new(TLS_method()));
2022 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002023 if (!server_ctx || !server_ctx2 || !client_ctx ||
2024 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2025 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2026 !SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()) ||
2027 !SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()) ||
2028 // Historically signing preferences would be lost in some cases with the
2029 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2030 // this doesn't happen when |version| is TLS 1.2, configure the private
2031 // key to only sign SHA-256.
2032 !SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
2033 &kECDSAWithSHA256, 1)) {
2034 return false;
2035 }
2036
2037 SSL_CTX_set_min_version(client_ctx.get(), version);
2038 SSL_CTX_set_max_version(client_ctx.get(), version);
2039 SSL_CTX_set_min_version(server_ctx.get(), version);
2040 SSL_CTX_set_max_version(server_ctx.get(), version);
2041 SSL_CTX_set_min_version(server_ctx2.get(), version);
2042 SSL_CTX_set_max_version(server_ctx2.get(), version);
2043
2044 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), SwitchContext);
2045 SSL_CTX_set_tlsext_servername_arg(server_ctx.get(), server_ctx2.get());
2046
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002047 bssl::UniquePtr<SSL> client, server;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002048 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2049 server_ctx.get(), nullptr)) {
2050 fprintf(stderr, "Handshake failed at version %04x.\n", version);
2051 return false;
2052 }
2053
2054 // The client should have received |cert2|.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002055 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client.get()));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002056 if (!peer ||
2057 X509_cmp(peer.get(), cert2.get()) != 0) {
2058 fprintf(stderr, "Incorrect certificate received at version %04x.\n",
2059 version);
2060 return false;
2061 }
2062 }
2063
2064 return true;
2065}
2066
David Benjamin99620572016-08-30 00:35:36 -04002067static int SetMaxVersion(const struct ssl_early_callback_ctx *ctx) {
2068 SSL_set_max_version(ctx->ssl, TLS1_2_VERSION);
2069 return 1;
2070}
2071
2072// TestEarlyCallbackVersionSwitch tests that the early callback can swap the
2073// maximum version.
2074static bool TestEarlyCallbackVersionSwitch() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002075 bssl::UniquePtr<X509> cert = GetTestCertificate();
2076 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2077 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2078 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin99620572016-08-30 00:35:36 -04002079 if (!cert || !key || !server_ctx || !client_ctx ||
2080 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2081 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
2082 return false;
2083 }
2084
2085 SSL_CTX_set_max_version(client_ctx.get(), TLS1_3_VERSION);
2086 SSL_CTX_set_max_version(server_ctx.get(), TLS1_3_VERSION);
2087
2088 SSL_CTX_set_select_certificate_cb(server_ctx.get(), SetMaxVersion);
2089
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002090 bssl::UniquePtr<SSL> client, server;
David Benjamin99620572016-08-30 00:35:36 -04002091 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2092 server_ctx.get(), nullptr)) {
2093 return false;
2094 }
2095
2096 if (SSL_version(client.get()) != TLS1_2_VERSION) {
2097 fprintf(stderr, "Early callback failed to switch the maximum version.\n");
2098 return false;
2099 }
2100
2101 return true;
2102}
2103
David Benjamin1d128f32015-09-08 17:41:40 -04002104int main() {
David Benjamin7a1eefd2015-10-17 23:39:22 -04002105 CRYPTO_library_init();
David Benjaminbb0a17c2014-09-20 15:35:39 -04002106
Adam Langley10f97f32016-07-12 08:09:33 -07002107 if (!TestCipherRules() ||
2108 !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
2109 !TestSSL_SESSIONEncoding(kCustomSession) ||
2110 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
2111 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
2112 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
2113 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
David Benjamin10e664b2016-06-20 22:20:47 -04002114 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
Adam Langley10f97f32016-07-12 08:09:33 -07002115 !TestDefaultVersion(SSL3_VERSION, TLS1_2_VERSION, &TLS_method) ||
2116 !TestDefaultVersion(SSL3_VERSION, SSL3_VERSION, &SSLv3_method) ||
2117 !TestDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method) ||
2118 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method) ||
2119 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method) ||
2120 !TestDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method) ||
2121 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method) ||
2122 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method) ||
2123 !TestCipherGetRFCName() ||
2124 !TestPaddingExtension() ||
2125 !TestClientCAList() ||
2126 !TestInternalSessionCache() ||
2127 !TestSequenceNumber(false /* TLS */) ||
2128 !TestSequenceNumber(true /* DTLS */) ||
2129 !TestOneSidedShutdown() ||
Steven Valdez87eab492016-06-27 16:34:59 -04002130 !TestSessionDuplication() ||
David Benjamin25490f22016-07-14 00:22:54 -04002131 !TestSetFD() ||
David Benjamin4501bd52016-08-01 13:39:41 -04002132 !TestSetBIO() ||
David Benjaminadd5e522016-07-14 00:33:24 -04002133 !TestGetPeerCertificate() ||
David Benjaminafc64de2016-07-19 17:12:41 +02002134 !TestRetainOnlySHA256OfCerts() ||
David Benjamina20e5352016-08-02 19:09:41 -04002135 !TestClientHello() ||
David Benjamin721e8b72016-08-03 13:13:17 -04002136 !TestSessionIDContext() ||
David Benjamin0fc37ef2016-08-17 15:29:46 -04002137 !TestSessionTimeout() ||
David Benjamin99620572016-08-30 00:35:36 -04002138 !TestSNICallback() ||
2139 !TestEarlyCallbackVersionSwitch()) {
Brian Smith83a82982015-04-09 16:21:10 -10002140 ERR_print_errors_fp(stderr);
David Benjaminbb0a17c2014-09-20 15:35:39 -04002141 return 1;
2142 }
2143
David Benjamin2e521212014-07-16 14:37:51 -04002144 printf("PASS\n");
2145 return 0;
2146}