1/* 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> 16#include <string.h> 17#include <time.h> 18 19#include <algorithm> 20#include <string> 21#include <vector> 22 23#include <openssl/base64.h> 24#include <openssl/bio.h> 25#include <openssl/crypto.h> 26#include <openssl/err.h> 27#include <openssl/ssl.h> 28 29#include "test/scoped_types.h" 30#include "../crypto/test/test_util.h" 31 32 33struct ExpectedCipher { 34 unsigned long id; 35 int in_group_flag; 36}; 37 38struct CipherTest { 39 // The rule string to apply. 40 const char *rule; 41 // The list of expected ciphers, in order, terminated with -1. 42 const ExpectedCipher *expected; 43}; 44 45// Selecting individual ciphers should work. 46static const char kRule1[] = 47 "ECDHE-ECDSA-CHACHA20-POLY1305:" 48 "ECDHE-RSA-CHACHA20-POLY1305:" 49 "ECDHE-ECDSA-AES128-GCM-SHA256:" 50 "ECDHE-RSA-AES128-GCM-SHA256"; 51 52static const ExpectedCipher kExpected1[] = { 53 { TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0 }, 54 { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0 }, 55 { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0 }, 56 { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 }, 57 { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 }, 58 { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 }, 59 { 0, 0 }, 60}; 61 62// + reorders selected ciphers to the end, keeping their relative 63// order. 64static const char kRule2[] = 65 "ECDHE-ECDSA-CHACHA20-POLY1305:" 66 "ECDHE-RSA-CHACHA20-POLY1305:" 67 "ECDHE-ECDSA-AES128-GCM-SHA256:" 68 "ECDHE-RSA-AES128-GCM-SHA256:" 69 "+aRSA"; 70 71static const ExpectedCipher kExpected2[] = { 72 { TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0 }, 73 { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0 }, 74 { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 }, 75 { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0 }, 76 { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 }, 77 { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 }, 78 { 0, 0 }, 79}; 80 81// ! banishes ciphers from future selections. 82static const char kRule3[] = 83 "!aRSA:" 84 "ECDHE-ECDSA-CHACHA20-POLY1305:" 85 "ECDHE-RSA-CHACHA20-POLY1305:" 86 "ECDHE-ECDSA-AES128-GCM-SHA256:" 87 "ECDHE-RSA-AES128-GCM-SHA256"; 88 89static const ExpectedCipher kExpected3[] = { 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 { 0, 0 }, 94}; 95 96// Multiple masks can be ANDed in a single rule. 97static const char kRule4[] = "kRSA+AESGCM+AES128"; 98 99static const ExpectedCipher kExpected4[] = { 100 { TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0 }, 101 { 0, 0 }, 102}; 103 104// - removes selected ciphers, but preserves their order for future 105// selections. Select AES_128_GCM, but order the key exchanges RSA, 106// DHE_RSA, ECDHE_RSA. 107static const char kRule5[] = 108 "ALL:-kECDHE:-kDHE:-kRSA:-ALL:" 109 "AESGCM+AES128+aRSA"; 110 111static const ExpectedCipher kExpected5[] = { 112 { TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0 }, 113 { TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, 0 }, 114 { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 }, 115 { 0, 0 }, 116}; 117 118// Unknown selectors are no-ops. 119static const char kRule6[] = 120 "ECDHE-ECDSA-CHACHA20-POLY1305:" 121 "ECDHE-RSA-CHACHA20-POLY1305:" 122 "ECDHE-ECDSA-AES128-GCM-SHA256:" 123 "ECDHE-RSA-AES128-GCM-SHA256:" 124 "BOGUS1:-BOGUS2:+BOGUS3:!BOGUS4"; 125 126static const ExpectedCipher kExpected6[] = { 127 { TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0 }, 128 { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0 }, 129 { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0 }, 130 { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 }, 131 { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 }, 132 { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 }, 133 { 0, 0 }, 134}; 135 136// Square brackets specify equi-preference groups. 137static const char kRule7[] = 138 "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:" 139 "[ECDHE-RSA-CHACHA20-POLY1305]:" 140 "ECDHE-RSA-AES128-GCM-SHA256"; 141 142static const ExpectedCipher kExpected7[] = { 143 { TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1 }, 144 { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 1 }, 145 { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 }, 146 { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 1 }, 147 { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 }, 148 { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 }, 149 { 0, 0 }, 150}; 151 152// @STRENGTH performs a stable strength-sort of the selected 153// ciphers and only the selected ciphers. 154static const char kRule8[] = 155 // To simplify things, banish all but {ECDHE_RSA,RSA} x 156 // {CHACHA20,AES_256_CBC,AES_128_CBC,RC4} x SHA1. 157 "!kEDH:!AESGCM:!3DES:!SHA256:!MD5:!SHA384:" 158 // Order some ciphers backwards by strength. 159 "ALL:-CHACHA20:-AES256:-AES128:-RC4:-ALL:" 160 // Select ECDHE ones and sort them by strength. Ties should resolve 161 // based on the order above. 162 "kECDHE:@STRENGTH:-ALL:" 163 // Now bring back everything uses RSA. ECDHE_RSA should be first, 164 // sorted by strength. Then RSA, backwards by strength. 165 "aRSA"; 166 167static const ExpectedCipher kExpected8[] = { 168 { TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0 }, 169 { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0 }, 170 { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 }, 171 { TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA, 0 }, 172 { TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0 }, 173 { SSL3_CK_RSA_RC4_128_SHA, 0 }, 174 { TLS1_CK_RSA_WITH_AES_128_SHA, 0 }, 175 { TLS1_CK_RSA_WITH_AES_256_SHA, 0 }, 176 { 0, 0 }, 177}; 178 179// Exact ciphers may not be used in multi-part rules; they are treated 180// as unknown aliases. 181static const char kRule9[] = 182 "ECDHE-ECDSA-AES128-GCM-SHA256:" 183 "ECDHE-RSA-AES128-GCM-SHA256:" 184 "!ECDHE-RSA-AES128-GCM-SHA256+RSA:" 185 "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256"; 186 187static const ExpectedCipher kExpected9[] = { 188 { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 }, 189 { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 }, 190 { 0, 0 }, 191}; 192 193// SSLv3 matches everything that existed before TLS 1.2. 194static const char kRule10[] = "AES128-SHA:AES128-SHA256:!SSLv3"; 195 196static const ExpectedCipher kExpected10[] = { 197 { TLS1_CK_RSA_WITH_AES_128_SHA256, 0 }, 198 { 0, 0 }, 199}; 200 201// TLSv1.2 matches everything added in TLS 1.2. 202static const char kRule11[] = "AES128-SHA:AES128-SHA256:!TLSv1.2"; 203 204static const ExpectedCipher kExpected11[] = { 205 { TLS1_CK_RSA_WITH_AES_128_SHA, 0 }, 206 { 0, 0 }, 207}; 208 209// The two directives have no intersection. 210static const char kRule12[] = "AES128-SHA:AES128-SHA256:!TLSv1.2+SSLv3"; 211 212static const ExpectedCipher kExpected12[] = { 213 { TLS1_CK_RSA_WITH_AES_128_SHA, 0 }, 214 { TLS1_CK_RSA_WITH_AES_128_SHA256, 0 }, 215 { 0, 0 }, 216}; 217 218// The shared name of the CHACHA20_POLY1305 variants behaves like a cipher name 219// and not an alias. It may not be used in a multipart rule. (That the shared 220// name works is covered by the standard tests.) 221static const char kRule13[] = 222 "ECDHE-ECDSA-CHACHA20-POLY1305:" 223 "ECDHE-RSA-CHACHA20-POLY1305:" 224 "!ECDHE-RSA-CHACHA20-POLY1305+RSA:" 225 "!ECDSA+ECDHE-ECDSA-CHACHA20-POLY1305"; 226 227static const ExpectedCipher kExpected13[] = { 228 { TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0 }, 229 { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 0 }, 230 { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0 }, 231 { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 0 }, 232 { 0, 0 }, 233}; 234 235static CipherTest kCipherTests[] = { 236 { kRule1, kExpected1 }, 237 { kRule2, kExpected2 }, 238 { kRule3, kExpected3 }, 239 { kRule4, kExpected4 }, 240 { kRule5, kExpected5 }, 241 { kRule6, kExpected6 }, 242 { kRule7, kExpected7 }, 243 { kRule8, kExpected8 }, 244 { kRule9, kExpected9 }, 245 { kRule10, kExpected10 }, 246 { kRule11, kExpected11 }, 247 { kRule12, kExpected12 }, 248 { kRule13, kExpected13 }, 249 { NULL, NULL }, 250}; 251 252static const char *kBadRules[] = { 253 // Invalid brackets. 254 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256", 255 "RSA]", 256 "[[RSA]]", 257 // Operators inside brackets. 258 "[+RSA]", 259 // Unknown directive. 260 "@BOGUS", 261 // Empty cipher lists error at SSL_CTX_set_cipher_list. 262 "", 263 "BOGUS", 264 // COMPLEMENTOFDEFAULT is empty. 265 "COMPLEMENTOFDEFAULT", 266 // Invalid command. 267 "?BAR", 268 // Special operators are not allowed if groups are used. 269 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO", 270 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO", 271 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO", 272 "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH", 273 NULL, 274}; 275 276static const char *kMustNotIncludeNull[] = { 277 "ALL", 278 "DEFAULT", 279 "ALL:!eNULL", 280 "ALL:!NULL", 281 "MEDIUM", 282 "HIGH", 283 "FIPS", 284 "SHA", 285 "SHA1", 286 "RSA", 287 "SSLv3", 288 "TLSv1", 289 "TLSv1.2", 290 NULL 291}; 292 293static void PrintCipherPreferenceList(ssl_cipher_preference_list_st *list) { 294 bool in_group = false; 295 for (size_t i = 0; i < sk_SSL_CIPHER_num(list->ciphers); i++) { 296 const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(list->ciphers, i); 297 if (!in_group && list->in_group_flags[i]) { 298 fprintf(stderr, "\t[\n"); 299 in_group = true; 300 } 301 fprintf(stderr, "\t"); 302 if (in_group) { 303 fprintf(stderr, " "); 304 } 305 fprintf(stderr, "%s\n", SSL_CIPHER_get_name(cipher)); 306 if (in_group && !list->in_group_flags[i]) { 307 fprintf(stderr, "\t]\n"); 308 in_group = false; 309 } 310 } 311} 312 313static bool TestCipherRule(CipherTest *t) { 314 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method())); 315 if (!ctx) { 316 return false; 317 } 318 319 if (!SSL_CTX_set_cipher_list(ctx.get(), t->rule)) { 320 fprintf(stderr, "Error testing cipher rule '%s'\n", t->rule); 321 return false; 322 } 323 324 // Compare the two lists. 325 size_t i; 326 for (i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) { 327 const SSL_CIPHER *cipher = 328 sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i); 329 if (t->expected[i].id != SSL_CIPHER_get_id(cipher) || 330 t->expected[i].in_group_flag != ctx->cipher_list->in_group_flags[i]) { 331 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t->rule); 332 PrintCipherPreferenceList(ctx->cipher_list); 333 return false; 334 } 335 } 336 337 if (t->expected[i].id != 0) { 338 fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t->rule); 339 PrintCipherPreferenceList(ctx->cipher_list); 340 return false; 341 } 342 343 return true; 344} 345 346static bool TestRuleDoesNotIncludeNull(const char *rule) { 347 ScopedSSL_CTX ctx(SSL_CTX_new(SSLv23_server_method())); 348 if (!ctx) { 349 return false; 350 } 351 if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) { 352 fprintf(stderr, "Error: cipher rule '%s' failed\n", rule); 353 return false; 354 } 355 for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) { 356 if (SSL_CIPHER_is_NULL(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) { 357 fprintf(stderr, "Error: cipher rule '%s' includes NULL\n",rule); 358 return false; 359 } 360 } 361 return true; 362} 363 364static bool TestCipherRules() { 365 for (size_t i = 0; kCipherTests[i].rule != NULL; i++) { 366 if (!TestCipherRule(&kCipherTests[i])) { 367 return false; 368 } 369 } 370 371 for (size_t i = 0; kBadRules[i] != NULL; i++) { 372 ScopedSSL_CTX ctx(SSL_CTX_new(SSLv23_server_method())); 373 if (!ctx) { 374 return false; 375 } 376 if (SSL_CTX_set_cipher_list(ctx.get(), kBadRules[i])) { 377 fprintf(stderr, "Cipher rule '%s' unexpectedly succeeded\n", kBadRules[i]); 378 return false; 379 } 380 ERR_clear_error(); 381 } 382 383 for (size_t i = 0; kMustNotIncludeNull[i] != NULL; i++) { 384 if (!TestRuleDoesNotIncludeNull(kMustNotIncludeNull[i])) { 385 return false; 386 } 387 } 388 389 return true; 390} 391 392// kOpenSSLSession is a serialized SSL_SESSION generated from openssl 393// s_client -sess_out. 394static const char kOpenSSLSession[] = 395 "MIIFpQIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ" 396 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH" 397 "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ" 398 "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx" 399 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4" 400 "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK" 401 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v" 402 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB" 403 "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6" 404 "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e" 405 "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu" 406 "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh" 407 "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg" 408 "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd" 409 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv" 410 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp" 411 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50" 412 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ" 413 "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv" 414 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw" 415 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa" 416 "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal" 417 "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf" 418 "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St" 419 "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z" 420 "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm" 421 "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S" 422 "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B" 423 "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE" 424 "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA" 425 "i4gv7Y5oliyn"; 426 427// kCustomSession is a custom serialized SSL_SESSION generated by 428// filling in missing fields from |kOpenSSLSession|. This includes 429// providing |peer_sha256|, so |peer| is not serialized. 430static const char kCustomSession[] = 431 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ" 432 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH" 433 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE" 434 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe" 435 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751" 436 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP" 437 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG" 438 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF"; 439 440// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client. 441static const char kBoringSSLSession[] = 442 "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R" 443 "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf" 444 "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ" 445 "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx" 446 "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy" 447 "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK" 448 "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v" 449 "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB" 450 "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo" 451 "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU" 452 "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce" 453 "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/" 454 "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL" 455 "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd" 456 "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv" 457 "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp" 458 "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50" 459 "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG" 460 "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv" 461 "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw" 462 "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb" 463 "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE" 464 "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd" 465 "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+" 466 "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a" 467 "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y" 468 "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH" 469 "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH" 470 "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s" 471 "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE" 472 "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC" 473 "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL" 474 "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds" 475 "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw" 476 "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG" 477 "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE" 478 "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB" 479 "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np" 480 "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If" 481 "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S" 482 "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531" 483 "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn" 484 "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF" 485 "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB" 486 "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB" 487 "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v" 488 "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA" 489 "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK" 490 "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j" 491 "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S" 492 "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+" 493 "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl" 494 "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi" 495 "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95" 496 "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh" 497 "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT" 498 "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i" 499 "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG" 500 "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy" 501 "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB" 502 "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP" 503 "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv" 504 "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE" 505 "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ" 506 "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC" 507 "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7" 508 "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD" 509 "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov" 510 "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig" 511 "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ" 512 "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+" 513 "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI" 514 "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI" 515 "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X" 516 "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm" 517 "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40" 518 "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG" 519 "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg" 520 "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0" 521 "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ" 522 "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP" 523 "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI" 524 "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t" 525 "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN" 526 "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3" 527 "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE" 528 "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW" 529 "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9" 530 "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw" 531 "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j" 532 "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3" 533 "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF" 534 "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV" 535 "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D" 536 "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg=="; 537 538// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing 539// the final (optional) element of |kCustomSession| with tag number 30. 540static const char kBadSessionExtraField[] = 541 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ" 542 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH" 543 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE" 544 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe" 545 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751" 546 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP" 547 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG" 548 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF"; 549 550// kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing 551// the version of |kCustomSession| with 2. 552static const char kBadSessionVersion[] = 553 "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ" 554 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH" 555 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE" 556 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe" 557 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751" 558 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP" 559 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG" 560 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF"; 561 562// kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data 563// appended. 564static const char kBadSessionTrailingData[] = 565 "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ" 566 "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH" 567 "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE" 568 "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe" 569 "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751" 570 "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP" 571 "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG" 572 "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA"; 573 574static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) { 575 size_t len; 576 if (!EVP_DecodedLength(&len, strlen(in))) { 577 fprintf(stderr, "EVP_DecodedLength failed\n"); 578 return false; 579 } 580 581 out->resize(len); 582 if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in, 583 strlen(in))) { 584 fprintf(stderr, "EVP_DecodeBase64 failed\n"); 585 return false; 586 } 587 out->resize(len); 588 return true; 589} 590 591static bool TestSSL_SESSIONEncoding(const char *input_b64) { 592 const uint8_t *cptr; 593 uint8_t *ptr; 594 595 // Decode the input. 596 std::vector<uint8_t> input; 597 if (!DecodeBase64(&input, input_b64)) { 598 return false; 599 } 600 601 // Verify the SSL_SESSION decodes. 602 ScopedSSL_SESSION session(SSL_SESSION_from_bytes(input.data(), input.size())); 603 if (!session) { 604 fprintf(stderr, "SSL_SESSION_from_bytes failed\n"); 605 return false; 606 } 607 608 // Verify the SSL_SESSION encoding round-trips. 609 size_t encoded_len; 610 ScopedOpenSSLBytes encoded; 611 uint8_t *encoded_raw; 612 if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) { 613 fprintf(stderr, "SSL_SESSION_to_bytes failed\n"); 614 return false; 615 } 616 encoded.reset(encoded_raw); 617 if (encoded_len != input.size() || 618 memcmp(input.data(), encoded.get(), input.size()) != 0) { 619 fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n"); 620 hexdump(stderr, "Before: ", input.data(), input.size()); 621 hexdump(stderr, "After: ", encoded_raw, encoded_len); 622 return false; 623 } 624 625 // Verify the SSL_SESSION also decodes with the legacy API. 626 cptr = input.data(); 627 session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size())); 628 if (!session || cptr != input.data() + input.size()) { 629 fprintf(stderr, "d2i_SSL_SESSION failed\n"); 630 return false; 631 } 632 633 // Verify the SSL_SESSION encoding round-trips via the legacy API. 634 int len = i2d_SSL_SESSION(session.get(), NULL); 635 if (len < 0 || (size_t)len != input.size()) { 636 fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n"); 637 return false; 638 } 639 640 encoded.reset((uint8_t *)OPENSSL_malloc(input.size())); 641 if (!encoded) { 642 fprintf(stderr, "malloc failed\n"); 643 return false; 644 } 645 646 ptr = encoded.get(); 647 len = i2d_SSL_SESSION(session.get(), &ptr); 648 if (len < 0 || (size_t)len != input.size()) { 649 fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n"); 650 return false; 651 } 652 if (ptr != encoded.get() + input.size()) { 653 fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n"); 654 return false; 655 } 656 if (memcmp(input.data(), encoded.get(), input.size()) != 0) { 657 fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n"); 658 return false; 659 } 660 661 return true; 662} 663 664static bool TestBadSSL_SESSIONEncoding(const char *input_b64) { 665 std::vector<uint8_t> input; 666 if (!DecodeBase64(&input, input_b64)) { 667 return false; 668 } 669 670 // Verify that the SSL_SESSION fails to decode. 671 ScopedSSL_SESSION session(SSL_SESSION_from_bytes(input.data(), input.size())); 672 if (session) { 673 fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n"); 674 return false; 675 } 676 ERR_clear_error(); 677 return true; 678} 679 680static bool TestDefaultVersion(uint16_t version, 681 const SSL_METHOD *(*method)(void)) { 682 ScopedSSL_CTX ctx(SSL_CTX_new(method())); 683 if (!ctx) { 684 return false; 685 } 686 return ctx->min_version == version && ctx->max_version == version; 687} 688 689static bool CipherGetRFCName(std::string *out, uint16_t value) { 690 const SSL_CIPHER *cipher = SSL_get_cipher_by_value(value); 691 if (cipher == NULL) { 692 return false; 693 } 694 ScopedOpenSSLString rfc_name(SSL_CIPHER_get_rfc_name(cipher)); 695 if (!rfc_name) { 696 return false; 697 } 698 out->assign(rfc_name.get()); 699 return true; 700} 701 702typedef struct { 703 int id; 704 const char *rfc_name; 705} CIPHER_RFC_NAME_TEST; 706 707static const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = { 708 { SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA" }, 709 { SSL3_CK_RSA_RC4_128_MD5, "TLS_RSA_WITH_RC4_MD5" }, 710 { TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA" }, 711 { TLS1_CK_DHE_RSA_WITH_AES_256_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA" }, 712 { TLS1_CK_DHE_RSA_WITH_AES_256_SHA256, 713 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256" }, 714 { TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256, 715 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" }, 716 { TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384, 717 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384" }, 718 { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 719 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" }, 720 { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 721 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" }, 722 { TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 723 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" }, 724 { TLS1_CK_PSK_WITH_RC4_128_SHA, "TLS_PSK_WITH_RC4_SHA" }, 725 { TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA, 726 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA" }, 727 { TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 728 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" }, 729 // These names are non-standard: 730 { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, 731 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" }, 732 { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, 733 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" }, 734}; 735 736static bool TestCipherGetRFCName(void) { 737 for (size_t i = 0; 738 i < sizeof(kCipherRFCNameTests) / sizeof(kCipherRFCNameTests[0]); i++) { 739 const CIPHER_RFC_NAME_TEST *test = &kCipherRFCNameTests[i]; 740 std::string rfc_name; 741 if (!CipherGetRFCName(&rfc_name, test->id & 0xffff)) { 742 fprintf(stderr, "SSL_CIPHER_get_rfc_name failed\n"); 743 return false; 744 } 745 if (rfc_name != test->rfc_name) { 746 fprintf(stderr, "SSL_CIPHER_get_rfc_name: got '%s', wanted '%s'\n", 747 rfc_name.c_str(), test->rfc_name); 748 return false; 749 } 750 } 751 return true; 752} 753 754// CreateSessionWithTicket returns a sample |SSL_SESSION| with the ticket 755// replaced for one of length |ticket_len| or nullptr on failure. 756static ScopedSSL_SESSION CreateSessionWithTicket(size_t ticket_len) { 757 std::vector<uint8_t> der; 758 if (!DecodeBase64(&der, kOpenSSLSession)) { 759 return nullptr; 760 } 761 ScopedSSL_SESSION session(SSL_SESSION_from_bytes(der.data(), der.size())); 762 if (!session) { 763 return nullptr; 764 } 765 766 // Swap out the ticket for a garbage one. 767 OPENSSL_free(session->tlsext_tick); 768 session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len)); 769 if (session->tlsext_tick == nullptr) { 770 return nullptr; 771 } 772 memset(session->tlsext_tick, 'a', ticket_len); 773 session->tlsext_ticklen = ticket_len; 774 775 // Fix up the timeout. 776 session->time = time(NULL); 777 return session; 778} 779 780// GetClientHelloLen creates a client SSL connection with a ticket of length 781// |ticket_len| and records the ClientHello. It returns the length of the 782// ClientHello, not including the record header, on success and zero on error. 783static size_t GetClientHelloLen(size_t ticket_len) { 784 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method())); 785 ScopedSSL_SESSION session = CreateSessionWithTicket(ticket_len); 786 if (!ctx || !session) { 787 return 0; 788 } 789 ScopedSSL ssl(SSL_new(ctx.get())); 790 ScopedBIO bio(BIO_new(BIO_s_mem())); 791 if (!ssl || !bio || !SSL_set_session(ssl.get(), session.get())) { 792 return 0; 793 } 794 // Do not configure a reading BIO, but record what's written to a memory BIO. 795 SSL_set_bio(ssl.get(), nullptr /* rbio */, BIO_up_ref(bio.get())); 796 int ret = SSL_connect(ssl.get()); 797 if (ret > 0) { 798 // SSL_connect should fail without a BIO to write to. 799 return 0; 800 } 801 ERR_clear_error(); 802 803 const uint8_t *unused; 804 size_t client_hello_len; 805 if (!BIO_mem_contents(bio.get(), &unused, &client_hello_len) || 806 client_hello_len <= SSL3_RT_HEADER_LENGTH) { 807 return 0; 808 } 809 return client_hello_len - SSL3_RT_HEADER_LENGTH; 810} 811 812struct PaddingTest { 813 size_t input_len, padded_len; 814}; 815 816static const PaddingTest kPaddingTests[] = { 817 // ClientHellos of length below 0x100 do not require padding. 818 {0xfe, 0xfe}, 819 {0xff, 0xff}, 820 // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200. 821 {0x100, 0x200}, 822 {0x123, 0x200}, 823 {0x1fb, 0x200}, 824 // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The 825 // padding extension takes a minimum of four bytes plus one required content 826 // byte. (To work around yet more server bugs, we avoid empty final 827 // extensions.) 828 {0x1fc, 0x201}, 829 {0x1fd, 0x202}, 830 {0x1fe, 0x203}, 831 {0x1ff, 0x204}, 832 // Finally, larger ClientHellos need no padding. 833 {0x200, 0x200}, 834 {0x201, 0x201}, 835}; 836 837static bool TestPaddingExtension() { 838 // Sample a baseline length. 839 size_t base_len = GetClientHelloLen(1); 840 if (base_len == 0) { 841 return false; 842 } 843 844 for (const PaddingTest &test : kPaddingTests) { 845 if (base_len > test.input_len) { 846 fprintf(stderr, "Baseline ClientHello too long.\n"); 847 return false; 848 } 849 850 size_t padded_len = GetClientHelloLen(1 + test.input_len - base_len); 851 if (padded_len != test.padded_len) { 852 fprintf(stderr, "%u-byte ClientHello padded to %u bytes, not %u.\n", 853 static_cast<unsigned>(test.input_len), 854 static_cast<unsigned>(padded_len), 855 static_cast<unsigned>(test.padded_len)); 856 return false; 857 } 858 } 859 return true; 860} 861 862// Test that |SSL_get_client_CA_list| echoes back the configured parameter even 863// before configuring as a server. 864static bool TestClientCAList() { 865 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method())); 866 if (!ctx) { 867 return false; 868 } 869 ScopedSSL ssl(SSL_new(ctx.get())); 870 if (!ssl) { 871 return false; 872 } 873 874 STACK_OF(X509_NAME) *stack = sk_X509_NAME_new_null(); 875 if (stack == nullptr) { 876 return false; 877 } 878 // |SSL_set_client_CA_list| takes ownership. 879 SSL_set_client_CA_list(ssl.get(), stack); 880 881 return SSL_get_client_CA_list(ssl.get()) == stack; 882} 883 884static void AppendSession(SSL_SESSION *session, void *arg) { 885 std::vector<SSL_SESSION*> *out = 886 reinterpret_cast<std::vector<SSL_SESSION*>*>(arg); 887 out->push_back(session); 888} 889 890// ExpectCache returns true if |ctx|'s session cache consists of |expected|, in 891// order. 892static bool ExpectCache(SSL_CTX *ctx, 893 const std::vector<SSL_SESSION*> &expected) { 894 // Check the linked list. 895 SSL_SESSION *ptr = ctx->session_cache_head; 896 for (SSL_SESSION *session : expected) { 897 if (ptr != session) { 898 return false; 899 } 900 // TODO(davidben): This is an absurd way to denote the end of the list. 901 if (ptr->next == 902 reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) { 903 ptr = nullptr; 904 } else { 905 ptr = ptr->next; 906 } 907 } 908 if (ptr != nullptr) { 909 return false; 910 } 911 912 // Check the hash table. 913 std::vector<SSL_SESSION*> actual, expected_copy; 914 lh_SSL_SESSION_doall_arg(SSL_CTX_sessions(ctx), AppendSession, &actual); 915 expected_copy = expected; 916 917 std::sort(actual.begin(), actual.end()); 918 std::sort(expected_copy.begin(), expected_copy.end()); 919 920 return actual == expected_copy; 921} 922 923static ScopedSSL_SESSION CreateTestSession(uint32_t number) { 924 ScopedSSL_SESSION ret(SSL_SESSION_new()); 925 if (!ret) { 926 return nullptr; 927 } 928 929 ret->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; 930 memset(ret->session_id, 0, ret->session_id_length); 931 memcpy(ret->session_id, &number, sizeof(number)); 932 return ret; 933} 934 935// TODO(davidben): Switch this to a |std::vector<ScopedSSL_SESSION>| once we can 936// rely on a move-aware |std::vector|. 937class ScopedSessionVector { 938 public: 939 explicit ScopedSessionVector(std::vector<SSL_SESSION*> *sessions) 940 : sessions_(sessions) {} 941 942 ~ScopedSessionVector() { 943 for (SSL_SESSION *session : *sessions_) { 944 SSL_SESSION_free(session); 945 } 946 } 947 948 private: 949 std::vector<SSL_SESSION*> *const sessions_; 950}; 951 952// Test that the internal session cache behaves as expected. 953static bool TestInternalSessionCache() { 954 ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method())); 955 if (!ctx) { 956 return false; 957 } 958 959 // Prepare 10 test sessions. 960 std::vector<SSL_SESSION*> sessions; 961 ScopedSessionVector cleanup(&sessions); 962 for (int i = 0; i < 10; i++) { 963 ScopedSSL_SESSION session = CreateTestSession(i); 964 if (!session) { 965 return false; 966 } 967 sessions.push_back(session.release()); 968 } 969 970 SSL_CTX_sess_set_cache_size(ctx.get(), 5); 971 972 // Insert all the test sessions. 973 for (SSL_SESSION *session : sessions) { 974 if (!SSL_CTX_add_session(ctx.get(), session)) { 975 return false; 976 } 977 } 978 979 // Only the last five should be in the list. 980 std::vector<SSL_SESSION*> expected; 981 expected.push_back(sessions[9]); 982 expected.push_back(sessions[8]); 983 expected.push_back(sessions[7]); 984 expected.push_back(sessions[6]); 985 expected.push_back(sessions[5]); 986 if (!ExpectCache(ctx.get(), expected)) { 987 return false; 988 } 989 990 // Inserting an element already in the cache should fail. 991 if (SSL_CTX_add_session(ctx.get(), sessions[7]) || 992 !ExpectCache(ctx.get(), expected)) { 993 return false; 994 } 995 996 // Although collisions should be impossible (256-bit session IDs), the cache 997 // must handle them gracefully. 998 ScopedSSL_SESSION collision(CreateTestSession(7)); 999 if (!collision || !SSL_CTX_add_session(ctx.get(), collision.get())) { 1000 return false; 1001 } 1002 expected.clear(); 1003 expected.push_back(collision.get()); 1004 expected.push_back(sessions[9]); 1005 expected.push_back(sessions[8]); 1006 expected.push_back(sessions[6]); 1007 expected.push_back(sessions[5]); 1008 if (!ExpectCache(ctx.get(), expected)) { 1009 return false; 1010 } 1011 1012 // Removing sessions behaves correctly. 1013 if (!SSL_CTX_remove_session(ctx.get(), sessions[6])) { 1014 return false; 1015 } 1016 expected.clear(); 1017 expected.push_back(collision.get()); 1018 expected.push_back(sessions[9]); 1019 expected.push_back(sessions[8]); 1020 expected.push_back(sessions[5]); 1021 if (!ExpectCache(ctx.get(), expected)) { 1022 return false; 1023 } 1024 1025 // Removing sessions requires an exact match. 1026 if (SSL_CTX_remove_session(ctx.get(), sessions[0]) || 1027 SSL_CTX_remove_session(ctx.get(), sessions[7]) || 1028 !ExpectCache(ctx.get(), expected)) { 1029 return false; 1030 } 1031 1032 return true; 1033} 1034 1035int main() { 1036 CRYPTO_library_init(); 1037 1038 if (!TestCipherRules() || 1039 !TestSSL_SESSIONEncoding(kOpenSSLSession) || 1040 !TestSSL_SESSIONEncoding(kCustomSession) || 1041 !TestSSL_SESSIONEncoding(kBoringSSLSession) || 1042 !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) || 1043 !TestBadSSL_SESSIONEncoding(kBadSessionVersion) || 1044 !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) || 1045 !TestDefaultVersion(0, &TLS_method) || 1046 !TestDefaultVersion(SSL3_VERSION, &SSLv3_method) || 1047 !TestDefaultVersion(TLS1_VERSION, &TLSv1_method) || 1048 !TestDefaultVersion(TLS1_1_VERSION, &TLSv1_1_method) || 1049 !TestDefaultVersion(TLS1_2_VERSION, &TLSv1_2_method) || 1050 !TestDefaultVersion(0, &DTLS_method) || 1051 !TestDefaultVersion(DTLS1_VERSION, &DTLSv1_method) || 1052 !TestDefaultVersion(DTLS1_2_VERSION, &DTLSv1_2_method) || 1053 !TestCipherGetRFCName() || 1054 !TestPaddingExtension() || 1055 !TestClientCAList() || 1056 !TestInternalSessionCache()) { 1057 ERR_print_errors_fp(stderr); 1058 return 1; 1059 } 1060 1061 printf("PASS\n"); 1062 return 0; 1063} 1064