Home | History | Annotate | Download | only in ssl
      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 
     33 struct ExpectedCipher {
     34   unsigned long id;
     35   int in_group_flag;
     36 };
     37 
     38 struct 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.
     46 static 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 
     52 static 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.
     64 static 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 
     71 static 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.
     82 static 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 
     89 static 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.
     97 static const char kRule4[] = "kRSA+AESGCM+AES128";
     98 
     99 static 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.
    107 static const char kRule5[] =
    108     "ALL:-kECDHE:-kDHE:-kRSA:-ALL:"
    109     "AESGCM+AES128+aRSA";
    110 
    111 static 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.
    119 static 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 
    126 static 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.
    137 static 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 
    142 static 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.
    154 static 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 
    167 static 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.
    181 static 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 
    187 static 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.
    194 static const char kRule10[] = "AES128-SHA:AES128-SHA256:!SSLv3";
    195 
    196 static 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.
    202 static const char kRule11[] = "AES128-SHA:AES128-SHA256:!TLSv1.2";
    203 
    204 static const ExpectedCipher kExpected11[] = {
    205   { TLS1_CK_RSA_WITH_AES_128_SHA, 0 },
    206   { 0, 0 },
    207 };
    208 
    209 // The two directives have no intersection.
    210 static const char kRule12[] = "AES128-SHA:AES128-SHA256:!TLSv1.2+SSLv3";
    211 
    212 static 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.)
    221 static 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 
    227 static 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 
    235 static 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 
    252 static 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 
    276 static 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 
    293 static 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 
    313 static 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 
    346 static 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 
    364 static 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.
    394 static 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.
    430 static 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.
    441 static 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.
    540 static 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.
    552 static 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.
    564 static 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 
    574 static 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 
    591 static 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 
    664 static 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 
    680 static 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 
    689 static 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 
    702 typedef struct {
    703   int id;
    704   const char *rfc_name;
    705 } CIPHER_RFC_NAME_TEST;
    706 
    707 static 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 
    736 static 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.
    756 static 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.
    783 static 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 
    812 struct PaddingTest {
    813   size_t input_len, padded_len;
    814 };
    815 
    816 static 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 
    837 static 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.
    864 static 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 
    884 static 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.
    892 static 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 
    923 static 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|.
    937 class 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.
    953 static 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 
   1035 int 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