Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

ssl_test.cc 17 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  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 <string>
  17. #include <vector>
  18. #include <openssl/base64.h>
  19. #include <openssl/bio.h>
  20. #include <openssl/err.h>
  21. #include <openssl/ssl.h>
  22. #include "test/scoped_types.h"
  23. struct ExpectedCipher {
  24. unsigned long id;
  25. int in_group_flag;
  26. };
  27. struct CipherTest {
  28. // The rule string to apply.
  29. const char *rule;
  30. // The list of expected ciphers, in order, terminated with -1.
  31. const ExpectedCipher *expected;
  32. };
  33. // Selecting individual ciphers should work.
  34. static const char kRule1[] =
  35. "ECDHE-ECDSA-CHACHA20-POLY1305:"
  36. "ECDHE-RSA-CHACHA20-POLY1305:"
  37. "ECDHE-ECDSA-AES128-GCM-SHA256:"
  38. "ECDHE-RSA-AES128-GCM-SHA256";
  39. static const ExpectedCipher kExpected1[] = {
  40. { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, 0 },
  41. { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, 0 },
  42. { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
  43. { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
  44. { 0, 0 },
  45. };
  46. // + reorders selected ciphers to the end, keeping their relative
  47. // order.
  48. static const char kRule2[] =
  49. "ECDHE-ECDSA-CHACHA20-POLY1305:"
  50. "ECDHE-RSA-CHACHA20-POLY1305:"
  51. "ECDHE-ECDSA-AES128-GCM-SHA256:"
  52. "ECDHE-RSA-AES128-GCM-SHA256:"
  53. "+aRSA";
  54. static const ExpectedCipher kExpected2[] = {
  55. { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, 0 },
  56. { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
  57. { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, 0 },
  58. { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
  59. { 0, 0 },
  60. };
  61. // ! banishes ciphers from future selections.
  62. static const char kRule3[] =
  63. "!aRSA:"
  64. "ECDHE-ECDSA-CHACHA20-POLY1305:"
  65. "ECDHE-RSA-CHACHA20-POLY1305:"
  66. "ECDHE-ECDSA-AES128-GCM-SHA256:"
  67. "ECDHE-RSA-AES128-GCM-SHA256";
  68. static const ExpectedCipher kExpected3[] = {
  69. { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, 0 },
  70. { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
  71. { 0, 0 },
  72. };
  73. // Multiple masks can be ANDed in a single rule.
  74. static const char kRule4[] = "kRSA+AESGCM+AES128";
  75. static const ExpectedCipher kExpected4[] = {
  76. { TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0 },
  77. { 0, 0 },
  78. };
  79. // - removes selected ciphers, but preserves their order for future
  80. // selections. Select AES_128_GCM, but order the key exchanges RSA,
  81. // DHE_RSA, ECDHE_RSA.
  82. static const char kRule5[] =
  83. "ALL:-kECDHE:-kDHE:-kRSA:-ALL:"
  84. "AESGCM+AES128+aRSA";
  85. static const ExpectedCipher kExpected5[] = {
  86. { TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0 },
  87. { TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
  88. { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
  89. { 0, 0 },
  90. };
  91. // Unknown selectors are no-ops.
  92. static const char kRule6[] =
  93. "ECDHE-ECDSA-CHACHA20-POLY1305:"
  94. "ECDHE-RSA-CHACHA20-POLY1305:"
  95. "ECDHE-ECDSA-AES128-GCM-SHA256:"
  96. "ECDHE-RSA-AES128-GCM-SHA256:"
  97. "BOGUS1:-BOGUS2:+BOGUS3:!BOGUS4";
  98. static const ExpectedCipher kExpected6[] = {
  99. { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, 0 },
  100. { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, 0 },
  101. { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
  102. { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
  103. { 0, 0 },
  104. };
  105. // Square brackets specify equi-preference groups.
  106. static const char kRule7[] =
  107. "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
  108. "[ECDHE-RSA-CHACHA20-POLY1305]:"
  109. "ECDHE-RSA-AES128-GCM-SHA256";
  110. static const ExpectedCipher kExpected7[] = {
  111. { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, 1 },
  112. { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0 },
  113. { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, 0 },
  114. { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0 },
  115. { 0, 0 },
  116. };
  117. // @STRENGTH performs a stable strength-sort of the selected
  118. // ciphers and only the selected ciphers.
  119. static const char kRule8[] =
  120. // To simplify things, banish all but {ECDHE_RSA,RSA} x
  121. // {CHACHA20,AES_256_CBC,AES_128_CBC,RC4} x SHA1.
  122. "!kEDH:!AESGCM:!3DES:!SHA256:!MD5:!SHA384:"
  123. // Order some ciphers backwards by strength.
  124. "ALL:-CHACHA20:-AES256:-AES128:-RC4:-ALL:"
  125. // Select ECDHE ones and sort them by strength. Ties should resolve
  126. // based on the order above.
  127. "kECDHE:@STRENGTH:-ALL:"
  128. // Now bring back everything uses RSA. ECDHE_RSA should be first,
  129. // sorted by strength. Then RSA, backwards by strength.
  130. "aRSA";
  131. static const ExpectedCipher kExpected8[] = {
  132. { TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0 },
  133. { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, 0 },
  134. { TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA, 0 },
  135. { TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0 },
  136. { SSL3_CK_RSA_RC4_128_SHA, 0 },
  137. { TLS1_CK_RSA_WITH_AES_128_SHA, 0 },
  138. { TLS1_CK_RSA_WITH_AES_256_SHA, 0 },
  139. { 0, 0 },
  140. };
  141. // Exact ciphers may not be used in multi-part rules; they are treated
  142. // as unknown aliases.
  143. static const char kRule9[] =
  144. "ECDHE-ECDSA-CHACHA20-POLY1305:"
  145. "ECDHE-RSA-CHACHA20-POLY1305:"
  146. "!ECDHE-RSA-CHACHA20-POLY1305+RSA:"
  147. "!ECDSA+ECDHE-ECDSA-CHACHA20-POLY1305";
  148. static const ExpectedCipher kExpected9[] = {
  149. { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, 0 },
  150. { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, 0 },
  151. { 0, 0 },
  152. };
  153. static CipherTest kCipherTests[] = {
  154. { kRule1, kExpected1 },
  155. { kRule2, kExpected2 },
  156. { kRule3, kExpected3 },
  157. { kRule4, kExpected4 },
  158. { kRule5, kExpected5 },
  159. { kRule6, kExpected6 },
  160. { kRule7, kExpected7 },
  161. { kRule8, kExpected8 },
  162. { kRule9, kExpected9 },
  163. { NULL, NULL },
  164. };
  165. static const char *kBadRules[] = {
  166. // Invalid brackets.
  167. "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
  168. "RSA]",
  169. "[[RSA]]",
  170. // Operators inside brackets.
  171. "[+RSA]",
  172. // Unknown directive.
  173. "@BOGUS",
  174. // Empty cipher lists error at SSL_CTX_set_cipher_list.
  175. "",
  176. "BOGUS",
  177. // COMPLEMENTOFDEFAULT is empty.
  178. "COMPLEMENTOFDEFAULT",
  179. // Invalid command.
  180. "?BAR",
  181. // Special operators are not allowed if groups are used.
  182. "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
  183. "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
  184. "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
  185. "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
  186. NULL,
  187. };
  188. static void PrintCipherPreferenceList(ssl_cipher_preference_list_st *list) {
  189. bool in_group = false;
  190. for (size_t i = 0; i < sk_SSL_CIPHER_num(list->ciphers); i++) {
  191. const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(list->ciphers, i);
  192. if (!in_group && list->in_group_flags[i]) {
  193. fprintf(stderr, "\t[\n");
  194. in_group = true;
  195. }
  196. fprintf(stderr, "\t");
  197. if (in_group) {
  198. fprintf(stderr, " ");
  199. }
  200. fprintf(stderr, "%s\n", SSL_CIPHER_get_name(cipher));
  201. if (in_group && !list->in_group_flags[i]) {
  202. fprintf(stderr, "\t]\n");
  203. in_group = false;
  204. }
  205. }
  206. }
  207. static bool TestCipherRule(CipherTest *t) {
  208. ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
  209. if (!ctx) {
  210. return false;
  211. }
  212. if (!SSL_CTX_set_cipher_list(ctx.get(), t->rule)) {
  213. fprintf(stderr, "Error testing cipher rule '%s'\n", t->rule);
  214. return false;
  215. }
  216. // Compare the two lists.
  217. size_t i;
  218. for (i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
  219. const SSL_CIPHER *cipher =
  220. sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i);
  221. if (t->expected[i].id != SSL_CIPHER_get_id(cipher) ||
  222. t->expected[i].in_group_flag != ctx->cipher_list->in_group_flags[i]) {
  223. fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t->rule);
  224. PrintCipherPreferenceList(ctx->cipher_list);
  225. return false;
  226. }
  227. }
  228. if (t->expected[i].id != 0) {
  229. fprintf(stderr, "Error: cipher rule '%s' evaluated to:\n", t->rule);
  230. PrintCipherPreferenceList(ctx->cipher_list);
  231. return false;
  232. }
  233. return true;
  234. }
  235. static bool TestCipherRules() {
  236. for (size_t i = 0; kCipherTests[i].rule != NULL; i++) {
  237. if (!TestCipherRule(&kCipherTests[i])) {
  238. return false;
  239. }
  240. }
  241. for (size_t i = 0; kBadRules[i] != NULL; i++) {
  242. ScopedSSL_CTX ctx(SSL_CTX_new(SSLv23_server_method()));
  243. if (!ctx) {
  244. return false;
  245. }
  246. if (SSL_CTX_set_cipher_list(ctx.get(), kBadRules[i])) {
  247. fprintf(stderr, "Cipher rule '%s' unexpectedly succeeded\n", kBadRules[i]);
  248. return false;
  249. }
  250. ERR_clear_error();
  251. }
  252. return true;
  253. }
  254. // kOpenSSLSession is a serialized SSL_SESSION generated from openssl
  255. // s_client -sess_out.
  256. static const char kOpenSSLSession[] =
  257. "MIIFpQIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
  258. "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
  259. "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
  260. "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
  261. "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
  262. "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
  263. "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
  264. "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
  265. "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
  266. "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
  267. "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
  268. "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
  269. "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
  270. "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
  271. "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
  272. "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
  273. "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
  274. "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
  275. "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
  276. "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
  277. "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
  278. "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
  279. "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
  280. "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
  281. "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
  282. "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
  283. "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
  284. "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
  285. "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
  286. "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
  287. "i4gv7Y5oliyn";
  288. // kCustomSession is a custom serialized SSL_SESSION generated by
  289. // filling in missing fields from |kOpenSSLSession|. This includes
  290. // providing |peer_sha256|, so |peer| is not serialized.
  291. static const char kCustomSession[] =
  292. "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
  293. "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
  294. "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
  295. "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
  296. "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
  297. "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
  298. "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
  299. "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
  300. static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
  301. size_t len;
  302. if (!EVP_DecodedLength(&len, strlen(in))) {
  303. fprintf(stderr, "EVP_DecodedLength failed\n");
  304. return false;
  305. }
  306. out->resize(len);
  307. if (!EVP_DecodeBase64(bssl::vector_data(out), &len, len, (const uint8_t *)in,
  308. strlen(in))) {
  309. fprintf(stderr, "EVP_DecodeBase64 failed\n");
  310. return false;
  311. }
  312. out->resize(len);
  313. return true;
  314. }
  315. static bool TestSSL_SESSIONEncoding(const char *input_b64) {
  316. const uint8_t *cptr;
  317. uint8_t *ptr;
  318. // Decode the input.
  319. std::vector<uint8_t> input;
  320. if (!DecodeBase64(&input, input_b64)) {
  321. return false;
  322. }
  323. // Verify the SSL_SESSION decodes.
  324. cptr = bssl::vector_data(&input);
  325. ScopedSSL_SESSION session(d2i_SSL_SESSION(NULL, &cptr, input.size()));
  326. if (!session || cptr != bssl::vector_data(&input) + input.size()) {
  327. fprintf(stderr, "d2i_SSL_SESSION failed\n");
  328. return false;
  329. }
  330. // Verify the SSL_SESSION encoding round-trips.
  331. size_t encoded_len;
  332. ScopedOpenSSLBytes encoded;
  333. uint8_t *encoded_raw;
  334. if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
  335. fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
  336. return false;
  337. }
  338. encoded.reset(encoded_raw);
  339. if (encoded_len != input.size() ||
  340. memcmp(bssl::vector_data(&input), encoded.get(), input.size()) != 0) {
  341. fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
  342. return false;
  343. }
  344. // Verify the SSL_SESSION encoding round-trips via the legacy API.
  345. int len = i2d_SSL_SESSION(session.get(), NULL);
  346. if (len < 0 || (size_t)len != input.size()) {
  347. fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n");
  348. return false;
  349. }
  350. encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
  351. if (!encoded) {
  352. fprintf(stderr, "malloc failed\n");
  353. return false;
  354. }
  355. ptr = encoded.get();
  356. len = i2d_SSL_SESSION(session.get(), &ptr);
  357. if (len < 0 || (size_t)len != input.size()) {
  358. fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n");
  359. return false;
  360. }
  361. if (ptr != encoded.get() + input.size()) {
  362. fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n");
  363. return false;
  364. }
  365. if (memcmp(bssl::vector_data(&input), encoded.get(), input.size()) != 0) {
  366. fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n");
  367. return false;
  368. }
  369. return true;
  370. }
  371. static bool TestDefaultVersion(uint16_t version,
  372. const SSL_METHOD *(*method)(void)) {
  373. ScopedSSL_CTX ctx(SSL_CTX_new(method()));
  374. if (!ctx) {
  375. return false;
  376. }
  377. return ctx->min_version == version && ctx->max_version == version;
  378. }
  379. static bool CipherGetRFCName(std::string *out, uint16_t value) {
  380. const SSL_CIPHER *cipher = SSL_get_cipher_by_value(value);
  381. if (cipher == NULL) {
  382. return false;
  383. }
  384. ScopedOpenSSLString rfc_name(SSL_CIPHER_get_rfc_name(cipher));
  385. out->assign(rfc_name.get());
  386. return true;
  387. }
  388. typedef struct {
  389. int id;
  390. const char *rfc_name;
  391. } CIPHER_RFC_NAME_TEST;
  392. static const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = {
  393. { SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA" },
  394. { SSL3_CK_RSA_RC4_128_MD5, "TLS_RSA_WITH_RC4_MD5" },
  395. { TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA" },
  396. { TLS1_CK_DHE_RSA_WITH_AES_256_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA" },
  397. { TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
  398. "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256" },
  399. { TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
  400. "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" },
  401. { TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
  402. "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384" },
  403. { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
  404. "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" },
  405. { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
  406. "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" },
  407. { TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
  408. "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" },
  409. { TLS1_CK_PSK_WITH_RC4_128_SHA, "TLS_PSK_WITH_RC4_SHA" },
  410. // These names are non-standard:
  411. { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305,
  412. "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
  413. { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305,
  414. "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" },
  415. { TLS1_CK_ECDHE_PSK_WITH_AES_128_GCM_SHA256,
  416. "TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256" },
  417. };
  418. static bool TestCipherGetRFCName(void) {
  419. for (size_t i = 0;
  420. i < sizeof(kCipherRFCNameTests) / sizeof(kCipherRFCNameTests[0]); i++) {
  421. const CIPHER_RFC_NAME_TEST *test = &kCipherRFCNameTests[i];
  422. std::string rfc_name;
  423. if (!CipherGetRFCName(&rfc_name, test->id & 0xffff)) {
  424. fprintf(stderr, "SSL_CIPHER_get_rfc_name failed\n");
  425. return false;
  426. }
  427. if (rfc_name != test->rfc_name) {
  428. fprintf(stderr, "SSL_CIPHER_get_rfc_name: got '%s', wanted '%s'\n",
  429. rfc_name.c_str(), test->rfc_name);
  430. return false;
  431. }
  432. }
  433. return true;
  434. }
  435. int main(void) {
  436. SSL_library_init();
  437. if (!TestCipherRules() ||
  438. !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
  439. !TestSSL_SESSIONEncoding(kCustomSession) ||
  440. !TestDefaultVersion(0, &TLS_method) ||
  441. !TestDefaultVersion(SSL3_VERSION, &SSLv3_method) ||
  442. !TestDefaultVersion(TLS1_VERSION, &TLSv1_method) ||
  443. !TestDefaultVersion(TLS1_1_VERSION, &TLSv1_1_method) ||
  444. !TestDefaultVersion(TLS1_2_VERSION, &TLSv1_2_method) ||
  445. !TestDefaultVersion(0, &DTLS_method) ||
  446. !TestDefaultVersion(DTLS1_VERSION, &DTLSv1_method) ||
  447. !TestDefaultVersion(DTLS1_2_VERSION, &DTLSv1_2_method) ||
  448. !TestCipherGetRFCName()) {
  449. ERR_print_errors_fp(stderr);
  450. return 1;
  451. }
  452. printf("PASS\n");
  453. return 0;
  454. }