選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 
 
 

1064 行
38 KiB

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