blob: 78900e91c7a8b24e8807b00828e0ab56e205ad35 [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 Valdez87eab492016-06-27 16:34:59 -04001351 uint8_t *s0_bytes, *s1_bytes;
1352 size_t s0_len, s1_len;
1353
1354 if (!SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len)) {
1355 return false;
1356 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001357 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001358
1359 if (!SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len)) {
1360 return false;
1361 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001362 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001363
1364 return s0_len == s1_len && memcmp(s0_bytes, s1_bytes, s0_len) == 0;
1365}
David Benjamin686bb192016-05-10 15:15:41 -04001366
David Benjamin5c0fb882016-06-14 14:03:51 -04001367static bool ExpectFDs(const SSL *ssl, int rfd, int wfd) {
1368 if (SSL_get_rfd(ssl) != rfd || SSL_get_wfd(ssl) != wfd) {
1369 fprintf(stderr, "Got fds %d and %d, wanted %d and %d.\n", SSL_get_rfd(ssl),
1370 SSL_get_wfd(ssl), rfd, wfd);
1371 return false;
1372 }
1373
1374 // The wrapper BIOs are always equal when fds are equal, even if set
1375 // individually.
1376 if (rfd == wfd && SSL_get_rbio(ssl) != SSL_get_wbio(ssl)) {
1377 fprintf(stderr, "rbio and wbio did not match.\n");
1378 return false;
1379 }
1380
1381 return true;
1382}
1383
1384static bool TestSetFD() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001385 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin5c0fb882016-06-14 14:03:51 -04001386 if (!ctx) {
1387 return false;
1388 }
1389
1390 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001391 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjamin5c0fb882016-06-14 14:03:51 -04001392 if (!ssl ||
1393 !SSL_set_rfd(ssl.get(), 1) ||
1394 !SSL_set_wfd(ssl.get(), 2) ||
1395 !ExpectFDs(ssl.get(), 1, 2)) {
1396 return false;
1397 }
1398
1399 // Test setting the same FD.
1400 ssl.reset(SSL_new(ctx.get()));
1401 if (!ssl ||
1402 !SSL_set_fd(ssl.get(), 1) ||
1403 !ExpectFDs(ssl.get(), 1, 1)) {
1404 return false;
1405 }
1406
1407 // Test setting the same FD one side at a time.
1408 ssl.reset(SSL_new(ctx.get()));
1409 if (!ssl ||
1410 !SSL_set_rfd(ssl.get(), 1) ||
1411 !SSL_set_wfd(ssl.get(), 1) ||
1412 !ExpectFDs(ssl.get(), 1, 1)) {
1413 return false;
1414 }
1415
1416 // Test setting the same FD in the other order.
1417 ssl.reset(SSL_new(ctx.get()));
1418 if (!ssl ||
1419 !SSL_set_wfd(ssl.get(), 1) ||
1420 !SSL_set_rfd(ssl.get(), 1) ||
1421 !ExpectFDs(ssl.get(), 1, 1)) {
1422 return false;
1423 }
1424
David Benjamin5c0fb882016-06-14 14:03:51 -04001425 // Test changing the read FD partway through.
1426 ssl.reset(SSL_new(ctx.get()));
1427 if (!ssl ||
1428 !SSL_set_fd(ssl.get(), 1) ||
1429 !SSL_set_rfd(ssl.get(), 2) ||
1430 !ExpectFDs(ssl.get(), 2, 1)) {
1431 return false;
1432 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001433
1434 // Test changing the write FD partway through.
1435 ssl.reset(SSL_new(ctx.get()));
1436 if (!ssl ||
1437 !SSL_set_fd(ssl.get(), 1) ||
1438 !SSL_set_wfd(ssl.get(), 2) ||
1439 !ExpectFDs(ssl.get(), 1, 2)) {
1440 return false;
1441 }
1442
1443 // Test a no-op change to the read FD partway through.
1444 ssl.reset(SSL_new(ctx.get()));
1445 if (!ssl ||
1446 !SSL_set_fd(ssl.get(), 1) ||
1447 !SSL_set_rfd(ssl.get(), 1) ||
1448 !ExpectFDs(ssl.get(), 1, 1)) {
1449 return false;
1450 }
1451
1452 // Test a no-op change to the write FD partway through.
1453 ssl.reset(SSL_new(ctx.get()));
1454 if (!ssl ||
1455 !SSL_set_fd(ssl.get(), 1) ||
1456 !SSL_set_wfd(ssl.get(), 1) ||
1457 !ExpectFDs(ssl.get(), 1, 1)) {
1458 return false;
1459 }
1460
1461 // ASan builds will implicitly test that the internal |BIO| reference-counting
1462 // is correct.
1463
1464 return true;
1465}
1466
David Benjamin4501bd52016-08-01 13:39:41 -04001467static bool TestSetBIO() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001468 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin4501bd52016-08-01 13:39:41 -04001469 if (!ctx) {
1470 return false;
1471 }
1472
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001473 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1474 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04001475 bio3(BIO_new(BIO_s_mem()));
1476 if (!ssl || !bio1 || !bio2 || !bio3) {
1477 return false;
1478 }
1479
1480 // SSL_set_bio takes one reference when the parameters are the same.
1481 BIO_up_ref(bio1.get());
1482 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1483
1484 // Repeating the call does nothing.
1485 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1486
1487 // It takes one reference each when the parameters are different.
1488 BIO_up_ref(bio2.get());
1489 BIO_up_ref(bio3.get());
1490 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1491
1492 // Repeating the call does nothing.
1493 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1494
1495 // It takes one reference when changing only wbio.
1496 BIO_up_ref(bio1.get());
1497 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1498
1499 // It takes one reference when changing only rbio and the two are different.
1500 BIO_up_ref(bio3.get());
1501 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1502
1503 // If setting wbio to rbio, it takes no additional references.
1504 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1505
1506 // From there, wbio may be switched to something else.
1507 BIO_up_ref(bio1.get());
1508 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1509
1510 // If setting rbio to wbio, it takes no additional references.
1511 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1512
1513 // From there, rbio may be switched to something else, but, for historical
1514 // reasons, it takes a reference to both parameters.
1515 BIO_up_ref(bio1.get());
1516 BIO_up_ref(bio2.get());
1517 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1518
1519 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1520 // is correct.
1521 return true;
1522}
1523
David Benjamin25490f22016-07-14 00:22:54 -04001524static uint16_t kVersions[] = {
1525 SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION, TLS1_2_VERSION, TLS1_3_VERSION,
1526};
1527
1528static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1529
David Benjaminadd5e522016-07-14 00:33:24 -04001530static bool TestGetPeerCertificate() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001531 bssl::UniquePtr<X509> cert = GetTestCertificate();
1532 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminadd5e522016-07-14 00:33:24 -04001533 if (!cert || !key) {
1534 return false;
1535 }
1536
1537 for (uint16_t version : kVersions) {
1538 // Configure both client and server to accept any certificate.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001539 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminadd5e522016-07-14 00:33:24 -04001540 if (!ctx ||
1541 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1542 !SSL_CTX_use_PrivateKey(ctx.get(), key.get())) {
1543 return false;
1544 }
1545 SSL_CTX_set_min_version(ctx.get(), version);
1546 SSL_CTX_set_max_version(ctx.get(), version);
1547 SSL_CTX_set_verify(
1548 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1549 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1550
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001551 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001552 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1553 nullptr /* no session */)) {
David Benjaminadd5e522016-07-14 00:33:24 -04001554 return false;
1555 }
1556
1557 // Client and server should both see the leaf certificate.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001558 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04001559 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1560 fprintf(stderr, "%x: Server peer certificate did not match.\n", version);
1561 return false;
1562 }
1563
1564 peer.reset(SSL_get_peer_certificate(client.get()));
1565 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1566 fprintf(stderr, "%x: Client peer certificate did not match.\n", version);
1567 return false;
1568 }
1569
1570 // However, for historical reasons, the chain includes the leaf on the
1571 // client, but does not on the server.
1572 if (sk_X509_num(SSL_get_peer_cert_chain(client.get())) != 1) {
1573 fprintf(stderr, "%x: Client peer chain was incorrect.\n", version);
1574 return false;
1575 }
1576
1577 if (sk_X509_num(SSL_get_peer_cert_chain(server.get())) != 0) {
1578 fprintf(stderr, "%x: Server peer chain was incorrect.\n", version);
1579 return false;
1580 }
1581 }
1582
1583 return true;
1584}
1585
David Benjamin25490f22016-07-14 00:22:54 -04001586static bool TestRetainOnlySHA256OfCerts() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001587 bssl::UniquePtr<X509> cert = GetTestCertificate();
1588 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin25490f22016-07-14 00:22:54 -04001589 if (!cert || !key) {
1590 return false;
1591 }
1592
1593 uint8_t *cert_der = NULL;
1594 int cert_der_len = i2d_X509(cert.get(), &cert_der);
1595 if (cert_der_len < 0) {
1596 return false;
1597 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001598 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04001599
1600 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1601 SHA256(cert_der, cert_der_len, cert_sha256);
1602
1603 for (uint16_t version : kVersions) {
1604 // Configure both client and server to accept any certificate, but the
1605 // server must retain only the SHA-256 of the peer.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001606 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin25490f22016-07-14 00:22:54 -04001607 if (!ctx ||
1608 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1609 !SSL_CTX_use_PrivateKey(ctx.get(), key.get())) {
1610 return false;
1611 }
1612 SSL_CTX_set_min_version(ctx.get(), version);
1613 SSL_CTX_set_max_version(ctx.get(), version);
1614 SSL_CTX_set_verify(
1615 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1616 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1617 SSL_CTX_set_retain_only_sha256_of_client_certs(ctx.get(), 1);
1618
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001619 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001620 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1621 nullptr /* no session */)) {
David Benjamin25490f22016-07-14 00:22:54 -04001622 return false;
1623 }
1624
1625 // The peer certificate has been dropped.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001626 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
David Benjamin25490f22016-07-14 00:22:54 -04001627 if (peer) {
1628 fprintf(stderr, "%x: Peer certificate was retained.\n", version);
1629 return false;
1630 }
1631
1632 SSL_SESSION *session = SSL_get_session(server.get());
1633 if (!session->peer_sha256_valid) {
1634 fprintf(stderr, "%x: peer_sha256_valid was not set.\n", version);
1635 return false;
1636 }
1637
1638 if (memcmp(cert_sha256, session->peer_sha256, SHA256_DIGEST_LENGTH) != 0) {
1639 fprintf(stderr, "%x: peer_sha256 did not match.\n", version);
1640 return false;
1641 }
1642 }
1643
1644 return true;
1645}
1646
David Benjaminafc64de2016-07-19 17:12:41 +02001647static bool ClientHelloMatches(uint16_t version, const uint8_t *expected,
1648 size_t expected_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001649 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminafc64de2016-07-19 17:12:41 +02001650 if (!ctx) {
1651 return false;
1652 }
1653 SSL_CTX_set_max_version(ctx.get(), version);
1654 // Our default cipher list varies by CPU capabilities, so manually place the
1655 // ChaCha20 ciphers in front.
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001656 if (!SSL_CTX_set_cipher_list(ctx.get(), "!RC4:CHACHA20:ALL")) {
David Benjaminafc64de2016-07-19 17:12:41 +02001657 return false;
1658 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001659 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +02001660 if (!ssl) {
1661 return false;
1662 }
1663 std::vector<uint8_t> client_hello;
1664 if (!GetClientHello(ssl.get(), &client_hello)) {
1665 return false;
1666 }
1667
1668 // Zero the client_random.
1669 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
1670 1 + 3 + // handshake message header
1671 2; // client_version
1672 if (client_hello.size() < kRandomOffset + SSL3_RANDOM_SIZE) {
1673 fprintf(stderr, "ClientHello for version %04x too short.\n", version);
1674 return false;
1675 }
1676 memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
1677
1678 if (client_hello.size() != expected_len ||
1679 memcmp(client_hello.data(), expected, expected_len) != 0) {
1680 fprintf(stderr, "ClientHello for version %04x did not match:\n", version);
1681 fprintf(stderr, "Got:\n\t");
1682 for (size_t i = 0; i < client_hello.size(); i++) {
1683 fprintf(stderr, "0x%02x, ", client_hello[i]);
1684 }
1685 fprintf(stderr, "\nWanted:\n\t");
1686 for (size_t i = 0; i < expected_len; i++) {
1687 fprintf(stderr, "0x%02x, ", expected[i]);
1688 }
1689 fprintf(stderr, "\n");
1690 return false;
1691 }
1692
1693 return true;
1694}
1695
1696// Tests that our ClientHellos do not change unexpectedly.
1697static bool TestClientHello() {
1698 static const uint8_t kSSL3ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001699 0x16,
1700 0x03, 0x00,
1701 0x00, 0x3f,
1702 0x01,
1703 0x00, 0x00, 0x3b,
1704 0x03, 0x00,
1705 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1706 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1707 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1708 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1709 0x00,
1710 0x00, 0x14,
1711 0xc0, 0x09,
1712 0xc0, 0x13,
1713 0x00, 0x33,
1714 0xc0, 0x0a,
1715 0xc0, 0x14,
1716 0x00, 0x39,
1717 0x00, 0x2f,
1718 0x00, 0x35,
1719 0x00, 0x0a,
1720 0x00, 0xff, 0x01, 0x00,
David Benjaminafc64de2016-07-19 17:12:41 +02001721 };
1722 if (!ClientHelloMatches(SSL3_VERSION, kSSL3ClientHello,
1723 sizeof(kSSL3ClientHello))) {
1724 return false;
1725 }
1726
1727 static const uint8_t kTLS1ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001728 0x16,
1729 0x03, 0x01,
1730 0x00, 0x5e,
1731 0x01,
1732 0x00, 0x00, 0x5a,
1733 0x03, 0x01,
1734 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1735 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1736 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1737 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1738 0x00,
1739 0x00, 0x12,
1740 0xc0, 0x09,
1741 0xc0, 0x13,
1742 0x00, 0x33,
1743 0xc0, 0x0a,
1744 0xc0, 0x14,
1745 0x00, 0x39,
1746 0x00, 0x2f,
1747 0x00, 0x35,
1748 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001749 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1750 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1751 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1752 };
1753 if (!ClientHelloMatches(TLS1_VERSION, kTLS1ClientHello,
1754 sizeof(kTLS1ClientHello))) {
1755 return false;
1756 }
1757
1758 static const uint8_t kTLS11ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001759 0x16,
1760 0x03, 0x01,
1761 0x00, 0x5e,
1762 0x01,
1763 0x00, 0x00, 0x5a,
1764 0x03, 0x02,
1765 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1766 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1767 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1768 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1769 0x00,
1770 0x00, 0x12,
1771 0xc0, 0x09,
1772 0xc0, 0x13,
1773 0x00, 0x33,
1774 0xc0, 0x0a,
1775 0xc0, 0x14,
1776 0x00, 0x39,
1777 0x00, 0x2f,
1778 0x00, 0x35,
1779 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001780 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1781 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1782 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1783 };
1784 if (!ClientHelloMatches(TLS1_1_VERSION, kTLS11ClientHello,
1785 sizeof(kTLS11ClientHello))) {
1786 return false;
1787 }
1788
1789 static const uint8_t kTLS12ClientHello[] = {
David Benjamin57e929f2016-08-30 00:30:38 -04001790 0x16, 0x03, 0x01, 0x00, 0xa2, 0x01, 0x00, 0x00, 0x9e, 0x03, 0x03, 0x00,
1791 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1792 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1793 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0xcc, 0xa9,
1794 0xcc, 0xa8, 0xcc, 0x14, 0xcc, 0x13, 0xc0, 0x2b, 0xc0, 0x2f, 0x00, 0x9e,
1795 0xc0, 0x2c, 0xc0, 0x30, 0x00, 0x9f, 0xc0, 0x09, 0xc0, 0x23, 0xc0, 0x13,
1796 0xc0, 0x27, 0x00, 0x33, 0x00, 0x67, 0xc0, 0x0a, 0xc0, 0x24, 0xc0, 0x14,
1797 0xc0, 0x28, 0x00, 0x39, 0x00, 0x6b, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
1798 0x00, 0x3c, 0x00, 0x35, 0x00, 0x3d, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x3b,
1799 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00,
1800 0x00, 0x00, 0x0d, 0x00, 0x18, 0x00, 0x16, 0x07, 0x02, 0x06, 0x01, 0x06,
1801 0x03, 0x07, 0x01, 0x05, 0x01, 0x05, 0x03, 0x07, 0x00, 0x04, 0x01, 0x04,
1802 0x03, 0x02, 0x01, 0x02, 0x03, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1803 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
David Benjaminafc64de2016-07-19 17:12:41 +02001804 };
1805 if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
1806 sizeof(kTLS12ClientHello))) {
1807 return false;
1808 }
1809
1810 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
1811 // implementation has settled enough that it won't change.
1812
1813 return true;
1814}
1815
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001816static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04001817
1818static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
1819 // Save the most recent session.
1820 g_last_session.reset(session);
1821 return 1;
1822}
1823
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001824static bssl::UniquePtr<SSL_SESSION> CreateClientSession(SSL_CTX *client_ctx,
David Benjamina20e5352016-08-02 19:09:41 -04001825 SSL_CTX *server_ctx) {
1826 g_last_session = nullptr;
1827 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
1828
1829 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001830 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001831 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
1832 nullptr /* no session */)) {
1833 fprintf(stderr, "Failed to connect client and server.\n");
1834 return nullptr;
1835 }
1836
1837 // Run the read loop to account for post-handshake tickets in TLS 1.3.
1838 SSL_read(client.get(), nullptr, 0);
1839
1840 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
1841
1842 if (!g_last_session) {
1843 fprintf(stderr, "Client did not receive a session.\n");
1844 return nullptr;
1845 }
1846 return std::move(g_last_session);
1847}
1848
1849static bool ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1850 SSL_SESSION *session,
1851 bool reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001852 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001853 if (!ConnectClientAndServer(&client, &server, client_ctx,
1854 server_ctx, session)) {
1855 fprintf(stderr, "Failed to connect client and server.\n");
1856 return false;
1857 }
1858
1859 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
1860 fprintf(stderr, "Client and server were inconsistent.\n");
1861 return false;
1862 }
1863
1864 bool was_reused = !!SSL_session_reused(client.get());
1865 if (was_reused != reused) {
1866 fprintf(stderr, "Session was%s reused, but we expected the opposite.\n",
1867 was_reused ? "" : " not");
1868 return false;
1869 }
1870
1871 return true;
1872}
1873
1874static bool TestSessionIDContext() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001875 bssl::UniquePtr<X509> cert = GetTestCertificate();
1876 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamina20e5352016-08-02 19:09:41 -04001877 if (!cert || !key) {
1878 return false;
1879 }
1880
1881 static const uint8_t kContext1[] = {1};
1882 static const uint8_t kContext2[] = {2};
1883
1884 for (uint16_t version : kVersions) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001885 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
1886 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamina20e5352016-08-02 19:09:41 -04001887 if (!server_ctx || !client_ctx ||
1888 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1889 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
1890 !SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
1891 sizeof(kContext1))) {
1892 return false;
1893 }
1894
1895 SSL_CTX_set_min_version(client_ctx.get(), version);
1896 SSL_CTX_set_max_version(client_ctx.get(), version);
1897 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
1898
1899 SSL_CTX_set_min_version(server_ctx.get(), version);
1900 SSL_CTX_set_max_version(server_ctx.get(), version);
1901 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
1902
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001903 bssl::UniquePtr<SSL_SESSION> session =
David Benjamina20e5352016-08-02 19:09:41 -04001904 CreateClientSession(client_ctx.get(), server_ctx.get());
1905 if (!session) {
1906 fprintf(stderr, "Error getting session (version = %04x).\n", version);
1907 return false;
1908 }
1909
1910 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1911 true /* expect session reused */)) {
1912 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
1913 return false;
1914 }
1915
1916 // Change the session ID context.
1917 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext2,
1918 sizeof(kContext2))) {
1919 return false;
1920 }
1921
1922 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1923 false /* expect session not reused */)) {
1924 fprintf(stderr,
1925 "Error connection with different context (version = %04x).\n",
1926 version);
1927 return false;
1928 }
1929 }
1930
1931 return true;
1932}
1933
David Benjamin721e8b72016-08-03 13:13:17 -04001934static timeval g_current_time;
1935
1936static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
1937 *out_clock = g_current_time;
1938}
1939
1940static bool TestSessionTimeout() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001941 bssl::UniquePtr<X509> cert = GetTestCertificate();
1942 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin721e8b72016-08-03 13:13:17 -04001943 if (!cert || !key) {
1944 return false;
1945 }
1946
1947 for (uint16_t version : kVersions) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001948 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
1949 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin721e8b72016-08-03 13:13:17 -04001950 if (!server_ctx || !client_ctx ||
1951 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1952 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1953 return false;
1954 }
1955
1956 SSL_CTX_set_min_version(client_ctx.get(), version);
1957 SSL_CTX_set_max_version(client_ctx.get(), version);
1958 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
1959
1960 SSL_CTX_set_min_version(server_ctx.get(), version);
1961 SSL_CTX_set_max_version(server_ctx.get(), version);
1962 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
1963 SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
1964
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001965 bssl::UniquePtr<SSL_SESSION> session =
David Benjamin721e8b72016-08-03 13:13:17 -04001966 CreateClientSession(client_ctx.get(), server_ctx.get());
1967 if (!session) {
1968 fprintf(stderr, "Error getting session (version = %04x).\n", version);
1969 return false;
1970 }
1971
1972 // Advance the clock just behind the timeout.
1973 g_current_time.tv_sec += SSL_DEFAULT_SESSION_TIMEOUT;
1974
1975 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1976 true /* expect session reused */)) {
1977 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
1978 return false;
1979 }
1980
1981 // Advance the clock one more second.
1982 g_current_time.tv_sec++;
1983
1984 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1985 false /* expect session not reused */)) {
1986 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
1987 return false;
1988 }
1989 }
1990
1991 return true;
1992}
1993
David Benjamin0fc37ef2016-08-17 15:29:46 -04001994static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
1995 SSL_CTX *ctx = reinterpret_cast<SSL_CTX*>(arg);
1996 SSL_set_SSL_CTX(ssl, ctx);
1997 return SSL_TLSEXT_ERR_OK;
1998}
1999
2000static bool TestSNICallback() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002001 bssl::UniquePtr<X509> cert = GetTestCertificate();
2002 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2003 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
2004 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
David Benjamin0fc37ef2016-08-17 15:29:46 -04002005 if (!cert || !key || !cert2 || !key2) {
2006 return false;
2007 }
2008
2009 // At each version, test that switching the |SSL_CTX| at the SNI callback
2010 // behaves correctly.
2011 for (uint16_t version : kVersions) {
2012 if (version == SSL3_VERSION) {
2013 continue;
2014 }
2015
2016 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
2017
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002018 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2019 bssl::UniquePtr<SSL_CTX> server_ctx2(SSL_CTX_new(TLS_method()));
2020 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002021 if (!server_ctx || !server_ctx2 || !client_ctx ||
2022 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2023 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2024 !SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()) ||
2025 !SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()) ||
2026 // Historically signing preferences would be lost in some cases with the
2027 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2028 // this doesn't happen when |version| is TLS 1.2, configure the private
2029 // key to only sign SHA-256.
2030 !SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
2031 &kECDSAWithSHA256, 1)) {
2032 return false;
2033 }
2034
2035 SSL_CTX_set_min_version(client_ctx.get(), version);
2036 SSL_CTX_set_max_version(client_ctx.get(), version);
2037 SSL_CTX_set_min_version(server_ctx.get(), version);
2038 SSL_CTX_set_max_version(server_ctx.get(), version);
2039 SSL_CTX_set_min_version(server_ctx2.get(), version);
2040 SSL_CTX_set_max_version(server_ctx2.get(), version);
2041
2042 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), SwitchContext);
2043 SSL_CTX_set_tlsext_servername_arg(server_ctx.get(), server_ctx2.get());
2044
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002045 bssl::UniquePtr<SSL> client, server;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002046 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2047 server_ctx.get(), nullptr)) {
2048 fprintf(stderr, "Handshake failed at version %04x.\n", version);
2049 return false;
2050 }
2051
2052 // The client should have received |cert2|.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002053 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client.get()));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002054 if (!peer ||
2055 X509_cmp(peer.get(), cert2.get()) != 0) {
2056 fprintf(stderr, "Incorrect certificate received at version %04x.\n",
2057 version);
2058 return false;
2059 }
2060 }
2061
2062 return true;
2063}
2064
David Benjamin99620572016-08-30 00:35:36 -04002065static int SetMaxVersion(const struct ssl_early_callback_ctx *ctx) {
2066 SSL_set_max_version(ctx->ssl, TLS1_2_VERSION);
2067 return 1;
2068}
2069
2070// TestEarlyCallbackVersionSwitch tests that the early callback can swap the
2071// maximum version.
2072static bool TestEarlyCallbackVersionSwitch() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002073 bssl::UniquePtr<X509> cert = GetTestCertificate();
2074 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2075 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2076 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin99620572016-08-30 00:35:36 -04002077 if (!cert || !key || !server_ctx || !client_ctx ||
2078 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2079 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
2080 return false;
2081 }
2082
2083 SSL_CTX_set_max_version(client_ctx.get(), TLS1_3_VERSION);
2084 SSL_CTX_set_max_version(server_ctx.get(), TLS1_3_VERSION);
2085
2086 SSL_CTX_set_select_certificate_cb(server_ctx.get(), SetMaxVersion);
2087
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002088 bssl::UniquePtr<SSL> client, server;
David Benjamin99620572016-08-30 00:35:36 -04002089 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2090 server_ctx.get(), nullptr)) {
2091 return false;
2092 }
2093
2094 if (SSL_version(client.get()) != TLS1_2_VERSION) {
2095 fprintf(stderr, "Early callback failed to switch the maximum version.\n");
2096 return false;
2097 }
2098
2099 return true;
2100}
2101
David Benjamin1d128f32015-09-08 17:41:40 -04002102int main() {
David Benjamin7a1eefd2015-10-17 23:39:22 -04002103 CRYPTO_library_init();
David Benjaminbb0a17c2014-09-20 15:35:39 -04002104
Adam Langley10f97f32016-07-12 08:09:33 -07002105 if (!TestCipherRules() ||
2106 !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
2107 !TestSSL_SESSIONEncoding(kCustomSession) ||
2108 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
2109 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
2110 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
2111 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
David Benjamin10e664b2016-06-20 22:20:47 -04002112 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
Adam Langley10f97f32016-07-12 08:09:33 -07002113 !TestDefaultVersion(SSL3_VERSION, TLS1_2_VERSION, &TLS_method) ||
2114 !TestDefaultVersion(SSL3_VERSION, SSL3_VERSION, &SSLv3_method) ||
2115 !TestDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method) ||
2116 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method) ||
2117 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method) ||
2118 !TestDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method) ||
2119 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method) ||
2120 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method) ||
2121 !TestCipherGetRFCName() ||
2122 !TestPaddingExtension() ||
2123 !TestClientCAList() ||
2124 !TestInternalSessionCache() ||
2125 !TestSequenceNumber(false /* TLS */) ||
2126 !TestSequenceNumber(true /* DTLS */) ||
2127 !TestOneSidedShutdown() ||
Steven Valdez87eab492016-06-27 16:34:59 -04002128 !TestSessionDuplication() ||
David Benjamin25490f22016-07-14 00:22:54 -04002129 !TestSetFD() ||
David Benjamin4501bd52016-08-01 13:39:41 -04002130 !TestSetBIO() ||
David Benjaminadd5e522016-07-14 00:33:24 -04002131 !TestGetPeerCertificate() ||
David Benjaminafc64de2016-07-19 17:12:41 +02002132 !TestRetainOnlySHA256OfCerts() ||
David Benjamina20e5352016-08-02 19:09:41 -04002133 !TestClientHello() ||
David Benjamin721e8b72016-08-03 13:13:17 -04002134 !TestSessionIDContext() ||
David Benjamin0fc37ef2016-08-17 15:29:46 -04002135 !TestSessionTimeout() ||
David Benjamin99620572016-08-30 00:35:36 -04002136 !TestSNICallback() ||
2137 !TestEarlyCallbackVersionSwitch()) {
Brian Smith83a82982015-04-09 16:21:10 -10002138 ERR_print_errors_fp(stderr);
David Benjaminbb0a17c2014-09-20 15:35:39 -04002139 return 1;
2140 }
2141
David Benjamin2e521212014-07-16 14:37:51 -04002142 printf("PASS\n");
2143 return 0;
2144}