Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 
 
 

577 Zeilen
20 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 <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. // kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
  301. // the final (optional) element of |kCustomSession| with tag number 30.
  302. static const char kBadSessionExtraField[] =
  303. "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
  304. "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
  305. "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
  306. "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
  307. "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
  308. "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
  309. "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
  310. "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
  311. // kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
  312. // the version of |kCustomSession| with 2.
  313. static const char kBadSessionVersion[] =
  314. "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
  315. "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
  316. "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
  317. "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
  318. "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
  319. "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
  320. "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
  321. "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
  322. // kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
  323. // appended.
  324. static const char kBadSessionTrailingData[] =
  325. "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
  326. "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
  327. "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
  328. "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
  329. "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
  330. "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
  331. "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
  332. "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
  333. static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
  334. size_t len;
  335. if (!EVP_DecodedLength(&len, strlen(in))) {
  336. fprintf(stderr, "EVP_DecodedLength failed\n");
  337. return false;
  338. }
  339. out->resize(len);
  340. if (!EVP_DecodeBase64(bssl::vector_data(out), &len, len, (const uint8_t *)in,
  341. strlen(in))) {
  342. fprintf(stderr, "EVP_DecodeBase64 failed\n");
  343. return false;
  344. }
  345. out->resize(len);
  346. return true;
  347. }
  348. static bool TestSSL_SESSIONEncoding(const char *input_b64) {
  349. const uint8_t *cptr;
  350. uint8_t *ptr;
  351. // Decode the input.
  352. std::vector<uint8_t> input;
  353. if (!DecodeBase64(&input, input_b64)) {
  354. return false;
  355. }
  356. // Verify the SSL_SESSION decodes.
  357. ScopedSSL_SESSION session(SSL_SESSION_from_bytes(bssl::vector_data(&input),
  358. input.size()));
  359. if (!session) {
  360. fprintf(stderr, "SSL_SESSION_from_bytes failed\n");
  361. return false;
  362. }
  363. // Verify the SSL_SESSION encoding round-trips.
  364. size_t encoded_len;
  365. ScopedOpenSSLBytes encoded;
  366. uint8_t *encoded_raw;
  367. if (!SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len)) {
  368. fprintf(stderr, "SSL_SESSION_to_bytes failed\n");
  369. return false;
  370. }
  371. encoded.reset(encoded_raw);
  372. if (encoded_len != input.size() ||
  373. memcmp(bssl::vector_data(&input), encoded.get(), input.size()) != 0) {
  374. fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
  375. return false;
  376. }
  377. // Verify the SSL_SESSION also decodes with the legacy API.
  378. cptr = bssl::vector_data(&input);
  379. session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
  380. if (!session || cptr != bssl::vector_data(&input) + input.size()) {
  381. fprintf(stderr, "d2i_SSL_SESSION failed\n");
  382. return false;
  383. }
  384. // Verify the SSL_SESSION encoding round-trips via the legacy API.
  385. int len = i2d_SSL_SESSION(session.get(), NULL);
  386. if (len < 0 || (size_t)len != input.size()) {
  387. fprintf(stderr, "i2d_SSL_SESSION(NULL) returned invalid length\n");
  388. return false;
  389. }
  390. encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
  391. if (!encoded) {
  392. fprintf(stderr, "malloc failed\n");
  393. return false;
  394. }
  395. ptr = encoded.get();
  396. len = i2d_SSL_SESSION(session.get(), &ptr);
  397. if (len < 0 || (size_t)len != input.size()) {
  398. fprintf(stderr, "i2d_SSL_SESSION returned invalid length\n");
  399. return false;
  400. }
  401. if (ptr != encoded.get() + input.size()) {
  402. fprintf(stderr, "i2d_SSL_SESSION did not advance ptr correctly\n");
  403. return false;
  404. }
  405. if (memcmp(bssl::vector_data(&input), encoded.get(), input.size()) != 0) {
  406. fprintf(stderr, "i2d_SSL_SESSION did not round-trip\n");
  407. return false;
  408. }
  409. return true;
  410. }
  411. static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
  412. std::vector<uint8_t> input;
  413. if (!DecodeBase64(&input, input_b64)) {
  414. return false;
  415. }
  416. // Verify that the SSL_SESSION fails to decode.
  417. ScopedSSL_SESSION session(SSL_SESSION_from_bytes(bssl::vector_data(&input),
  418. input.size()));
  419. if (session) {
  420. fprintf(stderr, "SSL_SESSION_from_bytes unexpectedly succeeded\n");
  421. return false;
  422. }
  423. ERR_clear_error();
  424. return true;
  425. }
  426. static bool TestDefaultVersion(uint16_t version,
  427. const SSL_METHOD *(*method)(void)) {
  428. ScopedSSL_CTX ctx(SSL_CTX_new(method()));
  429. if (!ctx) {
  430. return false;
  431. }
  432. return ctx->min_version == version && ctx->max_version == version;
  433. }
  434. static bool CipherGetRFCName(std::string *out, uint16_t value) {
  435. const SSL_CIPHER *cipher = SSL_get_cipher_by_value(value);
  436. if (cipher == NULL) {
  437. return false;
  438. }
  439. ScopedOpenSSLString rfc_name(SSL_CIPHER_get_rfc_name(cipher));
  440. if (!rfc_name) {
  441. return false;
  442. }
  443. out->assign(rfc_name.get());
  444. return true;
  445. }
  446. typedef struct {
  447. int id;
  448. const char *rfc_name;
  449. } CIPHER_RFC_NAME_TEST;
  450. static const CIPHER_RFC_NAME_TEST kCipherRFCNameTests[] = {
  451. { SSL3_CK_RSA_DES_192_CBC3_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA" },
  452. { SSL3_CK_RSA_RC4_128_MD5, "TLS_RSA_WITH_RC4_MD5" },
  453. { TLS1_CK_RSA_WITH_AES_128_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA" },
  454. { TLS1_CK_DHE_RSA_WITH_AES_256_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA" },
  455. { TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
  456. "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256" },
  457. { TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
  458. "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" },
  459. { TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
  460. "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384" },
  461. { TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
  462. "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" },
  463. { TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
  464. "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" },
  465. { TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
  466. "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" },
  467. { TLS1_CK_PSK_WITH_RC4_128_SHA, "TLS_PSK_WITH_RC4_SHA" },
  468. { TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
  469. "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA" },
  470. // These names are non-standard:
  471. { TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305,
  472. "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" },
  473. { TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305,
  474. "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" },
  475. };
  476. static bool TestCipherGetRFCName(void) {
  477. for (size_t i = 0;
  478. i < sizeof(kCipherRFCNameTests) / sizeof(kCipherRFCNameTests[0]); i++) {
  479. const CIPHER_RFC_NAME_TEST *test = &kCipherRFCNameTests[i];
  480. std::string rfc_name;
  481. if (!CipherGetRFCName(&rfc_name, test->id & 0xffff)) {
  482. fprintf(stderr, "SSL_CIPHER_get_rfc_name failed\n");
  483. return false;
  484. }
  485. if (rfc_name != test->rfc_name) {
  486. fprintf(stderr, "SSL_CIPHER_get_rfc_name: got '%s', wanted '%s'\n",
  487. rfc_name.c_str(), test->rfc_name);
  488. return false;
  489. }
  490. }
  491. return true;
  492. }
  493. int main(void) {
  494. SSL_library_init();
  495. if (!TestCipherRules() ||
  496. !TestSSL_SESSIONEncoding(kOpenSSLSession) ||
  497. !TestSSL_SESSIONEncoding(kCustomSession) ||
  498. !TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
  499. !TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
  500. !TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
  501. !TestDefaultVersion(0, &TLS_method) ||
  502. !TestDefaultVersion(SSL3_VERSION, &SSLv3_method) ||
  503. !TestDefaultVersion(TLS1_VERSION, &TLSv1_method) ||
  504. !TestDefaultVersion(TLS1_1_VERSION, &TLSv1_1_method) ||
  505. !TestDefaultVersion(TLS1_2_VERSION, &TLSv1_2_method) ||
  506. !TestDefaultVersion(0, &DTLS_method) ||
  507. !TestDefaultVersion(DTLS1_VERSION, &DTLSv1_method) ||
  508. !TestDefaultVersion(DTLS1_2_VERSION, &DTLSv1_2_method) ||
  509. !TestCipherGetRFCName()) {
  510. ERR_print_errors_fp(stderr);
  511. return 1;
  512. }
  513. printf("PASS\n");
  514. return 0;
  515. }