blob: be6443cd1b7ed92a8147e14f589b8bfc52266eef [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[] = {
David Benjamin2bdb35c2015-02-21 11:03:06 -0500817 { SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA" },
David Benjamin2bdb35c2015-02-21 11:03:06 -0500818 { TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA" },
David Benjamin2bdb35c2015-02-21 11:03:06 -0500819 { 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" },
David Benjamin2bdb35c2015-02-21 11:03:06 -0500822 { 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" },
Adam Langley85bc5602015-06-09 09:54:04 -0700832 { TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
833 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA" },
David Benjamin13414b32015-12-09 23:02:39 -0500834 { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
835 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
David Benjamin1d77e562015-03-22 17:22:08 -0400836 // These names are non-standard:
Brian Smith271777f2015-10-03 13:53:33 -1000837 { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD,
David Benjamin2bdb35c2015-02-21 11:03:06 -0500838 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
Brian Smith271777f2015-10-03 13:53:33 -1000839 { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD,
David Benjamin2bdb35c2015-02-21 11:03:06 -0500840 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" },
David Benjamin65226252015-02-05 16:49:47 -0500841};
842
David Benjamin1d77e562015-03-22 17:22:08 -0400843static bool TestCipherGetRFCName(void) {
844 for (size_t i = 0;
Steven Valdezcb966542016-08-17 16:56:14 -0400845 i < OPENSSL_ARRAY_SIZE(kCipherRFCNameTests); i++) {
David Benjamin65226252015-02-05 16:49:47 -0500846 const CIPHER_RFC_NAME_TEST *test = &kCipherRFCNameTests[i];
David Benjamin1d77e562015-03-22 17:22:08 -0400847 std::string rfc_name;
848 if (!CipherGetRFCName(&rfc_name, test->id & 0xffff)) {
849 fprintf(stderr, "SSL_CIPHER_get_rfc_name failed\n");
850 return false;
David Benjamin65226252015-02-05 16:49:47 -0500851 }
David Benjamin1d77e562015-03-22 17:22:08 -0400852 if (rfc_name != test->rfc_name) {
David Benjamin65226252015-02-05 16:49:47 -0500853 fprintf(stderr, "SSL_CIPHER_get_rfc_name: got '%s', wanted '%s'\n",
David Benjamin1d77e562015-03-22 17:22:08 -0400854 rfc_name.c_str(), test->rfc_name);
855 return false;
David Benjamin65226252015-02-05 16:49:47 -0500856 }
David Benjamin65226252015-02-05 16:49:47 -0500857 }
David Benjamin1d77e562015-03-22 17:22:08 -0400858 return true;
David Benjamin65226252015-02-05 16:49:47 -0500859}
860
David Benjamin422fe082015-07-21 22:03:43 -0400861// CreateSessionWithTicket returns a sample |SSL_SESSION| with the ticket
862// replaced for one of length |ticket_len| or nullptr on failure.
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700863static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(size_t ticket_len) {
David Benjamin422fe082015-07-21 22:03:43 -0400864 std::vector<uint8_t> der;
865 if (!DecodeBase64(&der, kOpenSSLSession)) {
866 return nullptr;
867 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700868 bssl::UniquePtr<SSL_SESSION> session(SSL_SESSION_from_bytes(der.data(), der.size()));
David Benjamin422fe082015-07-21 22:03:43 -0400869 if (!session) {
870 return nullptr;
871 }
872
873 // Swap out the ticket for a garbage one.
874 OPENSSL_free(session->tlsext_tick);
875 session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len));
876 if (session->tlsext_tick == nullptr) {
877 return nullptr;
878 }
879 memset(session->tlsext_tick, 'a', ticket_len);
880 session->tlsext_ticklen = ticket_len;
David Benjamin1269ddd2015-10-18 15:18:55 -0400881
882 // Fix up the timeout.
883 session->time = time(NULL);
David Benjamin422fe082015-07-21 22:03:43 -0400884 return session;
885}
886
David Benjaminafc64de2016-07-19 17:12:41 +0200887static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700888 bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
David Benjaminafc64de2016-07-19 17:12:41 +0200889 if (!bio) {
890 return false;
891 }
892 // Do not configure a reading BIO, but record what's written to a memory BIO.
David Benjamin96a16cd2016-08-11 12:14:47 -0400893 BIO_up_ref(bio.get());
894 SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
David Benjaminafc64de2016-07-19 17:12:41 +0200895 int ret = SSL_connect(ssl);
896 if (ret > 0) {
897 // SSL_connect should fail without a BIO to write to.
898 return false;
899 }
900 ERR_clear_error();
901
902 const uint8_t *client_hello;
903 size_t client_hello_len;
904 if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
905 return false;
906 }
907 *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
908 return true;
909}
910
David Benjamin422fe082015-07-21 22:03:43 -0400911// GetClientHelloLen creates a client SSL connection with a ticket of length
912// |ticket_len| and records the ClientHello. It returns the length of the
913// ClientHello, not including the record header, on success and zero on error.
914static size_t GetClientHelloLen(size_t ticket_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700915 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
916 bssl::UniquePtr<SSL_SESSION> session = CreateSessionWithTicket(ticket_len);
David Benjamin422fe082015-07-21 22:03:43 -0400917 if (!ctx || !session) {
918 return 0;
919 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700920 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +0200921 if (!ssl || !SSL_set_session(ssl.get(), session.get())) {
David Benjamin422fe082015-07-21 22:03:43 -0400922 return 0;
923 }
David Benjaminafc64de2016-07-19 17:12:41 +0200924 std::vector<uint8_t> client_hello;
925 if (!GetClientHello(ssl.get(), &client_hello) ||
926 client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
David Benjamin422fe082015-07-21 22:03:43 -0400927 return 0;
928 }
David Benjaminafc64de2016-07-19 17:12:41 +0200929 return client_hello.size() - SSL3_RT_HEADER_LENGTH;
David Benjamin422fe082015-07-21 22:03:43 -0400930}
931
932struct PaddingTest {
933 size_t input_len, padded_len;
934};
935
936static const PaddingTest kPaddingTests[] = {
937 // ClientHellos of length below 0x100 do not require padding.
938 {0xfe, 0xfe},
939 {0xff, 0xff},
940 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
941 {0x100, 0x200},
942 {0x123, 0x200},
943 {0x1fb, 0x200},
944 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
945 // padding extension takes a minimum of four bytes plus one required content
946 // byte. (To work around yet more server bugs, we avoid empty final
947 // extensions.)
948 {0x1fc, 0x201},
949 {0x1fd, 0x202},
950 {0x1fe, 0x203},
951 {0x1ff, 0x204},
952 // Finally, larger ClientHellos need no padding.
953 {0x200, 0x200},
954 {0x201, 0x201},
955};
956
957static bool TestPaddingExtension() {
958 // Sample a baseline length.
959 size_t base_len = GetClientHelloLen(1);
960 if (base_len == 0) {
961 return false;
962 }
963
964 for (const PaddingTest &test : kPaddingTests) {
965 if (base_len > test.input_len) {
966 fprintf(stderr, "Baseline ClientHello too long.\n");
967 return false;
968 }
969
970 size_t padded_len = GetClientHelloLen(1 + test.input_len - base_len);
971 if (padded_len != test.padded_len) {
972 fprintf(stderr, "%u-byte ClientHello padded to %u bytes, not %u.\n",
973 static_cast<unsigned>(test.input_len),
974 static_cast<unsigned>(padded_len),
975 static_cast<unsigned>(test.padded_len));
976 return false;
977 }
978 }
979 return true;
980}
981
David Benjamin1d128f32015-09-08 17:41:40 -0400982// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
983// before configuring as a server.
984static bool TestClientCAList() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700985 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin1d128f32015-09-08 17:41:40 -0400986 if (!ctx) {
987 return false;
988 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700989 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjamin1d128f32015-09-08 17:41:40 -0400990 if (!ssl) {
991 return false;
992 }
993
994 STACK_OF(X509_NAME) *stack = sk_X509_NAME_new_null();
995 if (stack == nullptr) {
996 return false;
997 }
998 // |SSL_set_client_CA_list| takes ownership.
999 SSL_set_client_CA_list(ssl.get(), stack);
1000
1001 return SSL_get_client_CA_list(ssl.get()) == stack;
1002}
1003
David Benjamin0f653952015-10-18 14:28:01 -04001004static void AppendSession(SSL_SESSION *session, void *arg) {
1005 std::vector<SSL_SESSION*> *out =
1006 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
1007 out->push_back(session);
1008}
1009
1010// ExpectCache returns true if |ctx|'s session cache consists of |expected|, in
1011// order.
1012static bool ExpectCache(SSL_CTX *ctx,
1013 const std::vector<SSL_SESSION*> &expected) {
1014 // Check the linked list.
1015 SSL_SESSION *ptr = ctx->session_cache_head;
1016 for (SSL_SESSION *session : expected) {
1017 if (ptr != session) {
1018 return false;
1019 }
1020 // TODO(davidben): This is an absurd way to denote the end of the list.
1021 if (ptr->next ==
1022 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
1023 ptr = nullptr;
1024 } else {
1025 ptr = ptr->next;
1026 }
1027 }
1028 if (ptr != nullptr) {
1029 return false;
1030 }
1031
1032 // Check the hash table.
1033 std::vector<SSL_SESSION*> actual, expected_copy;
1034 lh_SSL_SESSION_doall_arg(SSL_CTX_sessions(ctx), AppendSession, &actual);
1035 expected_copy = expected;
1036
1037 std::sort(actual.begin(), actual.end());
1038 std::sort(expected_copy.begin(), expected_copy.end());
1039
1040 return actual == expected_copy;
1041}
1042
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001043static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
1044 bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new());
David Benjamin0f653952015-10-18 14:28:01 -04001045 if (!ret) {
1046 return nullptr;
1047 }
1048
1049 ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
1050 memset(ret->session_id, 0, ret->session_id_length);
1051 memcpy(ret->session_id, &number, sizeof(number));
1052 return ret;
1053}
1054
David Benjamin0f653952015-10-18 14:28:01 -04001055// Test that the internal session cache behaves as expected.
1056static bool TestInternalSessionCache() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001057 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin0f653952015-10-18 14:28:01 -04001058 if (!ctx) {
1059 return false;
1060 }
1061
1062 // Prepare 10 test sessions.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001063 std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
David Benjamin0f653952015-10-18 14:28:01 -04001064 for (int i = 0; i < 10; i++) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001065 bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
David Benjamin0f653952015-10-18 14:28:01 -04001066 if (!session) {
1067 return false;
1068 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001069 sessions.push_back(std::move(session));
David Benjamin0f653952015-10-18 14:28:01 -04001070 }
1071
1072 SSL_CTX_sess_set_cache_size(ctx.get(), 5);
1073
1074 // Insert all the test sessions.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001075 for (const auto &session : sessions) {
1076 if (!SSL_CTX_add_session(ctx.get(), session.get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001077 return false;
1078 }
1079 }
1080
1081 // Only the last five should be in the list.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001082 std::vector<SSL_SESSION*> expected = {
1083 sessions[9].get(),
1084 sessions[8].get(),
1085 sessions[7].get(),
1086 sessions[6].get(),
1087 sessions[5].get(),
1088 };
David Benjamin0f653952015-10-18 14:28:01 -04001089 if (!ExpectCache(ctx.get(), expected)) {
1090 return false;
1091 }
1092
1093 // Inserting an element already in the cache should fail.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001094 if (SSL_CTX_add_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001095 !ExpectCache(ctx.get(), expected)) {
1096 return false;
1097 }
1098
1099 // Although collisions should be impossible (256-bit session IDs), the cache
1100 // must handle them gracefully.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001101 bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
David Benjamin0f653952015-10-18 14:28:01 -04001102 if (!collision || !SSL_CTX_add_session(ctx.get(), collision.get())) {
1103 return false;
1104 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001105 expected = {
1106 collision.get(),
1107 sessions[9].get(),
1108 sessions[8].get(),
1109 sessions[6].get(),
1110 sessions[5].get(),
1111 };
David Benjamin0f653952015-10-18 14:28:01 -04001112 if (!ExpectCache(ctx.get(), expected)) {
1113 return false;
1114 }
1115
1116 // Removing sessions behaves correctly.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001117 if (!SSL_CTX_remove_session(ctx.get(), sessions[6].get())) {
David Benjamin0f653952015-10-18 14:28:01 -04001118 return false;
1119 }
David Benjamin4f6acaf2015-11-21 03:00:50 -05001120 expected = {
1121 collision.get(),
1122 sessions[9].get(),
1123 sessions[8].get(),
1124 sessions[5].get(),
1125 };
David Benjamin0f653952015-10-18 14:28:01 -04001126 if (!ExpectCache(ctx.get(), expected)) {
1127 return false;
1128 }
1129
1130 // Removing sessions requires an exact match.
David Benjamin4f6acaf2015-11-21 03:00:50 -05001131 if (SSL_CTX_remove_session(ctx.get(), sessions[0].get()) ||
1132 SSL_CTX_remove_session(ctx.get(), sessions[7].get()) ||
David Benjamin0f653952015-10-18 14:28:01 -04001133 !ExpectCache(ctx.get(), expected)) {
1134 return false;
1135 }
1136
1137 return true;
1138}
1139
David Benjaminde942382016-02-11 12:02:01 -05001140static uint16_t EpochFromSequence(uint64_t seq) {
1141 return static_cast<uint16_t>(seq >> 48);
1142}
1143
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001144static bssl::UniquePtr<X509> GetTestCertificate() {
David Benjaminde942382016-02-11 12:02:01 -05001145 static const char kCertPEM[] =
1146 "-----BEGIN CERTIFICATE-----\n"
1147 "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1148 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1149 "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1150 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1151 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1152 "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1153 "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1154 "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1155 "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1156 "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1157 "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1158 "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1159 "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1160 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001161 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1162 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjaminde942382016-02-11 12:02:01 -05001163}
1164
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001165static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
David Benjaminde942382016-02-11 12:02:01 -05001166 static const char kKeyPEM[] =
1167 "-----BEGIN RSA PRIVATE KEY-----\n"
1168 "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1169 "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1170 "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1171 "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1172 "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1173 "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1174 "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1175 "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1176 "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1177 "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1178 "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1179 "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1180 "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1181 "-----END RSA PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001182 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1183 return bssl::UniquePtr<EVP_PKEY>(
David Benjaminde942382016-02-11 12:02:01 -05001184 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1185}
1186
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001187static bssl::UniquePtr<X509> GetECDSATestCertificate() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001188 static const char kCertPEM[] =
1189 "-----BEGIN CERTIFICATE-----\n"
1190 "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1191 "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1192 "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1193 "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1194 "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1195 "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1196 "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1197 "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1198 "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1199 "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1200 "-----END CERTIFICATE-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001201 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kCertPEM, strlen(kCertPEM)));
1202 return bssl::UniquePtr<X509>(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
David Benjamin0fc37ef2016-08-17 15:29:46 -04001203}
1204
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001205static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
David Benjamin0fc37ef2016-08-17 15:29:46 -04001206 static const char kKeyPEM[] =
1207 "-----BEGIN PRIVATE KEY-----\n"
1208 "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1209 "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1210 "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1211 "-----END PRIVATE KEY-----\n";
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001212 bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(kKeyPEM, strlen(kKeyPEM)));
1213 return bssl::UniquePtr<EVP_PKEY>(
David Benjamin0fc37ef2016-08-17 15:29:46 -04001214 PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1215}
1216
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001217static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
David Benjamina20e5352016-08-02 19:09:41 -04001218 SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1219 SSL_SESSION *session) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001220 bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
David Benjaminde942382016-02-11 12:02:01 -05001221 if (!client || !server) {
1222 return false;
1223 }
1224 SSL_set_connect_state(client.get());
1225 SSL_set_accept_state(server.get());
1226
David Benjamina20e5352016-08-02 19:09:41 -04001227 SSL_set_session(client.get(), session);
1228
David Benjaminde942382016-02-11 12:02:01 -05001229 BIO *bio1, *bio2;
1230 if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1231 return false;
1232 }
1233 // SSL_set_bio takes ownership.
1234 SSL_set_bio(client.get(), bio1, bio1);
1235 SSL_set_bio(server.get(), bio2, bio2);
1236
1237 // Drive both their handshakes to completion.
1238 for (;;) {
1239 int client_ret = SSL_do_handshake(client.get());
1240 int client_err = SSL_get_error(client.get(), client_ret);
1241 if (client_err != SSL_ERROR_NONE &&
1242 client_err != SSL_ERROR_WANT_READ &&
1243 client_err != SSL_ERROR_WANT_WRITE) {
1244 fprintf(stderr, "Client error: %d\n", client_err);
1245 return false;
1246 }
1247
1248 int server_ret = SSL_do_handshake(server.get());
1249 int server_err = SSL_get_error(server.get(), server_ret);
1250 if (server_err != SSL_ERROR_NONE &&
1251 server_err != SSL_ERROR_WANT_READ &&
1252 server_err != SSL_ERROR_WANT_WRITE) {
1253 fprintf(stderr, "Server error: %d\n", server_err);
1254 return false;
1255 }
1256
1257 if (client_ret == 1 && server_ret == 1) {
1258 break;
1259 }
1260 }
1261
David Benjamin686bb192016-05-10 15:15:41 -04001262 *out_client = std::move(client);
1263 *out_server = std::move(server);
1264 return true;
1265}
1266
1267static bool TestSequenceNumber(bool dtls) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001268 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
1269 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
David Benjamin686bb192016-05-10 15:15:41 -04001270 if (!client_ctx || !server_ctx) {
1271 return false;
1272 }
1273
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001274 bssl::UniquePtr<X509> cert = GetTestCertificate();
1275 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin686bb192016-05-10 15:15:41 -04001276 if (!cert || !key ||
1277 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1278 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1279 return false;
1280 }
1281
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001282 bssl::UniquePtr<SSL> client, server;
David Benjamin686bb192016-05-10 15:15:41 -04001283 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001284 server_ctx.get(), nullptr /* no session */)) {
David Benjamin686bb192016-05-10 15:15:41 -04001285 return false;
1286 }
1287
David Benjaminde942382016-02-11 12:02:01 -05001288 uint64_t client_read_seq = SSL_get_read_sequence(client.get());
1289 uint64_t client_write_seq = SSL_get_write_sequence(client.get());
1290 uint64_t server_read_seq = SSL_get_read_sequence(server.get());
1291 uint64_t server_write_seq = SSL_get_write_sequence(server.get());
1292
1293 if (dtls) {
1294 // Both client and server must be at epoch 1.
1295 if (EpochFromSequence(client_read_seq) != 1 ||
1296 EpochFromSequence(client_write_seq) != 1 ||
1297 EpochFromSequence(server_read_seq) != 1 ||
1298 EpochFromSequence(server_write_seq) != 1) {
1299 fprintf(stderr, "Bad epochs.\n");
1300 return false;
1301 }
1302
1303 // The next record to be written should exceed the largest received.
1304 if (client_write_seq <= server_read_seq ||
1305 server_write_seq <= client_read_seq) {
1306 fprintf(stderr, "Inconsistent sequence numbers.\n");
1307 return false;
1308 }
1309 } else {
1310 // The next record to be written should equal the next to be received.
1311 if (client_write_seq != server_read_seq ||
1312 server_write_seq != client_write_seq) {
1313 fprintf(stderr, "Inconsistent sequence numbers.\n");
1314 return false;
1315 }
1316 }
1317
1318 // Send a record from client to server.
1319 uint8_t byte = 0;
1320 if (SSL_write(client.get(), &byte, 1) != 1 ||
1321 SSL_read(server.get(), &byte, 1) != 1) {
1322 fprintf(stderr, "Could not send byte.\n");
1323 return false;
1324 }
1325
1326 // The client write and server read sequence numbers should have incremented.
1327 if (client_write_seq + 1 != SSL_get_write_sequence(client.get()) ||
1328 server_read_seq + 1 != SSL_get_read_sequence(server.get())) {
1329 fprintf(stderr, "Sequence numbers did not increment.\n");\
1330 return false;
1331 }
1332
1333 return true;
1334}
1335
David Benjamin686bb192016-05-10 15:15:41 -04001336static bool TestOneSidedShutdown() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001337 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1338 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
David Benjamin686bb192016-05-10 15:15:41 -04001339 if (!client_ctx || !server_ctx) {
1340 return false;
1341 }
1342
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001343 bssl::UniquePtr<X509> cert = GetTestCertificate();
1344 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin686bb192016-05-10 15:15:41 -04001345 if (!cert || !key ||
1346 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1347 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1348 return false;
1349 }
1350
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001351 bssl::UniquePtr<SSL> client, server;
David Benjamin686bb192016-05-10 15:15:41 -04001352 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001353 server_ctx.get(), nullptr /* no session */)) {
David Benjamin686bb192016-05-10 15:15:41 -04001354 return false;
1355 }
1356
1357 // Shut down half the connection. SSL_shutdown will return 0 to signal only
1358 // one side has shut down.
1359 if (SSL_shutdown(client.get()) != 0) {
1360 fprintf(stderr, "Could not shutdown.\n");
1361 return false;
1362 }
1363
1364 // Reading from the server should consume the EOF.
1365 uint8_t byte;
1366 if (SSL_read(server.get(), &byte, 1) != 0 ||
1367 SSL_get_error(server.get(), 0) != SSL_ERROR_ZERO_RETURN) {
1368 fprintf(stderr, "Connection was not shut down cleanly.\n");
1369 return false;
1370 }
1371
1372 // However, the server may continue to write data and then shut down the
1373 // connection.
1374 byte = 42;
1375 if (SSL_write(server.get(), &byte, 1) != 1 ||
1376 SSL_read(client.get(), &byte, 1) != 1 ||
1377 byte != 42) {
1378 fprintf(stderr, "Could not send byte.\n");
1379 return false;
1380 }
1381
1382 // The server may then shutdown the connection.
1383 if (SSL_shutdown(server.get()) != 1 ||
1384 SSL_shutdown(client.get()) != 1) {
1385 fprintf(stderr, "Could not complete shutdown.\n");
1386 return false;
1387 }
1388
1389 return true;
1390}
Steven Valdez87eab492016-06-27 16:34:59 -04001391static bool TestSessionDuplication() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001392 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
1393 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
Steven Valdez87eab492016-06-27 16:34:59 -04001394 if (!client_ctx || !server_ctx) {
1395 return false;
1396 }
1397
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001398 bssl::UniquePtr<X509> cert = GetTestCertificate();
1399 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
Steven Valdez87eab492016-06-27 16:34:59 -04001400 if (!cert || !key ||
1401 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1402 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
1403 return false;
1404 }
1405
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001406 bssl::UniquePtr<SSL> client, server;
Steven Valdez87eab492016-06-27 16:34:59 -04001407 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
David Benjamina20e5352016-08-02 19:09:41 -04001408 server_ctx.get(), nullptr /* no session */)) {
Steven Valdez87eab492016-06-27 16:34:59 -04001409 return false;
1410 }
1411
1412 SSL_SESSION *session0 = SSL_get_session(client.get());
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001413 bssl::UniquePtr<SSL_SESSION> session1(SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL));
Steven Valdez87eab492016-06-27 16:34:59 -04001414 if (!session1) {
David Benjamin4501bd52016-08-01 13:39:41 -04001415 return false;
Steven Valdez87eab492016-06-27 16:34:59 -04001416 }
David Benjamin4501bd52016-08-01 13:39:41 -04001417
Steven Valdez84b5c002016-08-25 16:30:58 -04001418 session1->not_resumable = 0;
1419
Steven Valdez87eab492016-06-27 16:34:59 -04001420 uint8_t *s0_bytes, *s1_bytes;
1421 size_t s0_len, s1_len;
1422
1423 if (!SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len)) {
1424 return false;
1425 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001426 bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001427
1428 if (!SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len)) {
1429 return false;
1430 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001431 bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
Steven Valdez87eab492016-06-27 16:34:59 -04001432
1433 return s0_len == s1_len && memcmp(s0_bytes, s1_bytes, s0_len) == 0;
1434}
David Benjamin686bb192016-05-10 15:15:41 -04001435
David Benjamin5c0fb882016-06-14 14:03:51 -04001436static bool ExpectFDs(const SSL *ssl, int rfd, int wfd) {
1437 if (SSL_get_rfd(ssl) != rfd || SSL_get_wfd(ssl) != wfd) {
1438 fprintf(stderr, "Got fds %d and %d, wanted %d and %d.\n", SSL_get_rfd(ssl),
1439 SSL_get_wfd(ssl), rfd, wfd);
1440 return false;
1441 }
1442
1443 // The wrapper BIOs are always equal when fds are equal, even if set
1444 // individually.
1445 if (rfd == wfd && SSL_get_rbio(ssl) != SSL_get_wbio(ssl)) {
1446 fprintf(stderr, "rbio and wbio did not match.\n");
1447 return false;
1448 }
1449
1450 return true;
1451}
1452
1453static bool TestSetFD() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001454 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin5c0fb882016-06-14 14:03:51 -04001455 if (!ctx) {
1456 return false;
1457 }
1458
1459 // Test setting different read and write FDs.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001460 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjamin5c0fb882016-06-14 14:03:51 -04001461 if (!ssl ||
1462 !SSL_set_rfd(ssl.get(), 1) ||
1463 !SSL_set_wfd(ssl.get(), 2) ||
1464 !ExpectFDs(ssl.get(), 1, 2)) {
1465 return false;
1466 }
1467
1468 // Test setting the same FD.
1469 ssl.reset(SSL_new(ctx.get()));
1470 if (!ssl ||
1471 !SSL_set_fd(ssl.get(), 1) ||
1472 !ExpectFDs(ssl.get(), 1, 1)) {
1473 return false;
1474 }
1475
1476 // Test setting the same FD one side at a time.
1477 ssl.reset(SSL_new(ctx.get()));
1478 if (!ssl ||
1479 !SSL_set_rfd(ssl.get(), 1) ||
1480 !SSL_set_wfd(ssl.get(), 1) ||
1481 !ExpectFDs(ssl.get(), 1, 1)) {
1482 return false;
1483 }
1484
1485 // Test setting the same FD in the other order.
1486 ssl.reset(SSL_new(ctx.get()));
1487 if (!ssl ||
1488 !SSL_set_wfd(ssl.get(), 1) ||
1489 !SSL_set_rfd(ssl.get(), 1) ||
1490 !ExpectFDs(ssl.get(), 1, 1)) {
1491 return false;
1492 }
1493
David Benjamin5c0fb882016-06-14 14:03:51 -04001494 // Test changing the read FD partway through.
1495 ssl.reset(SSL_new(ctx.get()));
1496 if (!ssl ||
1497 !SSL_set_fd(ssl.get(), 1) ||
1498 !SSL_set_rfd(ssl.get(), 2) ||
1499 !ExpectFDs(ssl.get(), 2, 1)) {
1500 return false;
1501 }
David Benjamin5c0fb882016-06-14 14:03:51 -04001502
1503 // Test changing the write FD partway through.
1504 ssl.reset(SSL_new(ctx.get()));
1505 if (!ssl ||
1506 !SSL_set_fd(ssl.get(), 1) ||
1507 !SSL_set_wfd(ssl.get(), 2) ||
1508 !ExpectFDs(ssl.get(), 1, 2)) {
1509 return false;
1510 }
1511
1512 // Test a no-op change to the read FD partway through.
1513 ssl.reset(SSL_new(ctx.get()));
1514 if (!ssl ||
1515 !SSL_set_fd(ssl.get(), 1) ||
1516 !SSL_set_rfd(ssl.get(), 1) ||
1517 !ExpectFDs(ssl.get(), 1, 1)) {
1518 return false;
1519 }
1520
1521 // Test a no-op change to the write FD partway through.
1522 ssl.reset(SSL_new(ctx.get()));
1523 if (!ssl ||
1524 !SSL_set_fd(ssl.get(), 1) ||
1525 !SSL_set_wfd(ssl.get(), 1) ||
1526 !ExpectFDs(ssl.get(), 1, 1)) {
1527 return false;
1528 }
1529
1530 // ASan builds will implicitly test that the internal |BIO| reference-counting
1531 // is correct.
1532
1533 return true;
1534}
1535
David Benjamin4501bd52016-08-01 13:39:41 -04001536static bool TestSetBIO() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001537 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin4501bd52016-08-01 13:39:41 -04001538 if (!ctx) {
1539 return false;
1540 }
1541
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001542 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1543 bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
David Benjamin4501bd52016-08-01 13:39:41 -04001544 bio3(BIO_new(BIO_s_mem()));
1545 if (!ssl || !bio1 || !bio2 || !bio3) {
1546 return false;
1547 }
1548
1549 // SSL_set_bio takes one reference when the parameters are the same.
1550 BIO_up_ref(bio1.get());
1551 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1552
1553 // Repeating the call does nothing.
1554 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1555
1556 // It takes one reference each when the parameters are different.
1557 BIO_up_ref(bio2.get());
1558 BIO_up_ref(bio3.get());
1559 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1560
1561 // Repeating the call does nothing.
1562 SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
1563
1564 // It takes one reference when changing only wbio.
1565 BIO_up_ref(bio1.get());
1566 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1567
1568 // It takes one reference when changing only rbio and the two are different.
1569 BIO_up_ref(bio3.get());
1570 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1571
1572 // If setting wbio to rbio, it takes no additional references.
1573 SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
1574
1575 // From there, wbio may be switched to something else.
1576 BIO_up_ref(bio1.get());
1577 SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
1578
1579 // If setting rbio to wbio, it takes no additional references.
1580 SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
1581
1582 // From there, rbio may be switched to something else, but, for historical
1583 // reasons, it takes a reference to both parameters.
1584 BIO_up_ref(bio1.get());
1585 BIO_up_ref(bio2.get());
1586 SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
1587
1588 // ASAN builds will implicitly test that the internal |BIO| reference-counting
1589 // is correct.
1590 return true;
1591}
1592
David Benjamincb18ac22016-09-27 14:09:15 -04001593static uint16_t kTLSVersions[] = {
David Benjamin25490f22016-07-14 00:22:54 -04001594 SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION, TLS1_2_VERSION, TLS1_3_VERSION,
1595};
1596
David Benjamincb18ac22016-09-27 14:09:15 -04001597static uint16_t kDTLSVersions[] = {
1598 DTLS1_VERSION, DTLS1_2_VERSION,
1599};
1600
David Benjamin25490f22016-07-14 00:22:54 -04001601static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
1602
David Benjaminadd5e522016-07-14 00:33:24 -04001603static bool TestGetPeerCertificate() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001604 bssl::UniquePtr<X509> cert = GetTestCertificate();
1605 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjaminadd5e522016-07-14 00:33:24 -04001606 if (!cert || !key) {
1607 return false;
1608 }
1609
David Benjamincb18ac22016-09-27 14:09:15 -04001610 for (uint16_t version : kTLSVersions) {
David Benjaminadd5e522016-07-14 00:33:24 -04001611 // Configure both client and server to accept any certificate.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001612 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjaminadd5e522016-07-14 00:33:24 -04001613 if (!ctx ||
1614 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001615 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04001616 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1617 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
David Benjaminadd5e522016-07-14 00:33:24 -04001618 return false;
1619 }
David Benjaminadd5e522016-07-14 00:33:24 -04001620 SSL_CTX_set_verify(
1621 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1622 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1623
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001624 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001625 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1626 nullptr /* no session */)) {
David Benjaminadd5e522016-07-14 00:33:24 -04001627 return false;
1628 }
1629
1630 // Client and server should both see the leaf certificate.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001631 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
David Benjaminadd5e522016-07-14 00:33:24 -04001632 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1633 fprintf(stderr, "%x: Server peer certificate did not match.\n", version);
1634 return false;
1635 }
1636
1637 peer.reset(SSL_get_peer_certificate(client.get()));
1638 if (!peer || X509_cmp(cert.get(), peer.get()) != 0) {
1639 fprintf(stderr, "%x: Client peer certificate did not match.\n", version);
1640 return false;
1641 }
1642
1643 // However, for historical reasons, the chain includes the leaf on the
1644 // client, but does not on the server.
1645 if (sk_X509_num(SSL_get_peer_cert_chain(client.get())) != 1) {
1646 fprintf(stderr, "%x: Client peer chain was incorrect.\n", version);
1647 return false;
1648 }
1649
1650 if (sk_X509_num(SSL_get_peer_cert_chain(server.get())) != 0) {
1651 fprintf(stderr, "%x: Server peer chain was incorrect.\n", version);
1652 return false;
1653 }
1654 }
1655
1656 return true;
1657}
1658
David Benjamin25490f22016-07-14 00:22:54 -04001659static bool TestRetainOnlySHA256OfCerts() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001660 bssl::UniquePtr<X509> cert = GetTestCertificate();
1661 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin25490f22016-07-14 00:22:54 -04001662 if (!cert || !key) {
1663 return false;
1664 }
1665
1666 uint8_t *cert_der = NULL;
1667 int cert_der_len = i2d_X509(cert.get(), &cert_der);
1668 if (cert_der_len < 0) {
1669 return false;
1670 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001671 bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
David Benjamin25490f22016-07-14 00:22:54 -04001672
1673 uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
1674 SHA256(cert_der, cert_der_len, cert_sha256);
1675
David Benjamincb18ac22016-09-27 14:09:15 -04001676 for (uint16_t version : kTLSVersions) {
David Benjamin25490f22016-07-14 00:22:54 -04001677 // Configure both client and server to accept any certificate, but the
1678 // server must retain only the SHA-256 of the peer.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001679 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin25490f22016-07-14 00:22:54 -04001680 if (!ctx ||
1681 !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001682 !SSL_CTX_use_PrivateKey(ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04001683 !SSL_CTX_set_min_proto_version(ctx.get(), version) ||
1684 !SSL_CTX_set_max_proto_version(ctx.get(), version)) {
David Benjamin25490f22016-07-14 00:22:54 -04001685 return false;
1686 }
David Benjamin25490f22016-07-14 00:22:54 -04001687 SSL_CTX_set_verify(
1688 ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
1689 SSL_CTX_set_cert_verify_callback(ctx.get(), VerifySucceed, NULL);
1690 SSL_CTX_set_retain_only_sha256_of_client_certs(ctx.get(), 1);
1691
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001692 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001693 if (!ConnectClientAndServer(&client, &server, ctx.get(), ctx.get(),
1694 nullptr /* no session */)) {
David Benjamin25490f22016-07-14 00:22:54 -04001695 return false;
1696 }
1697
1698 // The peer certificate has been dropped.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001699 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server.get()));
David Benjamin25490f22016-07-14 00:22:54 -04001700 if (peer) {
1701 fprintf(stderr, "%x: Peer certificate was retained.\n", version);
1702 return false;
1703 }
1704
1705 SSL_SESSION *session = SSL_get_session(server.get());
1706 if (!session->peer_sha256_valid) {
1707 fprintf(stderr, "%x: peer_sha256_valid was not set.\n", version);
1708 return false;
1709 }
1710
1711 if (memcmp(cert_sha256, session->peer_sha256, SHA256_DIGEST_LENGTH) != 0) {
1712 fprintf(stderr, "%x: peer_sha256 did not match.\n", version);
1713 return false;
1714 }
1715 }
1716
1717 return true;
1718}
1719
David Benjaminafc64de2016-07-19 17:12:41 +02001720static bool ClientHelloMatches(uint16_t version, const uint8_t *expected,
1721 size_t expected_len) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001722 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
David Benjamin2dc02042016-09-19 19:57:37 -04001723 if (!ctx ||
David Benjamine4706902016-09-20 15:12:23 -04001724 !SSL_CTX_set_max_proto_version(ctx.get(), version) ||
David Benjamin2dc02042016-09-19 19:57:37 -04001725 // Our default cipher list varies by CPU capabilities, so manually place
1726 // the ChaCha20 ciphers in front.
1727 !SSL_CTX_set_cipher_list(ctx.get(), "CHACHA20:ALL")) {
David Benjaminafc64de2016-07-19 17:12:41 +02001728 return false;
1729 }
David Benjamin2dc02042016-09-19 19:57:37 -04001730
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001731 bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
David Benjaminafc64de2016-07-19 17:12:41 +02001732 if (!ssl) {
1733 return false;
1734 }
1735 std::vector<uint8_t> client_hello;
1736 if (!GetClientHello(ssl.get(), &client_hello)) {
1737 return false;
1738 }
1739
1740 // Zero the client_random.
1741 constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
1742 1 + 3 + // handshake message header
1743 2; // client_version
1744 if (client_hello.size() < kRandomOffset + SSL3_RANDOM_SIZE) {
1745 fprintf(stderr, "ClientHello for version %04x too short.\n", version);
1746 return false;
1747 }
1748 memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
1749
1750 if (client_hello.size() != expected_len ||
1751 memcmp(client_hello.data(), expected, expected_len) != 0) {
1752 fprintf(stderr, "ClientHello for version %04x did not match:\n", version);
1753 fprintf(stderr, "Got:\n\t");
1754 for (size_t i = 0; i < client_hello.size(); i++) {
1755 fprintf(stderr, "0x%02x, ", client_hello[i]);
1756 }
1757 fprintf(stderr, "\nWanted:\n\t");
1758 for (size_t i = 0; i < expected_len; i++) {
1759 fprintf(stderr, "0x%02x, ", expected[i]);
1760 }
1761 fprintf(stderr, "\n");
1762 return false;
1763 }
1764
1765 return true;
1766}
1767
1768// Tests that our ClientHellos do not change unexpectedly.
1769static bool TestClientHello() {
1770 static const uint8_t kSSL3ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001771 0x16,
1772 0x03, 0x00,
1773 0x00, 0x3f,
1774 0x01,
1775 0x00, 0x00, 0x3b,
1776 0x03, 0x00,
1777 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1778 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1779 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1780 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1781 0x00,
1782 0x00, 0x14,
1783 0xc0, 0x09,
1784 0xc0, 0x13,
1785 0x00, 0x33,
1786 0xc0, 0x0a,
1787 0xc0, 0x14,
1788 0x00, 0x39,
1789 0x00, 0x2f,
1790 0x00, 0x35,
1791 0x00, 0x0a,
1792 0x00, 0xff, 0x01, 0x00,
David Benjaminafc64de2016-07-19 17:12:41 +02001793 };
1794 if (!ClientHelloMatches(SSL3_VERSION, kSSL3ClientHello,
1795 sizeof(kSSL3ClientHello))) {
1796 return false;
1797 }
1798
1799 static const uint8_t kTLS1ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001800 0x16,
1801 0x03, 0x01,
1802 0x00, 0x5e,
1803 0x01,
1804 0x00, 0x00, 0x5a,
1805 0x03, 0x01,
1806 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1807 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1808 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1809 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1810 0x00,
1811 0x00, 0x12,
1812 0xc0, 0x09,
1813 0xc0, 0x13,
1814 0x00, 0x33,
1815 0xc0, 0x0a,
1816 0xc0, 0x14,
1817 0x00, 0x39,
1818 0x00, 0x2f,
1819 0x00, 0x35,
1820 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001821 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1822 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1823 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1824 };
1825 if (!ClientHelloMatches(TLS1_VERSION, kTLS1ClientHello,
1826 sizeof(kTLS1ClientHello))) {
1827 return false;
1828 }
1829
1830 static const uint8_t kTLS11ClientHello[] = {
Matt Braithwaite9c8c4182016-08-24 14:36:54 -07001831 0x16,
1832 0x03, 0x01,
1833 0x00, 0x5e,
1834 0x01,
1835 0x00, 0x00, 0x5a,
1836 0x03, 0x02,
1837 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1838 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1839 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1840 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1841 0x00,
1842 0x00, 0x12,
1843 0xc0, 0x09,
1844 0xc0, 0x13,
1845 0x00, 0x33,
1846 0xc0, 0x0a,
1847 0xc0, 0x14,
1848 0x00, 0x39,
1849 0x00, 0x2f,
1850 0x00, 0x35,
1851 0x00, 0x0a,
David Benjaminafc64de2016-07-19 17:12:41 +02001852 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
1853 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1854 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
1855 };
1856 if (!ClientHelloMatches(TLS1_1_VERSION, kTLS11ClientHello,
1857 sizeof(kTLS11ClientHello))) {
1858 return false;
1859 }
1860
1861 static const uint8_t kTLS12ClientHello[] = {
David Benjamin57e929f2016-08-30 00:30:38 -04001862 0x16, 0x03, 0x01, 0x00, 0xa2, 0x01, 0x00, 0x00, 0x9e, 0x03, 0x03, 0x00,
1863 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1864 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1865 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0xcc, 0xa9,
1866 0xcc, 0xa8, 0xcc, 0x14, 0xcc, 0x13, 0xc0, 0x2b, 0xc0, 0x2f, 0x00, 0x9e,
1867 0xc0, 0x2c, 0xc0, 0x30, 0x00, 0x9f, 0xc0, 0x09, 0xc0, 0x23, 0xc0, 0x13,
1868 0xc0, 0x27, 0x00, 0x33, 0x00, 0x67, 0xc0, 0x0a, 0xc0, 0x24, 0xc0, 0x14,
1869 0xc0, 0x28, 0x00, 0x39, 0x00, 0x6b, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
1870 0x00, 0x3c, 0x00, 0x35, 0x00, 0x3d, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x3b,
1871 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00,
David Benjaminaf56fbd2016-09-21 14:38:06 -04001872 0x00, 0x00, 0x0d, 0x00, 0x18, 0x00, 0x16, 0x08, 0x06, 0x06, 0x01, 0x06,
1873 0x03, 0x08, 0x05, 0x05, 0x01, 0x05, 0x03, 0x08, 0x04, 0x04, 0x01, 0x04,
David Benjamin57e929f2016-08-30 00:30:38 -04001874 0x03, 0x02, 0x01, 0x02, 0x03, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
1875 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
David Benjaminafc64de2016-07-19 17:12:41 +02001876 };
1877 if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
1878 sizeof(kTLS12ClientHello))) {
1879 return false;
1880 }
1881
1882 // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
1883 // implementation has settled enough that it won't change.
1884
1885 return true;
1886}
1887
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001888static bssl::UniquePtr<SSL_SESSION> g_last_session;
David Benjamina20e5352016-08-02 19:09:41 -04001889
1890static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
1891 // Save the most recent session.
1892 g_last_session.reset(session);
1893 return 1;
1894}
1895
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001896static bssl::UniquePtr<SSL_SESSION> CreateClientSession(SSL_CTX *client_ctx,
David Benjamina20e5352016-08-02 19:09:41 -04001897 SSL_CTX *server_ctx) {
1898 g_last_session = nullptr;
1899 SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
1900
1901 // Connect client and server to get a session.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001902 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001903 if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
1904 nullptr /* no session */)) {
1905 fprintf(stderr, "Failed to connect client and server.\n");
1906 return nullptr;
1907 }
1908
1909 // Run the read loop to account for post-handshake tickets in TLS 1.3.
1910 SSL_read(client.get(), nullptr, 0);
1911
1912 SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
1913
1914 if (!g_last_session) {
1915 fprintf(stderr, "Client did not receive a session.\n");
1916 return nullptr;
1917 }
1918 return std::move(g_last_session);
1919}
1920
1921static bool ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1922 SSL_SESSION *session,
1923 bool reused) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001924 bssl::UniquePtr<SSL> client, server;
David Benjamina20e5352016-08-02 19:09:41 -04001925 if (!ConnectClientAndServer(&client, &server, client_ctx,
1926 server_ctx, session)) {
1927 fprintf(stderr, "Failed to connect client and server.\n");
1928 return false;
1929 }
1930
1931 if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
1932 fprintf(stderr, "Client and server were inconsistent.\n");
1933 return false;
1934 }
1935
1936 bool was_reused = !!SSL_session_reused(client.get());
1937 if (was_reused != reused) {
1938 fprintf(stderr, "Session was%s reused, but we expected the opposite.\n",
1939 was_reused ? "" : " not");
1940 return false;
1941 }
1942
1943 return true;
1944}
1945
1946static bool TestSessionIDContext() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001947 bssl::UniquePtr<X509> cert = GetTestCertificate();
1948 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamina20e5352016-08-02 19:09:41 -04001949 if (!cert || !key) {
1950 return false;
1951 }
1952
1953 static const uint8_t kContext1[] = {1};
1954 static const uint8_t kContext2[] = {2};
1955
David Benjamincb18ac22016-09-27 14:09:15 -04001956 for (uint16_t version : kTLSVersions) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001957 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
1958 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamina20e5352016-08-02 19:09:41 -04001959 if (!server_ctx || !client_ctx ||
1960 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
1961 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
1962 !SSL_CTX_set_session_id_context(server_ctx.get(), kContext1,
David Benjamin2dc02042016-09-19 19:57:37 -04001963 sizeof(kContext1)) ||
David Benjamine4706902016-09-20 15:12:23 -04001964 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
1965 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
1966 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
1967 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
David Benjamina20e5352016-08-02 19:09:41 -04001968 return false;
1969 }
1970
David Benjamina20e5352016-08-02 19:09:41 -04001971 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
David Benjamina20e5352016-08-02 19:09:41 -04001972 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
1973
Matt Braithwaited17d74d2016-08-17 20:10:28 -07001974 bssl::UniquePtr<SSL_SESSION> session =
David Benjamina20e5352016-08-02 19:09:41 -04001975 CreateClientSession(client_ctx.get(), server_ctx.get());
1976 if (!session) {
1977 fprintf(stderr, "Error getting session (version = %04x).\n", version);
1978 return false;
1979 }
1980
1981 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1982 true /* expect session reused */)) {
1983 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
1984 return false;
1985 }
1986
1987 // Change the session ID context.
1988 if (!SSL_CTX_set_session_id_context(server_ctx.get(), kContext2,
1989 sizeof(kContext2))) {
1990 return false;
1991 }
1992
1993 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
1994 false /* expect session not reused */)) {
1995 fprintf(stderr,
1996 "Error connection with different context (version = %04x).\n",
1997 version);
1998 return false;
1999 }
2000 }
2001
2002 return true;
2003}
2004
David Benjamin721e8b72016-08-03 13:13:17 -04002005static timeval g_current_time;
2006
2007static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
2008 *out_clock = g_current_time;
2009}
2010
2011static bool TestSessionTimeout() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002012 bssl::UniquePtr<X509> cert = GetTestCertificate();
2013 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
David Benjamin721e8b72016-08-03 13:13:17 -04002014 if (!cert || !key) {
2015 return false;
2016 }
2017
David Benjamincb18ac22016-09-27 14:09:15 -04002018 for (uint16_t version : kTLSVersions) {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002019 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2020 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin721e8b72016-08-03 13:13:17 -04002021 if (!server_ctx || !client_ctx ||
2022 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04002023 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04002024 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2025 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2026 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2027 !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
David Benjamin721e8b72016-08-03 13:13:17 -04002028 return false;
2029 }
2030
David Benjamin721e8b72016-08-03 13:13:17 -04002031 SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
2032
David Benjamin721e8b72016-08-03 13:13:17 -04002033 SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
2034 SSL_CTX_set_current_time_cb(server_ctx.get(), CurrentTimeCallback);
2035
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002036 bssl::UniquePtr<SSL_SESSION> session =
David Benjamin721e8b72016-08-03 13:13:17 -04002037 CreateClientSession(client_ctx.get(), server_ctx.get());
2038 if (!session) {
2039 fprintf(stderr, "Error getting session (version = %04x).\n", version);
2040 return false;
2041 }
2042
2043 // Advance the clock just behind the timeout.
2044 g_current_time.tv_sec += SSL_DEFAULT_SESSION_TIMEOUT;
2045
2046 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2047 true /* expect session reused */)) {
2048 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
2049 return false;
2050 }
2051
2052 // Advance the clock one more second.
2053 g_current_time.tv_sec++;
2054
2055 if (!ExpectSessionReused(client_ctx.get(), server_ctx.get(), session.get(),
2056 false /* expect session not reused */)) {
2057 fprintf(stderr, "Error resuming session (version = %04x).\n", version);
2058 return false;
2059 }
2060 }
2061
2062 return true;
2063}
2064
David Benjamin0fc37ef2016-08-17 15:29:46 -04002065static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
2066 SSL_CTX *ctx = reinterpret_cast<SSL_CTX*>(arg);
2067 SSL_set_SSL_CTX(ssl, ctx);
2068 return SSL_TLSEXT_ERR_OK;
2069}
2070
2071static bool TestSNICallback() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002072 bssl::UniquePtr<X509> cert = GetTestCertificate();
2073 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2074 bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
2075 bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
David Benjamin0fc37ef2016-08-17 15:29:46 -04002076 if (!cert || !key || !cert2 || !key2) {
2077 return false;
2078 }
2079
2080 // At each version, test that switching the |SSL_CTX| at the SNI callback
2081 // behaves correctly.
David Benjamincb18ac22016-09-27 14:09:15 -04002082 for (uint16_t version : kTLSVersions) {
David Benjamin0fc37ef2016-08-17 15:29:46 -04002083 if (version == SSL3_VERSION) {
2084 continue;
2085 }
2086
2087 static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
2088
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002089 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2090 bssl::UniquePtr<SSL_CTX> server_ctx2(SSL_CTX_new(TLS_method()));
2091 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002092 if (!server_ctx || !server_ctx2 || !client_ctx ||
2093 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2094 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2095 !SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()) ||
2096 !SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()) ||
2097 // Historically signing preferences would be lost in some cases with the
2098 // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
2099 // this doesn't happen when |version| is TLS 1.2, configure the private
2100 // key to only sign SHA-256.
2101 !SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
David Benjamin2dc02042016-09-19 19:57:37 -04002102 &kECDSAWithSHA256, 1) ||
David Benjamine4706902016-09-20 15:12:23 -04002103 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2104 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2105 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2106 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2107 !SSL_CTX_set_min_proto_version(server_ctx2.get(), version) ||
2108 !SSL_CTX_set_max_proto_version(server_ctx2.get(), version)) {
David Benjamin0fc37ef2016-08-17 15:29:46 -04002109 return false;
2110 }
2111
David Benjamin0fc37ef2016-08-17 15:29:46 -04002112 SSL_CTX_set_tlsext_servername_callback(server_ctx.get(), SwitchContext);
2113 SSL_CTX_set_tlsext_servername_arg(server_ctx.get(), server_ctx2.get());
2114
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002115 bssl::UniquePtr<SSL> client, server;
David Benjamin0fc37ef2016-08-17 15:29:46 -04002116 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2117 server_ctx.get(), nullptr)) {
2118 fprintf(stderr, "Handshake failed at version %04x.\n", version);
2119 return false;
2120 }
2121
2122 // The client should have received |cert2|.
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002123 bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client.get()));
David Benjamin0fc37ef2016-08-17 15:29:46 -04002124 if (!peer ||
2125 X509_cmp(peer.get(), cert2.get()) != 0) {
2126 fprintf(stderr, "Incorrect certificate received at version %04x.\n",
2127 version);
2128 return false;
2129 }
2130 }
2131
2132 return true;
2133}
2134
David Benjamin99620572016-08-30 00:35:36 -04002135static int SetMaxVersion(const struct ssl_early_callback_ctx *ctx) {
David Benjamine4706902016-09-20 15:12:23 -04002136 if (!SSL_set_max_proto_version(ctx->ssl, TLS1_2_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002137 return -1;
2138 }
2139
David Benjamin99620572016-08-30 00:35:36 -04002140 return 1;
2141}
2142
2143// TestEarlyCallbackVersionSwitch tests that the early callback can swap the
2144// maximum version.
2145static bool TestEarlyCallbackVersionSwitch() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002146 bssl::UniquePtr<X509> cert = GetTestCertificate();
2147 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2148 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
2149 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
David Benjamin99620572016-08-30 00:35:36 -04002150 if (!cert || !key || !server_ctx || !client_ctx ||
2151 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
David Benjamin2dc02042016-09-19 19:57:37 -04002152 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
David Benjamine4706902016-09-20 15:12:23 -04002153 !SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION) ||
2154 !SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION)) {
David Benjamin99620572016-08-30 00:35:36 -04002155 return false;
2156 }
2157
David Benjamin99620572016-08-30 00:35:36 -04002158 SSL_CTX_set_select_certificate_cb(server_ctx.get(), SetMaxVersion);
2159
Matt Braithwaited17d74d2016-08-17 20:10:28 -07002160 bssl::UniquePtr<SSL> client, server;
David Benjamin99620572016-08-30 00:35:36 -04002161 if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
2162 server_ctx.get(), nullptr)) {
2163 return false;
2164 }
2165
2166 if (SSL_version(client.get()) != TLS1_2_VERSION) {
2167 fprintf(stderr, "Early callback failed to switch the maximum version.\n");
2168 return false;
2169 }
2170
2171 return true;
2172}
2173
David Benjamin2dc02042016-09-19 19:57:37 -04002174static bool TestSetVersion() {
2175 bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2176 if (!ctx) {
2177 return false;
2178 }
2179
David Benjamine4706902016-09-20 15:12:23 -04002180 if (!SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION) ||
2181 !SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION) ||
2182 !SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION) ||
2183 !SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002184 fprintf(stderr, "Could not set valid TLS version.\n");
2185 return false;
2186 }
2187
David Benjamine4706902016-09-20 15:12:23 -04002188 if (SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION) ||
2189 SSL_CTX_set_max_proto_version(ctx.get(), 0x0200) ||
2190 SSL_CTX_set_max_proto_version(ctx.get(), 0x1234) ||
2191 SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION) ||
2192 SSL_CTX_set_min_proto_version(ctx.get(), 0x0200) ||
2193 SSL_CTX_set_min_proto_version(ctx.get(), 0x1234)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002194 fprintf(stderr, "Unexpectedly set invalid TLS version.\n");
2195 return false;
2196 }
2197
David Benjamine34bcc92016-09-21 16:53:09 -04002198 if (!SSL_CTX_set_max_proto_version(ctx.get(), 0) ||
2199 !SSL_CTX_set_min_proto_version(ctx.get(), 0)) {
2200 fprintf(stderr, "Could not set default TLS version.\n");
2201 return false;
2202 }
2203
2204 if (ctx->min_version != SSL3_VERSION ||
2205 ctx->max_version != TLS1_2_VERSION) {
2206 fprintf(stderr, "Default TLS versions were incorrect (%04x and %04x).\n",
2207 ctx->min_version, ctx->max_version);
2208 return false;
2209 }
2210
David Benjamin2dc02042016-09-19 19:57:37 -04002211 ctx.reset(SSL_CTX_new(DTLS_method()));
2212 if (!ctx) {
2213 return false;
2214 }
2215
David Benjamine4706902016-09-20 15:12:23 -04002216 if (!SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION) ||
2217 !SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_2_VERSION) ||
2218 !SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION) ||
2219 !SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_2_VERSION)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002220 fprintf(stderr, "Could not set valid DTLS version.\n");
2221 return false;
2222 }
2223
David Benjamine4706902016-09-20 15:12:23 -04002224 if (SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION) ||
2225 SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */) ||
2226 SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */) ||
2227 SSL_CTX_set_max_proto_version(ctx.get(), 0x1234) ||
2228 SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION) ||
2229 SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */) ||
2230 SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */) ||
2231 SSL_CTX_set_min_proto_version(ctx.get(), 0x1234)) {
David Benjamin2dc02042016-09-19 19:57:37 -04002232 fprintf(stderr, "Unexpectedly set invalid DTLS version.\n");
2233 return false;
2234 }
2235
David Benjamine34bcc92016-09-21 16:53:09 -04002236 if (!SSL_CTX_set_max_proto_version(ctx.get(), 0) ||
2237 !SSL_CTX_set_min_proto_version(ctx.get(), 0)) {
2238 fprintf(stderr, "Could not set default DTLS version.\n");
2239 return false;
2240 }
2241
2242 if (ctx->min_version != TLS1_1_VERSION ||
2243 ctx->max_version != TLS1_2_VERSION) {
2244 fprintf(stderr, "Default DTLS versions were incorrect (%04x and %04x).\n",
2245 ctx->min_version, ctx->max_version);
2246 return false;
2247 }
2248
David Benjamin2dc02042016-09-19 19:57:37 -04002249 return true;
2250}
2251
David Benjamincb18ac22016-09-27 14:09:15 -04002252static bool TestVersions() {
2253 bssl::UniquePtr<X509> cert = GetTestCertificate();
2254 bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
2255 if (!cert || !key) {
2256 return false;
2257 }
2258
2259 for (bool is_dtls : std::vector<bool>{false, true}) {
2260 const SSL_METHOD *method = is_dtls ? DTLS_method() : TLS_method();
2261 const char *name = is_dtls ? "DTLS" : "TLS";
2262 const uint16_t *versions = is_dtls ? kDTLSVersions : kTLSVersions;
2263 size_t num_versions = is_dtls ? OPENSSL_ARRAY_SIZE(kDTLSVersions)
2264 : OPENSSL_ARRAY_SIZE(kTLSVersions);
2265 for (size_t i = 0; i < num_versions; i++) {
2266 uint16_t version = versions[i];
2267 bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
2268 bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
2269 bssl::UniquePtr<SSL> client, server;
2270 if (!server_ctx || !client_ctx ||
2271 !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
2272 !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()) ||
2273 !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
2274 !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
2275 !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
2276 !SSL_CTX_set_max_proto_version(server_ctx.get(), version) ||
2277 !ConnectClientAndServer(&client, &server, client_ctx.get(),
2278 server_ctx.get(), nullptr /* no session */)) {
2279 fprintf(stderr, "Failed to connect %s at version %04x.\n", name,
2280 version);
2281 return false;
2282 }
2283
2284 if (SSL_version(client.get()) != version ||
2285 SSL_version(server.get()) != version) {
2286 fprintf(stderr,
2287 "%s version mismatch. Got %04x and %04x, wanted %04x.\n", name,
2288 SSL_version(client.get()), SSL_version(server.get()), version);
2289 return false;
2290 }
2291 }
2292 }
2293
2294 return true;
2295}
2296
David Benjamin1d128f32015-09-08 17:41:40 -04002297int main() {
David Benjamin7a1eefd2015-10-17 23:39:22 -04002298 CRYPTO_library_init();
David Benjaminbb0a17c2014-09-20 15:35:39 -04002299
Adam Langley10f97f32016-07-12 08:09:33 -07002300 if (!TestCipherRules() ||
Alessandro Ghedini5fd18072016-09-28 21:04:25 +01002301 !TestCurveRules() ||
Adam Langley10f97f32016-07-12 08:09:33 -07002302 !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
2303 !TestSSL_SESSIONEncoding(kCustomSession) ||
2304 !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
2305 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
2306 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
2307 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
David Benjamin10e664b2016-06-20 22:20:47 -04002308 // TODO(svaldez): Update this when TLS 1.3 is enabled by default.
Adam Langley10f97f32016-07-12 08:09:33 -07002309 !TestDefaultVersion(SSL3_VERSION, TLS1_2_VERSION, &TLS_method) ||
2310 !TestDefaultVersion(SSL3_VERSION, SSL3_VERSION, &SSLv3_method) ||
2311 !TestDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method) ||
2312 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method) ||
2313 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method) ||
2314 !TestDefaultVersion(TLS1_1_VERSION, TLS1_2_VERSION, &DTLS_method) ||
2315 !TestDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &DTLSv1_method) ||
2316 !TestDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &DTLSv1_2_method) ||
2317 !TestCipherGetRFCName() ||
2318 !TestPaddingExtension() ||
2319 !TestClientCAList() ||
2320 !TestInternalSessionCache() ||
2321 !TestSequenceNumber(false /* TLS */) ||
2322 !TestSequenceNumber(true /* DTLS */) ||
2323 !TestOneSidedShutdown() ||
Steven Valdez87eab492016-06-27 16:34:59 -04002324 !TestSessionDuplication() ||
David Benjamin25490f22016-07-14 00:22:54 -04002325 !TestSetFD() ||
David Benjamin4501bd52016-08-01 13:39:41 -04002326 !TestSetBIO() ||
David Benjaminadd5e522016-07-14 00:33:24 -04002327 !TestGetPeerCertificate() ||
David Benjaminafc64de2016-07-19 17:12:41 +02002328 !TestRetainOnlySHA256OfCerts() ||
David Benjamina20e5352016-08-02 19:09:41 -04002329 !TestClientHello() ||
David Benjamin721e8b72016-08-03 13:13:17 -04002330 !TestSessionIDContext() ||
David Benjamin0fc37ef2016-08-17 15:29:46 -04002331 !TestSessionTimeout() ||
David Benjamin99620572016-08-30 00:35:36 -04002332 !TestSNICallback() ||
David Benjamin2dc02042016-09-19 19:57:37 -04002333 !TestEarlyCallbackVersionSwitch() ||
David Benjamincb18ac22016-09-27 14:09:15 -04002334 !TestSetVersion() ||
2335 !TestVersions()) {
Brian Smith83a82982015-04-09 16:21:10 -10002336 ERR_print_errors_fp(stderr);
David Benjaminbb0a17c2014-09-20 15:35:39 -04002337 return 1;
2338 }
2339
David Benjamin2e521212014-07-16 14:37:51 -04002340 printf("PASS\n");
2341 return 0;
2342}