blob: f6d173259e61c622c7ce3363aa6aca5a5da8163d [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
Alessandro Ghedini5fd18072016-09-28 21:04:25 +010059struct CurveTest {
60 // The rule string to apply.
61 const char *rule;
62 // The list of expected curves, in order.
63 std::vector<uint16_t> expected;
64};
65
David Benjaminfb974e62015-12-16 19:34:22 -050066static const CipherTest kCipherTests[] = {
67 // Selecting individual ciphers should work.
68 {
69 "ECDHE-ECDSA-CHACHA20-POLY1305:"
70 "ECDHE-RSA-CHACHA20-POLY1305:"
71 "ECDHE-ECDSA-AES128-GCM-SHA256:"
72 "ECDHE-RSA-AES128-GCM-SHA256",
73 {
74 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
75 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
76 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
77 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
78 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
79 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
80 },
81 },
82 // + reorders selected ciphers to the end, keeping their relative order.
83 {
84 "ECDHE-ECDSA-CHACHA20-POLY1305:"
85 "ECDHE-RSA-CHACHA20-POLY1305:"
86 "ECDHE-ECDSA-AES128-GCM-SHA256:"
87 "ECDHE-RSA-AES128-GCM-SHA256:"
88 "+aRSA",
89 {
90 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
91 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
92 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
93 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
94 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
95 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
96 },
97 },
98 // ! banishes ciphers from future selections.
99 {
100 "!aRSA:"
101 "ECDHE-ECDSA-CHACHA20-POLY1305:"
102 "ECDHE-RSA-CHACHA20-POLY1305:"
103 "ECDHE-ECDSA-AES128-GCM-SHA256:"
104 "ECDHE-RSA-AES128-GCM-SHA256",
105 {
106 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
107 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
108 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
109 },
110 },
111 // Multiple masks can be ANDed in a single rule.
112 {
113 "kRSA+AESGCM+AES128",
114 {
115 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
116 },
117 },
118 // - removes selected ciphers, but preserves their order for future
119 // selections. Select AES_128_GCM, but order the key exchanges RSA, DHE_RSA,
120 // ECDHE_RSA.
121 {
122 "ALL:-kECDHE:-kDHE:-kRSA:-ALL:"
123 "AESGCM+AES128+aRSA",
124 {
125 {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
126 {TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, 0},
127 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
128 },
129 },
130 // Unknown selectors are no-ops.
131 {
132 "ECDHE-ECDSA-CHACHA20-POLY1305:"
133 "ECDHE-RSA-CHACHA20-POLY1305:"
134 "ECDHE-ECDSA-AES128-GCM-SHA256:"
135 "ECDHE-RSA-AES128-GCM-SHA256:"
136 "BOGUS1:-BOGUS2:+BOGUS3:!BOGUS4",
137 {
138 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
139 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
140 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
141 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
142 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
143 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
144 },
145 },
146 // Square brackets specify equi-preference groups.
147 {
148 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
149 "[ECDHE-RSA-CHACHA20-POLY1305]:"
150 "ECDHE-RSA-AES128-GCM-SHA256",
151 {
152 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
153 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 1},
154 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
155 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 1},
156 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
157 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
158 },
159 },
160 // @STRENGTH performs a stable strength-sort of the selected ciphers and
161 // only the selected ciphers.
162 {
163 // To simplify things, banish all but {ECDHE_RSA,RSA} x
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700164 // {CHACHA20,AES_256_CBC,AES_128_CBC} x SHA1.
David Benjaminfb974e62015-12-16 19:34:22 -0500165 "!kEDH:!AESGCM:!3DES:!SHA256:!MD5:!SHA384:"
166 // Order some ciphers backwards by strength.
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -0700167 "ALL:-CHACHA20:-AES256:-AES128:-ALL:"
David Benjaminfb974e62015-12-16 19:34:22 -0500168 // Select ECDHE ones and sort them by strength. Ties should resolve
169 // based on the order above.
170 "kECDHE:@STRENGTH:-ALL:"
171 // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
172 // by strength. Then RSA, backwards by strength.
173 "aRSA",
174 {
175 {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
176 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
177 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500178 {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
David Benjaminfb974e62015-12-16 19:34:22 -0500179 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
180 {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
181 },
182 },
183 // Exact ciphers may not be used in multi-part rules; they are treated
184 // as unknown aliases.
185 {
186 "ECDHE-ECDSA-AES128-GCM-SHA256:"
187 "ECDHE-RSA-AES128-GCM-SHA256:"
188 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
189 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
190 {
191 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
192 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
193 },
194 },
195 // SSLv3 matches everything that existed before TLS 1.2.
196 {
197 "AES128-SHA:AES128-SHA256:!SSLv3",
198 {
199 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
200 },
201 },
202 // TLSv1.2 matches everything added in TLS 1.2.
203 {
204 "AES128-SHA:AES128-SHA256:!TLSv1.2",
205 {
206 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
207 },
208 },
209 // The two directives have no intersection.
210 {
211 "AES128-SHA:AES128-SHA256:!TLSv1.2+SSLv3",
212 {
213 {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
214 {TLS1_CK_RSA_WITH_AES_128_SHA256, 0},
215 },
216 },
217 // The shared name of the CHACHA20_POLY1305 variants behaves like a cipher
218 // name and not an alias. It may not be used in a multipart rule. (That the
219 // shared name works is covered by the standard tests.)
220 {
221 "ECDHE-ECDSA-CHACHA20-POLY1305:"
222 "ECDHE-RSA-CHACHA20-POLY1305:"
223 "!ECDHE-RSA-CHACHA20-POLY1305+RSA:"
224 "!ECDSA+ECDHE-ECDSA-CHACHA20-POLY1305",
225 {
226 {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
227 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0},
228 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
229 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0},
230 },
231 },
David Benjaminbb0a17c2014-09-20 15:35:39 -0400232};
233
234static const char *kBadRules[] = {
David Benjamin1d77e562015-03-22 17:22:08 -0400235 // Invalid brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400236 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
237 "RSA]",
238 "[[RSA]]",
David Benjamin1d77e562015-03-22 17:22:08 -0400239 // Operators inside brackets.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400240 "[+RSA]",
David Benjamin1d77e562015-03-22 17:22:08 -0400241 // Unknown directive.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400242 "@BOGUS",
David Benjamin1d77e562015-03-22 17:22:08 -0400243 // Empty cipher lists error at SSL_CTX_set_cipher_list.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400244 "",
245 "BOGUS",
David Benjamin32fbdf22015-04-07 01:14:06 -0400246 // COMPLEMENTOFDEFAULT is empty.
247 "COMPLEMENTOFDEFAULT",
David Benjamin1d77e562015-03-22 17:22:08 -0400248 // Invalid command.
David Benjaminbb0a17c2014-09-20 15:35:39 -0400249 "?BAR",
David Benjamin1d77e562015-03-22 17:22:08 -0400250 // Special operators are not allowed if groups are used.
David Benjamin37d92462014-09-20 17:54:24 -0400251 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
252 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
253 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
254 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
Adam Langleyf99f2442016-10-02 09:53:38 -0700255 // Opcode supplied, but missing selector.
256 "+",
David Benjaminbb0a17c2014-09-20 15:35:39 -0400257};
258
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700259static const char *kMustNotIncludeNull[] = {
260 "ALL",
261 "DEFAULT",
262 "ALL:!eNULL",
263 "ALL:!NULL",
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 Braithwaite053931e2016-05-25 12:06:05 -0700277 "HIGH",
278 "FIPS",
279 "SHA",
280 "SHA1",
281 "SHA256",
282 "SHA384",
283 "RSA",
284 "SSLv3",
285 "TLSv1",
286 "TLSv1.2",
287 "aRSA",
288 "RSA",
289 "aECDSA",
290 "ECDSA",
291 "AES",
292 "AES128",
293 "AES256",
294 "AESGCM",
295 "CHACHA20",
296};
297
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100298static const CurveTest kCurveTests[] = {
299 {
300 "P-256",
301 { SSL_CURVE_SECP256R1 },
302 },
303 {
304 "P-256:P-384:P-521:X25519",
305 {
306 SSL_CURVE_SECP256R1,
307 SSL_CURVE_SECP384R1,
308 SSL_CURVE_SECP521R1,
309 SSL_CURVE_X25519,
310 },
311 },
312};
313
314static const char *kBadCurvesLists[] = {
315 "",
316 ":",
317 "::",
318 "P-256::X25519",
319 "RSA:P-256",
320 "P-256:RSA",
321 "X25519:P-256:",
322 ":X25519:P-256",
323};
324
David Benjamin1d77e562015-03-22 17:22:08 -0400325static void PrintCipherPreferenceList(ssl_cipher_preference_list_st *list) {
326 bool in_group = false;
327 for (size_t i = 0; i < sk_SSL_CIPHER_num(list->ciphers); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400328 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(list->ciphers, i);
329 if (!in_group && list->in_group_flags[i]) {
330 fprintf(stderr, "\t[\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400331 in_group = true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400332 }
333 fprintf(stderr, "\t");
334 if (in_group) {
335 fprintf(stderr, " ");
336 }
337 fprintf(stderr, "%s\n", SSL_CIPHER_get_name(cipher));
338 if (in_group && !list->in_group_flags[i]) {
339 fprintf(stderr, "\t]\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400340 in_group = false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400341 }
342 }
343}
344
David Benjaminfb974e62015-12-16 19:34:22 -0500345static bool TestCipherRule(const CipherTest &t) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700346 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400347 if (!ctx) {
348 return false;
David Benjamin65226252015-02-05 16:49:47 -0500349 }
350
David Benjaminfb974e62015-12-16 19:34:22 -0500351 if (!SSL_CTX_set_cipher_list(ctx.get(), t.rule)) {
352 fprintf(stderr, "Error testing cipher rule '%s'\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400353 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400354 }
355
David Benjamin1d77e562015-03-22 17:22:08 -0400356 // Compare the two lists.
David Benjaminfb974e62015-12-16 19:34:22 -0500357 if (sk_SSL_CIPHER_num(ctx->cipher_list->ciphers) != t.expected.size()) {
358 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
359 PrintCipherPreferenceList(ctx->cipher_list);
360 return false;
361 }
362
363 for (size_t i = 0; i < t.expected.size(); i++) {
David Benjaminbb0a17c2014-09-20 15:35:39 -0400364 const SSL_CIPHER *cipher =
365 sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i);
David Benjaminfb974e62015-12-16 19:34:22 -0500366 if (t.expected[i].id != SSL_CIPHER_get_id(cipher) ||
367 t.expected[i].in_group_flag != ctx->cipher_list->in_group_flags[i]) {
368 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t.rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400369 PrintCipherPreferenceList(ctx->cipher_list);
370 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400371 }
372 }
373
David Benjamin1d77e562015-03-22 17:22:08 -0400374 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400375}
376
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700377static bool TestRuleDoesNotIncludeNull(const char *rule) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700378 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700379 if (!ctx) {
380 return false;
381 }
382 if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
383 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
384 return false;
385 }
386 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
387 if (SSL_CIPHER_is_NULL(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
388 fprintf(stderr, "Error: cipher rule '%s' includes NULL\n",rule);
389 return false;
390 }
391 }
392 return true;
393}
394
Matt Braithwaite053931e2016-05-25 12:06:05 -0700395static bool TestRuleDoesNotIncludeCECPQ1(const char *rule) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700396 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
Matt Braithwaite053931e2016-05-25 12:06:05 -0700397 if (!ctx) {
398 return false;
399 }
400 if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
401 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
402 return false;
403 }
404 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
405 if (SSL_CIPHER_is_CECPQ1(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
406 fprintf(stderr, "Error: cipher rule '%s' includes CECPQ1\n",rule);
407 return false;
408 }
409 }
410 return true;
411}
412
David Benjamin1d77e562015-03-22 17:22:08 -0400413static bool TestCipherRules() {
David Benjaminfb974e62015-12-16 19:34:22 -0500414 for (const CipherTest &test : kCipherTests) {
415 if (!TestCipherRule(test)) {
David Benjamin1d77e562015-03-22 17:22:08 -0400416 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400417 }
418 }
419
David Benjaminfb974e62015-12-16 19:34:22 -0500420 for (const char *rule : kBadRules) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700421 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400422 if (!ctx) {
423 return false;
David Benjamin65226252015-02-05 16:49:47 -0500424 }
David Benjaminfb974e62015-12-16 19:34:22 -0500425 if (SSL_CTX_set_cipher_list(ctx.get(), rule)) {
426 fprintf(stderr, "Cipher rule '%s' unexpectedly succeeded\n", rule);
David Benjamin1d77e562015-03-22 17:22:08 -0400427 return false;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400428 }
429 ERR_clear_error();
David Benjaminbb0a17c2014-09-20 15:35:39 -0400430 }
431
David Benjaminfb974e62015-12-16 19:34:22 -0500432 for (const char *rule : kMustNotIncludeNull) {
433 if (!TestRuleDoesNotIncludeNull(rule)) {
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700434 return false;
435 }
436 }
437
Matt Braithwaite053931e2016-05-25 12:06:05 -0700438 for (const char *rule : kMustNotIncludeCECPQ1) {
439 if (!TestRuleDoesNotIncludeCECPQ1(rule)) {
440 return false;
441 }
442 }
443
David Benjamin1d77e562015-03-22 17:22:08 -0400444 return true;
David Benjaminbb0a17c2014-09-20 15:35:39 -0400445}
David Benjamin2e521212014-07-16 14:37:51 -0400446
Alessandro Ghedini5fd18072016-09-28 21:04:25 +0100447static bool TestCurveRule(const CurveTest &t) {
448 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
449 if (!ctx) {
450 return false;
451 }
452
453 if (!SSL_CTX_set1_curves_list(ctx.get(), t.rule)) {
454 fprintf(stderr, "Error testing curves list '%s'\n", t.rule);
455 return false;
456 }
457
458 // Compare the two lists.
459 if (ctx->supported_group_list_len != t.expected.size()) {
460 fprintf(stderr, "Error testing curves list '%s': length\n", t.rule);
461 return false;
462 }
463
464 for (size_t i = 0; i < t.expected.size(); i++) {
465 if (t.expected[i] != ctx->supported_group_list[i]) {
466 fprintf(stderr, "Error testing curves list '%s': mismatch\n", t.rule);
467 return false;
468 }
469 }
470
471 return true;
472}
473
474static bool TestCurveRules() {
475 for (const CurveTest &test : kCurveTests) {
476 if (!TestCurveRule(test)) {
477 return false;
478 }
479 }
480
481 for (const char *rule : kBadCurvesLists) {
482 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(SSLv23_server_method()));
483 if (!ctx) {
484 return false;
485 }
486 if (SSL_CTX_set1_curves_list(ctx.get(), rule)) {
487 fprintf(stderr, "Curves list '%s' unexpectedly succeeded\n", rule);
488 return false;
489 }
490 ERR_clear_error();
491 }
492
493 return true;
494}
495
Adam Langley10f97f32016-07-12 08:09:33 -0700496// kOpenSSLSession is a serialized SSL_SESSION generated from openssl
497// s_client -sess_out.
498static const char kOpenSSLSession[] =
499 "MIIFpQIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
500 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
501 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
502 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
503 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
504 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
505 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
506 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
507 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
508 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
509 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
510 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
511 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
512 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
513 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
514 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
515 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
516 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
517 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
518 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
519 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
520 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
521 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
522 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
523 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
524 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
525 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
526 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
527 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
528 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
529 "i4gv7Y5oliyn";
530
531// kCustomSession is a custom serialized SSL_SESSION generated by
532// filling in missing fields from |kOpenSSLSession|. This includes
533// providing |peer_sha256|, so |peer| is not serialized.
534static const char kCustomSession[] =
535 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
536 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
537 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
538 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
539 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
540 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
541 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
542 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
543
544// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
545static const char kBoringSSLSession[] =
546 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
547 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
548 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
549 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
550 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
551 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
552 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
553 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
554 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
555 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
556 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
557 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
558 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
559 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
560 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
561 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
562 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
563 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
564 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
565 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
566 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
567 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
568 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
569 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
570 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
571 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
572 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
573 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
574 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
575 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
576 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
577 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
578 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
579 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
580 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
581 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
582 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
583 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
584 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
585 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
586 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
587 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
588 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
589 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
590 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
591 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
592 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
593 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
594 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
595 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
596 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
597 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
598 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
599 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
600 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
601 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
602 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
603 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
604 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
605 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
606 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
607 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
608 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
609 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
610 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
611 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
612 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
613 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
614 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
615 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
616 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
617 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
618 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
619 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
620 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
621 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
622 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
623 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
624 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
625 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
626 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
627 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
628 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
629 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
630 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
631 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
632 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
633 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
634 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
635 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
636 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
637 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
638 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
639 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
640 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
641
642// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
643// the final (optional) element of |kCustomSession| with tag number 30.
644static const char kBadSessionExtraField[] =
645 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
646 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
647 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
648 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
649 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
650 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
651 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
652 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
653
654// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
655// the version of |kCustomSession| with 2.
656static const char kBadSessionVersion[] =
657 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
658 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
659 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
660 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
661 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
662 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
663 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
664 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
665
666// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
667// appended.
668static const char kBadSessionTrailingData[] =
669 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
670 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
671 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
672 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
673 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
674 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
675 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
676 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
677
David Benjamin1d77e562015-03-22 17:22:08 -0400678static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
David Benjamin751e8892014-10-19 00:59:36 -0400679 size_t len;
David Benjamin751e8892014-10-19 00:59:36 -0400680 if (!EVP_DecodedLength(&len, strlen(in))) {
681 fprintf(stderr, "EVP_DecodedLength failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400682 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400683 }
684
David Benjamin1d77e562015-03-22 17:22:08 -0400685 out->resize(len);
David Benjaminef14b2d2015-11-11 14:01:27 -0800686 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
David Benjamin751e8892014-10-19 00:59:36 -0400687 strlen(in))) {
688 fprintf(stderr, "EVP_DecodeBase64 failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400689 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400690 }
David Benjamin1d77e562015-03-22 17:22:08 -0400691 out->resize(len);
692 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400693}
694
David Benjamin1d77e562015-03-22 17:22:08 -0400695static bool TestSSL_SESSIONEncoding(const char *input_b64) {
David Benjamin751e8892014-10-19 00:59:36 -0400696 const uint8_t *cptr;
697 uint8_t *ptr;
David Benjamin751e8892014-10-19 00:59:36 -0400698
David Benjamin1d77e562015-03-22 17:22:08 -0400699 // Decode the input.
700 std::vector<uint8_t> input;
701 if (!DecodeBase64(&input, input_b64)) {
702 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400703 }
704
David Benjamin1d77e562015-03-22 17:22:08 -0400705 // Verify the SSL_SESSION decodes.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700706 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminfd67aa82015-06-15 19:41:48 -0400707 if (!session) {
708 fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400709 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400710 }
711
David Benjamin1d77e562015-03-22 17:22:08 -0400712 // Verify the SSL_SESSION encoding round-trips.
713 size_t encoded_len;
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700714 bssl::UniquePtr<uint8_t> encoded;
David Benjamin1d77e562015-03-22 17:22:08 -0400715 uint8_t *encoded_raw;
716 if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
David Benjamin3cac4502014-10-21 01:46:30 -0400717 fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400718 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400719 }
David Benjamin1d77e562015-03-22 17:22:08 -0400720 encoded.reset(encoded_raw);
721 if (encoded_len != input.size() ||
David Benjaminef14b2d2015-11-11 14:01:27 -0800722 memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin3cac4502014-10-21 01:46:30 -0400723 fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
Sigbjorn Vik2b23d242015-06-29 15:07:26 +0200724 hexdump(stderr, "Before: ", input.data(), input.size());
725 hexdump(stderr, "After: ", encoded_raw, encoded_len);
David Benjamin1d77e562015-03-22 17:22:08 -0400726 return false;
David Benjamin3cac4502014-10-21 01:46:30 -0400727 }
David Benjamin3cac4502014-10-21 01:46:30 -0400728
David Benjaminfd67aa82015-06-15 19:41:48 -0400729 // Verify the SSL_SESSION also decodes with the legacy API.
David Benjaminef14b2d2015-11-11 14:01:27 -0800730 cptr = input.data();
David Benjaminfd67aa82015-06-15 19:41:48 -0400731 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
David Benjaminef14b2d2015-11-11 14:01:27 -0800732 if (!session || cptr != input.data() + input.size()) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400733 fprintf(stderr, "d2i_SSL_SESSION failed\n");
734 return false;
735 }
736
David Benjamin1d77e562015-03-22 17:22:08 -0400737 // Verify the SSL_SESSION encoding round-trips via the legacy API.
738 int len = i2d_SSL_SESSION(session.get(), NULL);
739 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400740 fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400741 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400742 }
743
David Benjamin1d77e562015-03-22 17:22:08 -0400744 encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
745 if (!encoded) {
David Benjamin751e8892014-10-19 00:59:36 -0400746 fprintf(stderr, "malloc failed\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400747 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400748 }
David Benjamin1d77e562015-03-22 17:22:08 -0400749
750 ptr = encoded.get();
751 len = i2d_SSL_SESSION(session.get(), &ptr);
752 if (len < 0 || (size_t)len != input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400753 fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400754 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400755 }
David Benjamin1d77e562015-03-22 17:22:08 -0400756 if (ptr != encoded.get() + input.size()) {
David Benjamin751e8892014-10-19 00:59:36 -0400757 fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400758 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400759 }
David Benjaminef14b2d2015-11-11 14:01:27 -0800760 if (memcmp(input.data(), encoded.get(), input.size()) != 0) {
David Benjamin751e8892014-10-19 00:59:36 -0400761 fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n");
David Benjamin1d77e562015-03-22 17:22:08 -0400762 return false;
David Benjamin751e8892014-10-19 00:59:36 -0400763 }
764
David Benjamin1d77e562015-03-22 17:22:08 -0400765 return true;
David Benjamin751e8892014-10-19 00:59:36 -0400766}
767
David Benjaminf297e022015-05-28 19:55:29 -0400768static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
769 std::vector<uint8_t> input;
770 if (!DecodeBase64(&input, input_b64)) {
771 return false;
772 }
773
774 // Verify that the SSL_SESSION fails to decode.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700775 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(input.data(), input.size()));
David Benjaminf297e022015-05-28 19:55:29 -0400776 if (session) {
David Benjaminfd67aa82015-06-15 19:41:48 -0400777 fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
David Benjaminf297e022015-05-28 19:55:29 -0400778 return false;
779 }
780 ERR_clear_error();
781 return true;
782}
783
David Benjamin10e664b2016-06-20 22:20:47 -0400784static bool TestDefaultVersion(uint16_t min_version, uint16_t max_version,
David Benjamin1d77e562015-03-22 17:22:08 -0400785 const SSL_METHOD *(*method)(void)) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700786 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
David Benjamin1d77e562015-03-22 17:22:08 -0400787 if (!ctx) {
788 return false;
David Benjamin82c9e902014-12-12 15:55:27 -0500789 }
David Benjaminb6a0a512016-06-21 10:33:21 -0400790 if (ctx->min_version != min_version || ctx->max_version != max_version) {
791 fprintf(stderr, "Got min %04x, max %04x; wanted min %04x, max %04x\n",
792 ctx->min_version, ctx->max_version, min_version, max_version);
793 return false;
794 }
795 return true;
David Benjamin82c9e902014-12-12 15:55:27 -0500796}
797
David Benjamin1d77e562015-03-22 17:22:08 -0400798static bool CipherGetRFCName(std::string *out, uint16_t value) {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500799 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(value);
800 if (cipher == NULL) {
David Benjamin1d77e562015-03-22 17:22:08 -0400801 return false;
David Benjamin65226252015-02-05 16:49:47 -0500802 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700803 bssl::UniquePtr<char> rfc_name(SSL_CIPHER_get_rfc_name(cipher));
David Benjamin3fa65f02015-05-15 19:11:57 -0400804 if (!rfc_name) {
805 return false;
806 }
David Benjamin67be0482015-04-20 16:19:00 -0400807 out->assign(rfc_name.get());
David Benjamin1d77e562015-03-22 17:22:08 -0400808 return true;
David Benjamin65226252015-02-05 16:49:47 -0500809}
810
811typedef struct {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500812 int id;
David Benjamin65226252015-02-05 16:49:47 -0500813 const char *rfc_name;
814} CIPHER_RFC_NAME_TEST;
815
816static const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = {
Steven Valdez803c77a2016-09-06 14:13:43 -0400817 {SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA"},
818 {TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA"},
819 {TLS1_CK_DHE_RSA_WITH_AES_256_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"},
820 {TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
821 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"},
822 {TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
823 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"},
824 {TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
825 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"},
826 {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
827 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"},
828 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
829 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"},
830 {TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
831 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"},
832 {TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
833 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA"},
834 {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
835 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"},
836 {TLS1_CK_AES_256_GCM_SHA384, "TLS_AES_256_GCM_SHA384"},
837 {TLS1_CK_AES_128_GCM_SHA256, "TLS_AES_128_GCM_SHA256"},
838 {TLS1_CK_CHACHA20_POLY1305_SHA256, "TLS_CHACHA20_POLY1305_SHA256"},
839
840 // These names are non-standard:
841 {TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD,
842 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"},
843 {TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD,
844 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"},
David Benjamin65226252015-02-05 16:49:47 -0500845};
846
David Benjamin1d77e562015-03-22 17:22:08 -0400847static bool TestCipherGetRFCName(void) {
848 for (size_t i = 0;
Steven Valdezcb966542016-08-17 16:56:14 -0400849 i < OPENSSL_ARRAY_SIZE(kCipherRFCNameTests); i++) {
David Benjamin65226252015-02-05 16:49:47 -0500850 const CIPHER_RFC_NAME_TEST *test = &kCipherRFCNameTests[i];
David Benjamin1d77e562015-03-22 17:22:08 -0400851 std::string rfc_name;
852 if (!CipherGetRFCName(&rfc_name, test->id & 0xffff)) {
853 fprintf(stderr, "SSL_CIPHER_get_rfc_name failed\n");
854 return false;
David Benjamin65226252015-02-05 16:49:47 -0500855 }
David Benjamin1d77e562015-03-22 17:22:08 -0400856 if (rfc_name != test->rfc_name) {
David Benjamin65226252015-02-05 16:49:47 -0500857 fprintf(stderr, "SSL_CIPHER_get_rfc_name: got '%s', wanted '%s'\n",
David Benjamin1d77e562015-03-22 17:22:08 -0400858 rfc_name.c_str(), test->rfc_name);
859 return false;
David Benjamin65226252015-02-05 16:49:47 -0500860 }
David Benjamin65226252015-02-05 16:49:47 -0500861 }
David Benjamin1d77e562015-03-22 17:22:08 -0400862 return true;
David Benjamin65226252015-02-05 16:49:47 -0500863}
864
David Benjamin422fe082015-07-21 22:03:43 -0400865// CreateSessionWithTicket returns a sample |SSL_SESSION| with the ticket
866// replaced for one of length |ticket_len| or nullptr on failure.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700867static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -0400868 std::vector<uint8_t> der;
869 if (!DecodeBase64(&der, kOpenSSLSession)) {
870 return nullptr;
871 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700872 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(der.data(), der.size()));
David Benjamin422fe082015-07-21 22:03:43 -0400873 if (!session) {
874 return nullptr;
875 }
876
877 // Swap out the ticket for a garbage one.
878 OPENSSL_free(session->tlsext_tick);
879 session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len));
880 if (session->tlsext_tick == nullptr) {
881 return nullptr;
882 }
883 memset(session->tlsext_tick, 'a', ticket_len);
884 session->tlsext_ticklen = ticket_len;
David Benjamin1269ddd2015-10-18 15:18:55 -0400885
886 // Fix up the timeout.
887 session->time = time(NULL);
David Benjamin422fe082015-07-21 22:03:43 -0400888 return session;
889}
890
David Benjaminafc64de2016-07-19 17:12:41 +0200891static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700892 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +0200893 if (!bio) {
894 return false;
895 }
896 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -0400897 BIO_up_ref(bio.get());
898 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +0200899 int ret = SSL_connect(ssl);
900 if (ret > 0) {
901 // SSL_connect should fail without a BIO to write to.
902 return false;
903 }
904 ERR_clear_error();
905
906 const uint8_t *client_hello;
907 size_t client_hello_len;
908 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
909 return false;
910 }
911 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
912 return true;
913}
914
David Benjamin422fe082015-07-21 22:03:43 -0400915// GetClientHelloLen creates a client SSL connection with a ticket of length
916// |ticket_len| and records the ClientHello. It returns the length of the
917// ClientHello, not including the record header, on success and zero on error.
918static size_t GetClientHelloLen(size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700919 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
920 bssl::UniquePtr<SSL_SESSION> session = CreateSessionWithTicket(ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -0400921 if (!ctx || !session) {
922 return 0;
923 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700924 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +0200925 if (!ssl || !SSL_set_session(ssl.get(), session.get())) {
David Benjamin422fe082015-07-21 22:03:43 -0400926 return 0;
927 }
David Benjaminafc64de2016-07-19 17:12:41 +0200928 std::vector<uint8_t> client_hello;
929 if (!GetClientHello(ssl.get(), &client_hello) ||
930 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -0400931 return 0;
932 }
David Benjaminafc64de2016-07-19 17:12:41 +0200933 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -0400934}
935
936struct PaddingTest {
937 size_t input_len, padded_len;
938};
939
940static const PaddingTest kPaddingTests[] = {
941 // ClientHellos of length below 0x100 do not require padding.
942 {0xfe, 0xfe},
943 {0xff, 0xff},
944 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
945 {0x100, 0x200},
946 {0x123, 0x200},
947 {0x1fb, 0x200},
948 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
949 // padding extension takes a minimum of four bytes plus one required content
950 // byte. (To work around yet more server bugs, we avoid empty final
951 // extensions.)
952 {0x1fc, 0x201},
953 {0x1fd, 0x202},
954 {0x1fe, 0x203},
955 {0x1ff, 0x204},
956 // Finally, larger ClientHellos need no padding.
957 {0x200, 0x200},
958 {0x201, 0x201},
959};
960
961static bool TestPaddingExtension() {
962 // Sample a baseline length.
963 size_t base_len = GetClientHelloLen(1);
964 if (base_len == 0) {
965 return false;
966 }
967
968 for (const PaddingTest &test : kPaddingTests) {
969 if (base_len > test.input_len) {
970 fprintf(stderr, "Baseline ClientHello too long.\n");
971 return false;
972 }
973
974 size_t padded_len = GetClientHelloLen(1 + test.input_len - base_len);
975 if (padded_len != test.padded_len) {
976 fprintf(stderr, "%u-byte ClientHello padded to %u bytes, not %u.\n",
977 static_cast<unsigned>(test.input_len),
978 static_cast<unsigned>(padded_len),
979 static_cast<unsigned>(test.padded_len));
980 return false;
981 }
982 }
983 return true;
984}
985
David Benjamin1d128f32015-09-08 17:41:40 -0400986// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
987// before configuring as a server.
988static bool TestClientCAList() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700989 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin1d128f32015-09-08 17:41:40 -0400990 if (!ctx) {
991 return false;
992 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700993 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjamin1d128f32015-09-08 17:41:40 -0400994 if (!ssl) {
995 return false;
996 }
997
998 STACK_OF(X509_NAME) *stack = sk_X509_NAME_new_null();
999 if (stack == nullptr) {
1000 return false;
1001 }
1002 // |SSL_set_client_CA_list| takes ownership.
1003 SSL_set_client_CA_list(ssl.get(), stack);
1004
1005 return SSL_get_client_CA_list(ssl.get()) == stack;
1006}
1007
David Benjamin0f653952015-10-18 14:28:01 -04001008static void AppendSession(SSL_SESSION *session, void *arg) {
1009 std::vector<SSL_SESSION*> *out =
1010 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
1011 out->push_back(session);
1012}
1013
1014// ExpectCache returns true if |ctx|'s session cache consists of |expected|, in
1015// order.
1016static bool ExpectCache(SSL_CTX *ctx,
1017 const std::vector<SSL_SESSION*> &expected) {
1018 // Check the linked list.
1019 SSL_SESSION *ptr = ctx->session_cache_head;
1020 for (SSL_SESSION *session : expected) {
1021 if (ptr != session) {
1022 return false;
1023 }
1024 // TODO(davidben): This is an absurd way to denote the end of the list.
1025 if (ptr->next ==
1026 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
1027 ptr = nullptr;
1028 } else {
1029 ptr = ptr->next;
1030 }
1031 }
1032 if (ptr != nullptr) {
1033 return false;
1034 }
1035
1036 // Check the hash table.
1037 std::vector<SSL_SESSION*> actual, expected_copy;
1038 lh_SSL_SESSION_doall_arg(SSL_CTX_sessions(ctx), AppendSession, &actual);
1039 expected_copy = expected;
1040
1041 std::sort(actual.begin(), actual.end());
1042 std::sort(expected_copy.begin(), expected_copy.end());
1043
1044 return actual == expected_copy;
1045}
1046
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001047static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
1048 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new());
David Benjamin0f653952015-10-18 14:28:01 -04001049 if (!ret) {
1050 return nullptr;
1051 }
1052
1053 ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
1054 memset(ret->session_id, 0, ret->session_id_length);
1055 memcpy(ret->session_id, &number, sizeof(number));
1056 return ret;
1057}
1058
David Benjamin0f653952015-10-18 14:28:01 -04001059// Test that the internal session cache behaves as expected.
1060static bool TestInternalSessionCache() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001061 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin0f653952015-10-18 14:28:01 -04001062 if (!ctx) {
1063 return false;
1064 }
1065
1066 // Prepare 10 test sessions.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001067 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
David Benjamin0f653952015-10-18 14:28:01 -04001068 for (int i = 0; i < 10; i++) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001069 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
David Benjamin0f653952015-10-18 14:28:01 -04001070 if (!session) {
1071 return false;
1072 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001073 sessions.push_back(std::move(session));
David Benjamin0f653952015-10-18 14:28:01 -04001074 }
1075
1076 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1077
1078 // Insert all the test sessions.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001079 for (const auto &session : sessions) {
1080 if (!SSL_CTX_add_session(ctx.get(), session.get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001081 return false;
1082 }
1083 }
1084
1085 // Only the last five should be in the list.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001086 std::vector<SSL_SESSION*> expected = {
1087 sessions[9].get(),
1088 sessions[8].get(),
1089 sessions[7].get(),
1090 sessions[6].get(),
1091 sessions[5].get(),
1092 };
David Benjamin0f653952015-10-18 14:28:01 -04001093 if (!ExpectCache(ctx.get(), expected)) {
1094 return false;
1095 }
1096
1097 // Inserting an element already in the cache should fail.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001098 if (SSL_CTX_add_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001099 !ExpectCache(ctx.get(), expected)) {
1100 return false;
1101 }
1102
1103 // Although collisions should be impossible (256-bit session IDs), the cache
1104 // must handle them gracefully.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001105 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
David Benjamin0f653952015-10-18 14:28:01 -04001106 if (!collision || !SSL_CTX_add_session(ctx.get(), collision.get())) {
1107 return false;
1108 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001109 expected = {
1110 collision.get(),
1111 sessions[9].get(),
1112 sessions[8].get(),
1113 sessions[6].get(),
1114 sessions[5].get(),
1115 };
David Benjamin0f653952015-10-18 14:28:01 -04001116 if (!ExpectCache(ctx.get(), expected)) {
1117 return false;
1118 }
1119
1120 // Removing sessions behaves correctly.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001121 if (!SSL_CTX_remove_session(ctx.get(), sessions[6].get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001122 return false;
1123 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001124 expected = {
1125 collision.get(),
1126 sessions[9].get(),
1127 sessions[8].get(),
1128 sessions[5].get(),
1129 };
David Benjamin0f653952015-10-18 14:28:01 -04001130 if (!ExpectCache(ctx.get(), expected)) {
1131 return false;
1132 }
1133
1134 // Removing sessions requires an exact match.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001135 if (SSL_CTX_remove_session(ctx.get(), sessions[0].get()) ||
1136 SSL_CTX_remove_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001137 !ExpectCache(ctx.get(), expected)) {
1138 return false;
1139 }
1140
1141 return true;
1142}
1143
David Benjaminde942382016-02-11 12:02:01 -05001144static uint16_t EpochFromSequence(uint64_t seq) {
1145 return static_cast<uint16_t>(seq >> 48);
1146}
1147
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001148static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001149 static const char kCertPEM[] =
1150 "-----BEGIN CERTIFICATE-----\n"
1151 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1152 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1153 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1154 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1155 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1156 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1157 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1158 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1159 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1160 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1161 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1162 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1163 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1164 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001165 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1166 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjaminde942382016-02-11 12:02:01 -05001167}
1168
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001169static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001170 static const char kKeyPEM[] =
1171 "-----BEGIN RSA PRIVATE KEY-----\n"
1172 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1173 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1174 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1175 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1176 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1177 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1178 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1179 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1180 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1181 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1182 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1183 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1184 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1185 "-----END RSA PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001186 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1187 return bssl::UniquePtr<EVP_PKEY>(
David Benjaminde942382016-02-11 12:02:01 -05001188 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1189}
1190
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001191static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001192 static const char kCertPEM[] =
1193 "-----BEGIN CERTIFICATE-----\n"
1194 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1195 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1196 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1197 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1198 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1199 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1200 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1201 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1202 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1203 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1204 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001205 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1206 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjamin0fc37ef2016-08-17 15:29:46 -04001207}
1208
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001209static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001210 static const char kKeyPEM[] =
1211 "-----BEGIN PRIVATE KEY-----\n"
1212 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1213 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1214 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1215 "-----END PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001216 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1217 return bssl::UniquePtr<EVP_PKEY>(
David Benjamin0fc37ef2016-08-17 15:29:46 -04001218 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1219}
1220
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001221static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001222 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1223 SSL_SESSION *session) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001224 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001225 if (!client || !server) {
1226 return false;
1227 }
1228 SSL_set_connect_state(client.get());
1229 SSL_set_accept_state(server.get());
1230
David Benjamina20e5352016-08-02 19:09:41 -04001231 SSL_set_session(client.get(), session);
1232
David Benjaminde942382016-02-11 12:02:01 -05001233 BIO *bio1, *bio2;
1234 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1235 return false;
1236 }
1237 // SSL_set_bio takes ownership.
1238 SSL_set_bio(client.get(), bio1, bio1);
1239 SSL_set_bio(server.get(), bio2, bio2);
1240
1241 // Drive both their handshakes to completion.
1242 for (;;) {
1243 int client_ret = SSL_do_handshake(client.get());
1244 int client_err = SSL_get_error(client.get(), client_ret);
1245 if (client_err != SSL_ERROR_NONE &&
1246 client_err != SSL_ERROR_WANT_READ &&
1247 client_err != SSL_ERROR_WANT_WRITE) {
1248 fprintf(stderr, "Client error: %d\n", client_err);
1249 return false;
1250 }
1251
1252 int server_ret = SSL_do_handshake(server.get());
1253 int server_err = SSL_get_error(server.get(), server_ret);
1254 if (server_err != SSL_ERROR_NONE &&
1255 server_err != SSL_ERROR_WANT_READ &&
1256 server_err != SSL_ERROR_WANT_WRITE) {
1257 fprintf(stderr, "Server error: %d\n", server_err);
1258 return false;
1259 }
1260
1261 if (client_ret == 1 && server_ret == 1) {
1262 break;
1263 }
1264 }
1265
David Benjamin686bb192016-05-10 15:15:41 -04001266 *out_client = std::move(client);
1267 *out_server = std::move(server);
1268 return true;
1269}
1270
1271static bool TestSequenceNumber(bool dtls) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001272 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
1273 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
David Benjamin686bb192016-05-10 15:15:41 -04001274 if (!client_ctx || !server_ctx) {
1275 return false;
1276 }
1277
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001278 bssl::UniquePtr<X509> cert = GetTestCertificate();
1279 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin686bb192016-05-10 15:15:41 -04001280 if (!cert || !key ||
1281 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1282 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1283 return false;
1284 }
1285
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001286 bssl::UniquePtr<SSL> client, server;
David Benjamin686bb192016-05-10 15:15:41 -04001287 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001288 server_ctx.get(), nullptr /* no session */)) {
David Benjamin686bb192016-05-10 15:15:41 -04001289 return false;
1290 }
1291
David Benjaminde942382016-02-11 12:02:01 -05001292 uint64_t client_read_seq = SSL_get_read_sequence(client.get());
1293 uint64_t client_write_seq = SSL_get_write_sequence(client.get());
1294 uint64_t server_read_seq = SSL_get_read_sequence(server.get());
1295 uint64_t server_write_seq = SSL_get_write_sequence(server.get());
1296
1297 if (dtls) {
1298 // Both client and server must be at epoch 1.
1299 if (EpochFromSequence(client_read_seq) != 1 ||
1300 EpochFromSequence(client_write_seq) != 1 ||
1301 EpochFromSequence(server_read_seq) != 1 ||
1302 EpochFromSequence(server_write_seq) != 1) {
1303 fprintf(stderr, "Bad epochs.\n");
1304 return false;
1305 }
1306
1307 // The next record to be written should exceed the largest received.
1308 if (client_write_seq <= server_read_seq ||
1309 server_write_seq <= client_read_seq) {
1310 fprintf(stderr, "Inconsistent sequence numbers.\n");
1311 return false;
1312 }
1313 } else {
1314 // The next record to be written should equal the next to be received.
1315 if (client_write_seq != server_read_seq ||
1316 server_write_seq != client_write_seq) {
1317 fprintf(stderr, "Inconsistent sequence numbers.\n");
1318 return false;
1319 }
1320 }
1321
1322 // Send a record from client to server.
1323 uint8_t byte = 0;
1324 if (SSL_write(client.get(), &byte, 1) != 1 ||
1325 SSL_read(server.get(), &byte, 1) != 1) {
1326 fprintf(stderr, "Could not send byte.\n");
1327 return false;
1328 }
1329
1330 // The client write and server read sequence numbers should have incremented.
1331 if (client_write_seq + 1 != SSL_get_write_sequence(client.get()) ||
1332 server_read_seq + 1 != SSL_get_read_sequence(server.get())) {
1333 fprintf(stderr, "Sequence numbers did not increment.\n");\
1334 return false;
1335 }
1336
1337 return true;
1338}
1339
David Benjamin686bb192016-05-10 15:15:41 -04001340static bool TestOneSidedShutdown() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001341 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1342 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjamin686bb192016-05-10 15:15:41 -04001343 if (!client_ctx || !server_ctx) {
1344 return false;
1345 }
1346
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001347 bssl::UniquePtr<X509> cert = GetTestCertificate();
1348 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin686bb192016-05-10 15:15:41 -04001349 if (!cert || !key ||
1350 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1351 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1352 return false;
1353 }
1354
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001355 bssl::UniquePtr<SSL> client, server;
David Benjamin686bb192016-05-10 15:15:41 -04001356 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001357 server_ctx.get(), nullptr /* no session */)) {
David Benjamin686bb192016-05-10 15:15:41 -04001358 return false;
1359 }
1360
1361 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1362 // one side has shut down.
1363 if (SSL_shutdown(client.get()) != 0) {
1364 fprintf(stderr, "Could not shutdown.\n");
1365 return false;
1366 }
1367
1368 // Reading from the server should consume the EOF.
1369 uint8_t byte;
1370 if (SSL_read(server.get(), &byte, 1) != 0 ||
1371 SSL_get_error(server.get(), 0) != SSL_ERROR_ZERO_RETURN) {
1372 fprintf(stderr, "Connection was not shut down cleanly.\n");
1373 return false;
1374 }
1375
1376 // However, the server may continue to write data and then shut down the
1377 // connection.
1378 byte = 42;
1379 if (SSL_write(server.get(), &byte, 1) != 1 ||
1380 SSL_read(client.get(), &byte, 1) != 1 ||
1381 byte != 42) {
1382 fprintf(stderr, "Could not send byte.\n");
1383 return false;
1384 }
1385
1386 // The server may then shutdown the connection.
1387 if (SSL_shutdown(server.get()) != 1 ||
1388 SSL_shutdown(client.get()) != 1) {
1389 fprintf(stderr, "Could not complete shutdown.\n");
1390 return false;
1391 }
1392
1393 return true;
1394}
Steven Valdez87eab492016-06-27 16:34:59 -04001395static bool TestSessionDuplication() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001396 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1397 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
Steven Valdez87eab492016-06-27 16:34:59 -04001398 if (!client_ctx || !server_ctx) {
1399 return false;
1400 }
1401
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001402 bssl::UniquePtr<X509> cert = GetTestCertificate();
1403 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
Steven Valdez87eab492016-06-27 16:34:59 -04001404 if (!cert || !key ||
1405 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1406 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1407 return false;
1408 }
1409
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001410 bssl::UniquePtr<SSL> client, server;
Steven Valdez87eab492016-06-27 16:34:59 -04001411 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001412 server_ctx.get(), nullptr /* no session */)) {
Steven Valdez87eab492016-06-27 16:34:59 -04001413 return false;
1414 }
1415
1416 SSL_SESSION *session0 = SSL_get_session(client.get());
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001417 bssl::UniquePtr<SSL_SESSION> session1(SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL));
Steven Valdez87eab492016-06-27 16:34:59 -04001418 if (!session1) {
David Benjamin4501bd52016-08-01 13:39:41 -04001419 return false;
Steven Valdez87eab492016-06-27 16:34:59 -04001420 }
David Benjamin4501bd52016-08-01 13:39:41 -04001421
Steven Valdez84b5c002016-08-25 16:30:58 -04001422 session1->not_resumable = 0;
1423
Steven Valdez87eab492016-06-27 16:34:59 -04001424 uint8_t *s0_bytes, *s1_bytes;
1425 size_t s0_len, s1_len;
1426
1427 if (!SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len)) {
1428 return false;
1429 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001430 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001431
1432 if (!SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len)) {
1433 return false;
1434 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001435 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001436
1437 return s0_len == s1_len && memcmp(s0_bytes, s1_bytes, s0_len) == 0;
1438}
David Benjamin686bb192016-05-10 15:15:41 -04001439
David Benjamin5c0fb882016-06-14 14:03:51 -04001440static bool ExpectFDs(const SSL *ssl, int rfd, int wfd) {
1441 if (SSL_get_rfd(ssl) != rfd || SSL_get_wfd(ssl) != wfd) {
1442 fprintf(stderr, "Got fds %d and %d, wanted %d and %d.\n", SSL_get_rfd(ssl),
1443 SSL_get_wfd(ssl), rfd, wfd);
1444 return false;
1445 }
1446
1447 // The wrapper BIOs are always equal when fds are equal, even if set
1448 // individually.
1449 if (rfd == wfd && SSL_get_rbio(ssl) != SSL_get_wbio(ssl)) {
1450 fprintf(stderr, "rbio and wbio did not match.\n");
1451 return false;
1452 }
1453
1454 return true;
1455}
1456
1457static bool TestSetFD() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001458 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin5c0fb882016-06-14 14:03:51 -04001459 if (!ctx) {
1460 return false;
1461 }
1462
1463 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001464 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjamin5c0fb882016-06-14 14:03:51 -04001465 if (!ssl ||
1466 !SSL_set_rfd(ssl.get(), 1) ||
1467 !SSL_set_wfd(ssl.get(), 2) ||
1468 !ExpectFDs(ssl.get(), 1, 2)) {
1469 return false;
1470 }
1471
1472 // Test setting the same FD.
1473 ssl.reset(SSL_new(ctx.get()));
1474 if (!ssl ||
1475 !SSL_set_fd(ssl.get(), 1) ||
1476 !ExpectFDs(ssl.get(), 1, 1)) {
1477 return false;
1478 }
1479
1480 // Test setting the same FD one side at a time.
1481 ssl.reset(SSL_new(ctx.get()));
1482 if (!ssl ||
1483 !SSL_set_rfd(ssl.get(), 1) ||
1484 !SSL_set_wfd(ssl.get(), 1) ||
1485 !ExpectFDs(ssl.get(), 1, 1)) {
1486 return false;
1487 }
1488
1489 // Test setting the same FD in the other order.
1490 ssl.reset(SSL_new(ctx.get()));
1491 if (!ssl ||
1492 !SSL_set_wfd(ssl.get(), 1) ||
1493 !SSL_set_rfd(ssl.get(), 1) ||
1494 !ExpectFDs(ssl.get(), 1, 1)) {
1495 return false;
1496 }
1497
David Benjamin5c0fb882016-06-14 14:03:51 -04001498 // Test changing the read FD partway through.
1499 ssl.reset(SSL_new(ctx.get()));
1500 if (!ssl ||
1501 !SSL_set_fd(ssl.get(), 1) ||
1502 !SSL_set_rfd(ssl.get(), 2) ||
1503 !ExpectFDs(ssl.get(), 2, 1)) {
1504 return false;
1505 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001506
1507 // Test changing the write FD partway through.
1508 ssl.reset(SSL_new(ctx.get()));
1509 if (!ssl ||
1510 !SSL_set_fd(ssl.get(), 1) ||
1511 !SSL_set_wfd(ssl.get(), 2) ||
1512 !ExpectFDs(ssl.get(), 1, 2)) {
1513 return false;
1514 }
1515
1516 // Test a no-op change to the read FD partway through.
1517 ssl.reset(SSL_new(ctx.get()));
1518 if (!ssl ||
1519 !SSL_set_fd(ssl.get(), 1) ||
1520 !SSL_set_rfd(ssl.get(), 1) ||
1521 !ExpectFDs(ssl.get(), 1, 1)) {
1522 return false;
1523 }
1524
1525 // Test a no-op change to the write FD partway through.
1526 ssl.reset(SSL_new(ctx.get()));
1527 if (!ssl ||
1528 !SSL_set_fd(ssl.get(), 1) ||
1529 !SSL_set_wfd(ssl.get(), 1) ||
1530 !ExpectFDs(ssl.get(), 1, 1)) {
1531 return false;
1532 }
1533
1534 // ASan builds will implicitly test that the internal |BIO| reference-counting
1535 // is correct.
1536
1537 return true;
1538}
1539
David Benjamin4501bd52016-08-01 13:39:41 -04001540static bool TestSetBIO() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001541 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin4501bd52016-08-01 13:39:41 -04001542 if (!ctx) {
1543 return false;
1544 }
1545
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001546 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1547 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04001548 bio3(BIO_new(BIO_s_mem()));
1549 if (!ssl || !bio1 || !bio2 || !bio3) {
1550 return false;
1551 }
1552
1553 // SSL_set_bio takes one reference when the parameters are the same.
1554 BIO_up_ref(bio1.get());
1555 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1556
1557 // Repeating the call does nothing.
1558 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1559
1560 // It takes one reference each when the parameters are different.
1561 BIO_up_ref(bio2.get());
1562 BIO_up_ref(bio3.get());
1563 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1564
1565 // Repeating the call does nothing.
1566 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1567
1568 // It takes one reference when changing only wbio.
1569 BIO_up_ref(bio1.get());
1570 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1571
1572 // It takes one reference when changing only rbio and the two are different.
1573 BIO_up_ref(bio3.get());
1574 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1575
1576 // If setting wbio to rbio, it takes no additional references.
1577 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1578
1579 // From there, wbio may be switched to something else.
1580 BIO_up_ref(bio1.get());
1581 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1582
1583 // If setting rbio to wbio, it takes no additional references.
1584 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1585
1586 // From there, rbio may be switched to something else, but, for historical
1587 // reasons, it takes a reference to both parameters.
1588 BIO_up_ref(bio1.get());
1589 BIO_up_ref(bio2.get());
1590 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1591
1592 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1593 // is correct.
1594 return true;
1595}
1596
David Benjamincb18ac22016-09-27 14:09:15 -04001597static uint16_t kTLSVersions[] = {
David Benjamin25490f22016-07-14 00:22:54 -04001598 SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION, TLS1_2_VERSION, TLS1_3_VERSION,
1599};
1600
David Benjamincb18ac22016-09-27 14:09:15 -04001601static uint16_t kDTLSVersions[] = {
1602 DTLS1_VERSION, DTLS1_2_VERSION,
1603};
1604
David Benjamin25490f22016-07-14 00:22:54 -04001605static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1606
David Benjaminadd5e522016-07-14 00:33:24 -04001607static bool TestGetPeerCertificate() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001608 bssl::UniquePtr<X509> cert = GetTestCertificate();
1609 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminadd5e522016-07-14 00:33:24 -04001610 if (!cert || !key) {
1611 return false;
1612 }
1613
David Benjamincb18ac22016-09-27 14:09:15 -04001614 for (uint16_t version : kTLSVersions) {
David Benjaminadd5e522016-07-14 00:33:24 -04001615 // Configure both client and server to accept any certificate.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001616 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminadd5e522016-07-14 00:33:24 -04001617 if (!ctx ||
1618 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001619 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04001620 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1621 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
David Benjaminadd5e522016-07-14 00:33:24 -04001622 return false;
1623 }
David Benjaminadd5e522016-07-14 00:33:24 -04001624 SSL_CTX_set_verify(
1625 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1626 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1627
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001628 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001629 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1630 nullptr /* no session */)) {
David Benjaminadd5e522016-07-14 00:33:24 -04001631 return false;
1632 }
1633
1634 // Client and server should both see the leaf certificate.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001635 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04001636 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1637 fprintf(stderr, "%x: Server peer certificate did not match.\n", version);
1638 return false;
1639 }
1640
1641 peer.reset(SSL_get_peer_certificate(client.get()));
1642 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1643 fprintf(stderr, "%x: Client peer certificate did not match.\n", version);
1644 return false;
1645 }
1646
1647 // However, for historical reasons, the chain includes the leaf on the
1648 // client, but does not on the server.
1649 if (sk_X509_num(SSL_get_peer_cert_chain(client.get())) != 1) {
1650 fprintf(stderr, "%x: Client peer chain was incorrect.\n", version);
1651 return false;
1652 }
1653
1654 if (sk_X509_num(SSL_get_peer_cert_chain(server.get())) != 0) {
1655 fprintf(stderr, "%x: Server peer chain was incorrect.\n", version);
1656 return false;
1657 }
1658 }
1659
1660 return true;
1661}
1662
David Benjamin25490f22016-07-14 00:22:54 -04001663static bool TestRetainOnlySHA256OfCerts() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001664 bssl::UniquePtr<X509> cert = GetTestCertificate();
1665 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin25490f22016-07-14 00:22:54 -04001666 if (!cert || !key) {
1667 return false;
1668 }
1669
1670 uint8_t *cert_der = NULL;
1671 int cert_der_len = i2d_X509(cert.get(), &cert_der);
1672 if (cert_der_len < 0) {
1673 return false;
1674 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001675 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04001676
1677 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1678 SHA256(cert_der, cert_der_len, cert_sha256);
1679
David Benjamincb18ac22016-09-27 14:09:15 -04001680 for (uint16_t version : kTLSVersions) {
David Benjamin25490f22016-07-14 00:22:54 -04001681 // Configure both client and server to accept any certificate, but the
1682 // server must retain only the SHA-256 of the peer.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001683 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin25490f22016-07-14 00:22:54 -04001684 if (!ctx ||
1685 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001686 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04001687 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1688 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
David Benjamin25490f22016-07-14 00:22:54 -04001689 return false;
1690 }
David Benjamin25490f22016-07-14 00:22:54 -04001691 SSL_CTX_set_verify(
1692 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1693 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1694 SSL_CTX_set_retain_only_sha256_of_client_certs(ctx.get(), 1);
1695
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001696 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001697 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1698 nullptr /* no session */)) {
David Benjamin25490f22016-07-14 00:22:54 -04001699 return false;
1700 }
1701
1702 // The peer certificate has been dropped.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001703 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
David Benjamin25490f22016-07-14 00:22:54 -04001704 if (peer) {
1705 fprintf(stderr, "%x: Peer certificate was retained.\n", version);
1706 return false;
1707 }
1708
1709 SSL_SESSION *session = SSL_get_session(server.get());
1710 if (!session->peer_sha256_valid) {
1711 fprintf(stderr, "%x: peer_sha256_valid was not set.\n", version);
1712 return false;
1713 }
1714
1715 if (memcmp(cert_sha256, session->peer_sha256, SHA256_DIGEST_LENGTH) != 0) {
1716 fprintf(stderr, "%x: peer_sha256 did not match.\n", version);
1717 return false;
1718 }
1719 }
1720
1721 return true;
1722}
1723
David Benjaminafc64de2016-07-19 17:12:41 +02001724static bool ClientHelloMatches(uint16_t version, const uint8_t *expected,
1725 size_t expected_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001726 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin2dc02042016-09-19 19:57:37 -04001727 if (!ctx ||
David Benjamine4706902016-09-20 15:12:23 -04001728 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001729 // Our default cipher list varies by CPU capabilities, so manually place
1730 // the ChaCha20 ciphers in front.
1731 !SSL_CTX_set_cipher_list(ctx.get(), "CHACHA20:ALL")) {
David Benjaminafc64de2016-07-19 17:12:41 +02001732 return false;
1733 }
David Benjamin2dc02042016-09-19 19:57:37 -04001734
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001735 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +02001736 if (!ssl) {
1737 return false;
1738 }
1739 std::vector<uint8_t> client_hello;
1740 if (!GetClientHello(ssl.get(), &client_hello)) {
1741 return false;
1742 }
1743
1744 // Zero the client_random.
1745 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
1746 1 + 3 + // handshake message header
1747 2; // client_version
1748 if (client_hello.size() < kRandomOffset + SSL3_RANDOM_SIZE) {
1749 fprintf(stderr, "ClientHello for version %04x too short.\n", version);
1750 return false;
1751 }
1752 memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
1753
1754 if (client_hello.size() != expected_len ||
1755 memcmp(client_hello.data(), expected, expected_len) != 0) {
1756 fprintf(stderr, "ClientHello for version %04x did not match:\n", version);
1757 fprintf(stderr, "Got:\n\t");
1758 for (size_t i = 0; i < client_hello.size(); i++) {
1759 fprintf(stderr, "0x%02x, ", client_hello[i]);
1760 }
1761 fprintf(stderr, "\nWanted:\n\t");
1762 for (size_t i = 0; i < expected_len; i++) {
1763 fprintf(stderr, "0x%02x, ", expected[i]);
1764 }
1765 fprintf(stderr, "\n");
1766 return false;
1767 }
1768
1769 return true;
1770}
1771
1772// Tests that our ClientHellos do not change unexpectedly.
1773static bool TestClientHello() {
1774 static const uint8_t kSSL3ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001775 0x16,
1776 0x03, 0x00,
1777 0x00, 0x3f,
1778 0x01,
1779 0x00, 0x00, 0x3b,
1780 0x03, 0x00,
1781 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1782 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1783 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1784 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1785 0x00,
1786 0x00, 0x14,
1787 0xc0, 0x09,
1788 0xc0, 0x13,
1789 0x00, 0x33,
1790 0xc0, 0x0a,
1791 0xc0, 0x14,
1792 0x00, 0x39,
1793 0x00, 0x2f,
1794 0x00, 0x35,
1795 0x00, 0x0a,
1796 0x00, 0xff, 0x01, 0x00,
David Benjaminafc64de2016-07-19 17:12:41 +02001797 };
1798 if (!ClientHelloMatches(SSL3_VERSION, kSSL3ClientHello,
1799 sizeof(kSSL3ClientHello))) {
1800 return false;
1801 }
1802
1803 static const uint8_t kTLS1ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001804 0x16,
1805 0x03, 0x01,
1806 0x00, 0x5e,
1807 0x01,
1808 0x00, 0x00, 0x5a,
1809 0x03, 0x01,
1810 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1811 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1812 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1813 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1814 0x00,
1815 0x00, 0x12,
1816 0xc0, 0x09,
1817 0xc0, 0x13,
1818 0x00, 0x33,
1819 0xc0, 0x0a,
1820 0xc0, 0x14,
1821 0x00, 0x39,
1822 0x00, 0x2f,
1823 0x00, 0x35,
1824 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001825 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1826 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1827 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1828 };
1829 if (!ClientHelloMatches(TLS1_VERSION, kTLS1ClientHello,
1830 sizeof(kTLS1ClientHello))) {
1831 return false;
1832 }
1833
1834 static const uint8_t kTLS11ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001835 0x16,
1836 0x03, 0x01,
1837 0x00, 0x5e,
1838 0x01,
1839 0x00, 0x00, 0x5a,
1840 0x03, 0x02,
1841 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1842 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1843 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1844 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1845 0x00,
1846 0x00, 0x12,
1847 0xc0, 0x09,
1848 0xc0, 0x13,
1849 0x00, 0x33,
1850 0xc0, 0x0a,
1851 0xc0, 0x14,
1852 0x00, 0x39,
1853 0x00, 0x2f,
1854 0x00, 0x35,
1855 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001856 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1857 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1858 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1859 };
1860 if (!ClientHelloMatches(TLS1_1_VERSION, kTLS11ClientHello,
1861 sizeof(kTLS11ClientHello))) {
1862 return false;
1863 }
1864
1865 static const uint8_t kTLS12ClientHello[] = {
David Benjamin57e929f2016-08-30 00:30:38 -04001866 0x16, 0x03, 0x01, 0x00, 0xa2, 0x01, 0x00, 0x00, 0x9e, 0x03, 0x03, 0x00,
1867 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1868 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1869 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0xcc, 0xa9,
1870 0xcc, 0xa8, 0xcc, 0x14, 0xcc, 0x13, 0xc0, 0x2b, 0xc0, 0x2f, 0x00, 0x9e,
1871 0xc0, 0x2c, 0xc0, 0x30, 0x00, 0x9f, 0xc0, 0x09, 0xc0, 0x23, 0xc0, 0x13,
1872 0xc0, 0x27, 0x00, 0x33, 0x00, 0x67, 0xc0, 0x0a, 0xc0, 0x24, 0xc0, 0x14,
1873 0xc0, 0x28, 0x00, 0x39, 0x00, 0x6b, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
1874 0x00, 0x3c, 0x00, 0x35, 0x00, 0x3d, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x3b,
1875 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00,
David Benjaminaf56fbd2016-09-21 14:38:06 -04001876 0x00, 0x00, 0x0d, 0x00, 0x18, 0x00, 0x16, 0x08, 0x06, 0x06, 0x01, 0x06,
1877 0x03, 0x08, 0x05, 0x05, 0x01, 0x05, 0x03, 0x08, 0x04, 0x04, 0x01, 0x04,
David Benjamin57e929f2016-08-30 00:30:38 -04001878 0x03, 0x02, 0x01, 0x02, 0x03, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1879 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
David Benjaminafc64de2016-07-19 17:12:41 +02001880 };
1881 if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
1882 sizeof(kTLS12ClientHello))) {
1883 return false;
1884 }
1885
1886 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
1887 // implementation has settled enough that it won't change.
1888
1889 return true;
1890}
1891
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001892static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04001893
1894static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
1895 // Save the most recent session.
1896 g_last_session.reset(session);
1897 return 1;
1898}
1899
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001900static bssl::UniquePtr<SSL_SESSION> CreateClientSession(SSL_CTX *client_ctx,
David Benjamina20e5352016-08-02 19:09:41 -04001901 SSL_CTX *server_ctx) {
1902 g_last_session = nullptr;
1903 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
1904
1905 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001906 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001907 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
1908 nullptr /* no session */)) {
1909 fprintf(stderr, "Failed to connect client and server.\n");
1910 return nullptr;
1911 }
1912
1913 // Run the read loop to account for post-handshake tickets in TLS 1.3.
1914 SSL_read(client.get(), nullptr, 0);
1915
1916 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
1917
1918 if (!g_last_session) {
1919 fprintf(stderr, "Client did not receive a session.\n");
1920 return nullptr;
1921 }
1922 return std::move(g_last_session);
1923}
1924
1925static bool ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1926 SSL_SESSION *session,
1927 bool reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001928 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001929 if (!ConnectClientAndServer(&client, &server, client_ctx,
1930 server_ctx, session)) {
1931 fprintf(stderr, "Failed to connect client and server.\n");
1932 return false;
1933 }
1934
1935 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
1936 fprintf(stderr, "Client and server were inconsistent.\n");
1937 return false;
1938 }
1939
1940 bool was_reused = !!SSL_session_reused(client.get());
1941 if (was_reused != reused) {
1942 fprintf(stderr, "Session was%s reused, but we expected the opposite.\n",
1943 was_reused ? "" : " not");
1944 return false;
1945 }
1946
1947 return true;
1948}
1949
1950static bool TestSessionIDContext() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001951 bssl::UniquePtr<X509> cert = GetTestCertificate();
1952 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamina20e5352016-08-02 19:09:41 -04001953 if (!cert || !key) {
1954 return false;
1955 }
1956
1957 static const uint8_t kContext1[] = {1};
1958 static const uint8_t kContext2[] = {2};
1959
David Benjamincb18ac22016-09-27 14:09:15 -04001960 for (uint16_t version : kTLSVersions) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001961 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
1962 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamina20e5352016-08-02 19:09:41 -04001963 if (!server_ctx || !client_ctx ||
1964 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1965 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
1966 !SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
David Benjamin2dc02042016-09-19 19:57:37 -04001967 sizeof(kContext1)) ||
David Benjamine4706902016-09-20 15:12:23 -04001968 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
1969 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
1970 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
1971 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
David Benjamina20e5352016-08-02 19:09:41 -04001972 return false;
1973 }
1974
David Benjamina20e5352016-08-02 19:09:41 -04001975 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04001976 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
1977
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001978 bssl::UniquePtr<SSL_SESSION> session =
David Benjamina20e5352016-08-02 19:09:41 -04001979 CreateClientSession(client_ctx.get(), server_ctx.get());
1980 if (!session) {
1981 fprintf(stderr, "Error getting session (version = %04x).\n", version);
1982 return false;
1983 }
1984
1985 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1986 true /* expect session reused */)) {
1987 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
1988 return false;
1989 }
1990
1991 // Change the session ID context.
1992 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext2,
1993 sizeof(kContext2))) {
1994 return false;
1995 }
1996
1997 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1998 false /* expect session not reused */)) {
1999 fprintf(stderr,
2000 "Error connection with different context (version = %04x).\n",
2001 version);
2002 return false;
2003 }
2004 }
2005
2006 return true;
2007}
2008
David Benjamin721e8b72016-08-03 13:13:17 -04002009static timeval g_current_time;
2010
2011static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2012 *out_clock = g_current_time;
2013}
2014
2015static bool TestSessionTimeout() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002016 bssl::UniquePtr<X509> cert = GetTestCertificate();
2017 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin721e8b72016-08-03 13:13:17 -04002018 if (!cert || !key) {
2019 return false;
2020 }
2021
David Benjamincb18ac22016-09-27 14:09:15 -04002022 for (uint16_t version : kTLSVersions) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002023 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2024 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin721e8b72016-08-03 13:13:17 -04002025 if (!server_ctx || !client_ctx ||
2026 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04002027 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04002028 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2029 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2030 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2031 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
David Benjamin721e8b72016-08-03 13:13:17 -04002032 return false;
2033 }
2034
David Benjamin721e8b72016-08-03 13:13:17 -04002035 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2036
David Benjamin721e8b72016-08-03 13:13:17 -04002037 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
2038 SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
2039
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002040 bssl::UniquePtr<SSL_SESSION> session =
David Benjamin721e8b72016-08-03 13:13:17 -04002041 CreateClientSession(client_ctx.get(), server_ctx.get());
2042 if (!session) {
2043 fprintf(stderr, "Error getting session (version = %04x).\n", version);
2044 return false;
2045 }
2046
2047 // Advance the clock just behind the timeout.
2048 g_current_time.tv_sec += SSL_DEFAULT_SESSION_TIMEOUT;
2049
2050 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2051 true /* expect session reused */)) {
2052 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
2053 return false;
2054 }
2055
2056 // Advance the clock one more second.
2057 g_current_time.tv_sec++;
2058
2059 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2060 false /* expect session not reused */)) {
2061 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
2062 return false;
2063 }
2064 }
2065
2066 return true;
2067}
2068
David Benjamin0fc37ef2016-08-17 15:29:46 -04002069static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
2070 SSL_CTX *ctx = reinterpret_cast<SSL_CTX*>(arg);
2071 SSL_set_SSL_CTX(ssl, ctx);
2072 return SSL_TLSEXT_ERR_OK;
2073}
2074
2075static bool TestSNICallback() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002076 bssl::UniquePtr<X509> cert = GetTestCertificate();
2077 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2078 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
2079 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
David Benjamin0fc37ef2016-08-17 15:29:46 -04002080 if (!cert || !key || !cert2 || !key2) {
2081 return false;
2082 }
2083
2084 // At each version, test that switching the |SSL_CTX| at the SNI callback
2085 // behaves correctly.
David Benjamincb18ac22016-09-27 14:09:15 -04002086 for (uint16_t version : kTLSVersions) {
David Benjamin0fc37ef2016-08-17 15:29:46 -04002087 if (version == SSL3_VERSION) {
2088 continue;
2089 }
2090
2091 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
2092
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002093 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2094 bssl::UniquePtr<SSL_CTX> server_ctx2(SSL_CTX_new(TLS_method()));
2095 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002096 if (!server_ctx || !server_ctx2 || !client_ctx ||
2097 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2098 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2099 !SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()) ||
2100 !SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()) ||
2101 // Historically signing preferences would be lost in some cases with the
2102 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2103 // this doesn't happen when |version| is TLS 1.2, configure the private
2104 // key to only sign SHA-256.
2105 !SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
David Benjamin2dc02042016-09-19 19:57:37 -04002106 &kECDSAWithSHA256, 1) ||
David Benjamine4706902016-09-20 15:12:23 -04002107 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2108 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2109 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2110 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2111 !SSL_CTX_set_min_proto_version(server_ctx2.get(), version) ||
2112 !SSL_CTX_set_max_proto_version(server_ctx2.get(), version)) {
David Benjamin0fc37ef2016-08-17 15:29:46 -04002113 return false;
2114 }
2115
David Benjamin0fc37ef2016-08-17 15:29:46 -04002116 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), SwitchContext);
2117 SSL_CTX_set_tlsext_servername_arg(server_ctx.get(), server_ctx2.get());
2118
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002119 bssl::UniquePtr<SSL> client, server;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002120 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2121 server_ctx.get(), nullptr)) {
2122 fprintf(stderr, "Handshake failed at version %04x.\n", version);
2123 return false;
2124 }
2125
2126 // The client should have received |cert2|.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002127 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client.get()));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002128 if (!peer ||
2129 X509_cmp(peer.get(), cert2.get()) != 0) {
2130 fprintf(stderr, "Incorrect certificate received at version %04x.\n",
2131 version);
2132 return false;
2133 }
2134 }
2135
2136 return true;
2137}
2138
David Benjamin99620572016-08-30 00:35:36 -04002139static int SetMaxVersion(const struct ssl_early_callback_ctx *ctx) {
David Benjamine4706902016-09-20 15:12:23 -04002140 if (!SSL_set_max_proto_version(ctx->ssl, TLS1_2_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002141 return -1;
2142 }
2143
David Benjamin99620572016-08-30 00:35:36 -04002144 return 1;
2145}
2146
2147// TestEarlyCallbackVersionSwitch tests that the early callback can swap the
2148// maximum version.
2149static bool TestEarlyCallbackVersionSwitch() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002150 bssl::UniquePtr<X509> cert = GetTestCertificate();
2151 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2152 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2153 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin99620572016-08-30 00:35:36 -04002154 if (!cert || !key || !server_ctx || !client_ctx ||
2155 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04002156 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04002157 !SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION) ||
2158 !SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION)) {
David Benjamin99620572016-08-30 00:35:36 -04002159 return false;
2160 }
2161
David Benjamin99620572016-08-30 00:35:36 -04002162 SSL_CTX_set_select_certificate_cb(server_ctx.get(), SetMaxVersion);
2163
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002164 bssl::UniquePtr<SSL> client, server;
David Benjamin99620572016-08-30 00:35:36 -04002165 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2166 server_ctx.get(), nullptr)) {
2167 return false;
2168 }
2169
2170 if (SSL_version(client.get()) != TLS1_2_VERSION) {
2171 fprintf(stderr, "Early callback failed to switch the maximum version.\n");
2172 return false;
2173 }
2174
2175 return true;
2176}
2177
David Benjamin2dc02042016-09-19 19:57:37 -04002178static bool TestSetVersion() {
2179 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2180 if (!ctx) {
2181 return false;
2182 }
2183
David Benjamine4706902016-09-20 15:12:23 -04002184 if (!SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION) ||
2185 !SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION) ||
2186 !SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION) ||
2187 !SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002188 fprintf(stderr, "Could not set valid TLS version.\n");
2189 return false;
2190 }
2191
David Benjamine4706902016-09-20 15:12:23 -04002192 if (SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION) ||
2193 SSL_CTX_set_max_proto_version(ctx.get(), 0x0200) ||
2194 SSL_CTX_set_max_proto_version(ctx.get(), 0x1234) ||
2195 SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION) ||
2196 SSL_CTX_set_min_proto_version(ctx.get(), 0x0200) ||
2197 SSL_CTX_set_min_proto_version(ctx.get(), 0x1234)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002198 fprintf(stderr, "Unexpectedly set invalid TLS version.\n");
2199 return false;
2200 }
2201
David Benjamine34bcc92016-09-21 16:53:09 -04002202 if (!SSL_CTX_set_max_proto_version(ctx.get(), 0) ||
2203 !SSL_CTX_set_min_proto_version(ctx.get(), 0)) {
2204 fprintf(stderr, "Could not set default TLS version.\n");
2205 return false;
2206 }
2207
2208 if (ctx->min_version != SSL3_VERSION ||
2209 ctx->max_version != TLS1_2_VERSION) {
2210 fprintf(stderr, "Default TLS versions were incorrect (%04x and %04x).\n",
2211 ctx->min_version, ctx->max_version);
2212 return false;
2213 }
2214
David Benjamin2dc02042016-09-19 19:57:37 -04002215 ctx.reset(SSL_CTX_new(DTLS_method()));
2216 if (!ctx) {
2217 return false;
2218 }
2219
David Benjamine4706902016-09-20 15:12:23 -04002220 if (!SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION) ||
2221 !SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION) ||
2222 !SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION) ||
2223 !SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002224 fprintf(stderr, "Could not set valid DTLS version.\n");
2225 return false;
2226 }
2227
David Benjamine4706902016-09-20 15:12:23 -04002228 if (SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION) ||
2229 SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */) ||
2230 SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */) ||
2231 SSL_CTX_set_max_proto_version(ctx.get(), 0x1234) ||
2232 SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION) ||
2233 SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */) ||
2234 SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */) ||
2235 SSL_CTX_set_min_proto_version(ctx.get(), 0x1234)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002236 fprintf(stderr, "Unexpectedly set invalid DTLS version.\n");
2237 return false;
2238 }
2239
David Benjamine34bcc92016-09-21 16:53:09 -04002240 if (!SSL_CTX_set_max_proto_version(ctx.get(), 0) ||
2241 !SSL_CTX_set_min_proto_version(ctx.get(), 0)) {
2242 fprintf(stderr, "Could not set default DTLS version.\n");
2243 return false;
2244 }
2245
2246 if (ctx->min_version != TLS1_1_VERSION ||
2247 ctx->max_version != TLS1_2_VERSION) {
2248 fprintf(stderr, "Default DTLS versions were incorrect (%04x and %04x).\n",
2249 ctx->min_version, ctx->max_version);
2250 return false;
2251 }
2252
David Benjamin2dc02042016-09-19 19:57:37 -04002253 return true;
2254}
2255
David Benjamincb18ac22016-09-27 14:09:15 -04002256static bool TestVersions() {
2257 bssl::UniquePtr<X509> cert = GetTestCertificate();
2258 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2259 if (!cert || !key) {
2260 return false;
2261 }
2262
2263 for (bool is_dtls : std::vector<bool>{false, true}) {
2264 const SSL_METHOD *method = is_dtls ? DTLS_method() : TLS_method();
2265 const char *name = is_dtls ? "DTLS" : "TLS";
2266 const uint16_t *versions = is_dtls ? kDTLSVersions : kTLSVersions;
2267 size_t num_versions = is_dtls ? OPENSSL_ARRAY_SIZE(kDTLSVersions)
2268 : OPENSSL_ARRAY_SIZE(kTLSVersions);
2269 for (size_t i = 0; i < num_versions; i++) {
2270 uint16_t version = versions[i];
2271 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2272 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2273 bssl::UniquePtr<SSL> client, server;
2274 if (!server_ctx || !client_ctx ||
2275 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2276 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2277 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2278 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2279 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2280 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2281 !ConnectClientAndServer(&client, &server, client_ctx.get(),
2282 server_ctx.get(), nullptr /* no session */)) {
2283 fprintf(stderr, "Failed to connect %s at version %04x.\n", name,
2284 version);
2285 return false;
2286 }
2287
2288 if (SSL_version(client.get()) != version ||
2289 SSL_version(server.get()) != version) {
2290 fprintf(stderr,
2291 "%s version mismatch. Got %04x and %04x, wanted %04x.\n", name,
2292 SSL_version(client.get()), SSL_version(server.get()), version);
2293 return false;
2294 }
2295 }
2296 }
2297
2298 return true;
2299}
2300
David Benjamin1d128f32015-09-08 17:41:40 -04002301int main() {
David Benjamin7a1eefd2015-10-17 23:39:22 -04002302 CRYPTO_library_init();
David Benjaminbb0a17c2014-09-20 15:35:39 -04002303
Adam Langley10f97f32016-07-12 08:09:33 -07002304 if (!TestCipherRules() ||
Alessandro Ghedini5fd18072016-09-28 21:04:25 +01002305 !TestCurveRules() ||
Adam Langley10f97f32016-07-12 08:09:33 -07002306 !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
2307 !TestSSL_SESSIONEncoding(kCustomSession) ||
2308 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
2309 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
2310 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
2311 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
David Benjamin10e664b2016-06-20 22:20:47 -04002312 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
Adam Langley10f97f32016-07-12 08:09:33 -07002313 !TestDefaultVersion(SSL3_VERSION, TLS1_2_VERSION, &TLS_method) ||
2314 !TestDefaultVersion(SSL3_VERSION, SSL3_VERSION, &SSLv3_method) ||
2315 !TestDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method) ||
2316 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method) ||
2317 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method) ||
2318 !TestDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method) ||
2319 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method) ||
2320 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method) ||
2321 !TestCipherGetRFCName() ||
2322 !TestPaddingExtension() ||
2323 !TestClientCAList() ||
2324 !TestInternalSessionCache() ||
2325 !TestSequenceNumber(false /* TLS */) ||
2326 !TestSequenceNumber(true /* DTLS */) ||
2327 !TestOneSidedShutdown() ||
Steven Valdez87eab492016-06-27 16:34:59 -04002328 !TestSessionDuplication() ||
David Benjamin25490f22016-07-14 00:22:54 -04002329 !TestSetFD() ||
David Benjamin4501bd52016-08-01 13:39:41 -04002330 !TestSetBIO() ||
David Benjaminadd5e522016-07-14 00:33:24 -04002331 !TestGetPeerCertificate() ||
David Benjaminafc64de2016-07-19 17:12:41 +02002332 !TestRetainOnlySHA256OfCerts() ||
David Benjamina20e5352016-08-02 19:09:41 -04002333 !TestClientHello() ||
David Benjamin721e8b72016-08-03 13:13:17 -04002334 !TestSessionIDContext() ||
David Benjamin0fc37ef2016-08-17 15:29:46 -04002335 !TestSessionTimeout() ||
David Benjamin99620572016-08-30 00:35:36 -04002336 !TestSNICallback() ||
David Benjamin2dc02042016-09-19 19:57:37 -04002337 !TestEarlyCallbackVersionSwitch() ||
David Benjamincb18ac22016-09-27 14:09:15 -04002338 !TestSetVersion() ||
2339 !TestVersions()) {
Brian Smith83a82982015-04-09 16:21:10 -10002340 ERR_print_errors_fp(stderr);
David Benjaminbb0a17c2014-09-20 15:35:39 -04002341 return 1;
2342 }
2343
David Benjamin2e521212014-07-16 14:37:51 -04002344 printf("PASS\n");
2345 return 0;
2346}