ct_test.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. /*
  2. * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <ctype.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <openssl/ct.h>
  14. #include <openssl/err.h>
  15. #include <openssl/pem.h>
  16. #include <openssl/x509.h>
  17. #include <openssl/x509v3.h>
  18. #include "testutil.h"
  19. #include <openssl/crypto.h>
  20. #ifndef OPENSSL_NO_CT
  21. /* Used when declaring buffers to read text files into */
  22. # define CT_TEST_MAX_FILE_SIZE 8096
  23. static char *certs_dir = NULL;
  24. static char *ct_dir = NULL;
  25. typedef struct ct_test_fixture {
  26. const char *test_case_name;
  27. /* The current time in milliseconds */
  28. uint64_t epoch_time_in_ms;
  29. /* The CT log store to use during tests */
  30. CTLOG_STORE* ctlog_store;
  31. /* Set the following to test handling of SCTs in X509 certificates */
  32. const char *certs_dir;
  33. char *certificate_file;
  34. char *issuer_file;
  35. /* Expected number of SCTs */
  36. int expected_sct_count;
  37. /* Expected number of valid SCTS */
  38. int expected_valid_sct_count;
  39. /* Set the following to test handling of SCTs in TLS format */
  40. const unsigned char *tls_sct_list;
  41. size_t tls_sct_list_len;
  42. STACK_OF(SCT) *sct_list;
  43. /*
  44. * A file to load the expected SCT text from.
  45. * This text will be compared to the actual text output during the test.
  46. * A maximum of |CT_TEST_MAX_FILE_SIZE| bytes will be read of this file.
  47. */
  48. const char *sct_dir;
  49. const char *sct_text_file;
  50. /* Whether to test the validity of the SCT(s) */
  51. int test_validity;
  52. } CT_TEST_FIXTURE;
  53. static CT_TEST_FIXTURE *set_up(const char *const test_case_name)
  54. {
  55. CT_TEST_FIXTURE *fixture = NULL;
  56. if (!TEST_ptr(fixture = OPENSSL_zalloc(sizeof(*fixture))))
  57. goto end;
  58. fixture->test_case_name = test_case_name;
  59. fixture->epoch_time_in_ms = 1473269626000ULL; /* Sep 7 17:33:46 2016 GMT */
  60. if (!TEST_ptr(fixture->ctlog_store = CTLOG_STORE_new())
  61. || !TEST_int_eq(
  62. CTLOG_STORE_load_default_file(fixture->ctlog_store), 1))
  63. goto end;
  64. return fixture;
  65. end:
  66. if (fixture != NULL)
  67. CTLOG_STORE_free(fixture->ctlog_store);
  68. OPENSSL_free(fixture);
  69. TEST_error("Failed to setup");
  70. return NULL;
  71. }
  72. static void tear_down(CT_TEST_FIXTURE *fixture)
  73. {
  74. if (fixture != NULL) {
  75. CTLOG_STORE_free(fixture->ctlog_store);
  76. SCT_LIST_free(fixture->sct_list);
  77. }
  78. OPENSSL_free(fixture);
  79. }
  80. static X509 *load_pem_cert(const char *dir, const char *file)
  81. {
  82. X509 *cert = NULL;
  83. char *file_path = test_mk_file_path(dir, file);
  84. if (file_path != NULL) {
  85. BIO *cert_io = BIO_new_file(file_path, "r");
  86. if (cert_io != NULL)
  87. cert = PEM_read_bio_X509(cert_io, NULL, NULL, NULL);
  88. BIO_free(cert_io);
  89. }
  90. OPENSSL_free(file_path);
  91. return cert;
  92. }
  93. static int read_text_file(const char *dir, const char *file,
  94. char *buffer, int buffer_length)
  95. {
  96. int len = -1;
  97. char *file_path = test_mk_file_path(dir, file);
  98. if (file_path != NULL) {
  99. BIO *file_io = BIO_new_file(file_path, "r");
  100. if (file_io != NULL)
  101. len = BIO_read(file_io, buffer, buffer_length);
  102. BIO_free(file_io);
  103. }
  104. OPENSSL_free(file_path);
  105. return len;
  106. }
  107. static int compare_sct_list_printout(STACK_OF(SCT) *sct,
  108. const char *expected_output)
  109. {
  110. BIO *text_buffer = NULL;
  111. char *actual_output = NULL;
  112. int result = 0;
  113. if (!TEST_ptr(text_buffer = BIO_new(BIO_s_mem())))
  114. goto end;
  115. SCT_LIST_print(sct, text_buffer, 0, "\n", NULL);
  116. /* Append \0 because we're about to use the buffer contents as a string. */
  117. if (!TEST_true(BIO_write(text_buffer, "\0", 1)))
  118. goto end;
  119. BIO_get_mem_data(text_buffer, &actual_output);
  120. if (!TEST_str_eq(actual_output, expected_output))
  121. goto end;
  122. result = 1;
  123. end:
  124. BIO_free(text_buffer);
  125. return result;
  126. }
  127. static int compare_extension_printout(X509_EXTENSION *extension,
  128. const char *expected_output)
  129. {
  130. BIO *text_buffer = NULL;
  131. char *actual_output = NULL;
  132. int result = 0;
  133. if (!TEST_ptr(text_buffer = BIO_new(BIO_s_mem()))
  134. || !TEST_true(X509V3_EXT_print(text_buffer, extension,
  135. X509V3_EXT_DEFAULT, 0)))
  136. goto end;
  137. /* Append \0 because we're about to use the buffer contents as a string. */
  138. if (!TEST_true(BIO_write(text_buffer, "\0", 1)))
  139. goto end;
  140. BIO_get_mem_data(text_buffer, &actual_output);
  141. if (!TEST_str_eq(actual_output, expected_output))
  142. goto end;
  143. result = 1;
  144. end:
  145. BIO_free(text_buffer);
  146. return result;
  147. }
  148. static int assert_validity(CT_TEST_FIXTURE *fixture, STACK_OF(SCT) *scts,
  149. CT_POLICY_EVAL_CTX *policy_ctx)
  150. {
  151. int invalid_sct_count = 0;
  152. int valid_sct_count = 0;
  153. int i;
  154. if (!TEST_int_ge(SCT_LIST_validate(scts, policy_ctx), 0))
  155. return 0;
  156. for (i = 0; i < sk_SCT_num(scts); ++i) {
  157. SCT *sct_i = sk_SCT_value(scts, i);
  158. switch (SCT_get_validation_status(sct_i)) {
  159. case SCT_VALIDATION_STATUS_VALID:
  160. ++valid_sct_count;
  161. break;
  162. case SCT_VALIDATION_STATUS_INVALID:
  163. ++invalid_sct_count;
  164. break;
  165. case SCT_VALIDATION_STATUS_NOT_SET:
  166. case SCT_VALIDATION_STATUS_UNKNOWN_LOG:
  167. case SCT_VALIDATION_STATUS_UNVERIFIED:
  168. case SCT_VALIDATION_STATUS_UNKNOWN_VERSION:
  169. /* Ignore other validation statuses. */
  170. break;
  171. }
  172. }
  173. if (!TEST_int_eq(valid_sct_count, fixture->expected_valid_sct_count)) {
  174. int unverified_sct_count = sk_SCT_num(scts) -
  175. invalid_sct_count - valid_sct_count;
  176. TEST_info("%d SCTs failed, %d SCTs unverified",
  177. invalid_sct_count, unverified_sct_count);
  178. return 0;
  179. }
  180. return 1;
  181. }
  182. static int execute_cert_test(CT_TEST_FIXTURE *fixture)
  183. {
  184. int success = 0;
  185. X509 *cert = NULL, *issuer = NULL;
  186. STACK_OF(SCT) *scts = NULL;
  187. SCT *sct = NULL;
  188. char expected_sct_text[CT_TEST_MAX_FILE_SIZE];
  189. int sct_text_len = 0;
  190. unsigned char *tls_sct_list = NULL;
  191. size_t tls_sct_list_len = 0;
  192. CT_POLICY_EVAL_CTX *ct_policy_ctx = CT_POLICY_EVAL_CTX_new();
  193. if (fixture->sct_text_file != NULL) {
  194. sct_text_len = read_text_file(fixture->sct_dir, fixture->sct_text_file,
  195. expected_sct_text,
  196. CT_TEST_MAX_FILE_SIZE - 1);
  197. if (!TEST_int_ge(sct_text_len, 0))
  198. goto end;
  199. expected_sct_text[sct_text_len] = '\0';
  200. }
  201. CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE(
  202. ct_policy_ctx, fixture->ctlog_store);
  203. CT_POLICY_EVAL_CTX_set_time(ct_policy_ctx, fixture->epoch_time_in_ms);
  204. if (fixture->certificate_file != NULL) {
  205. int sct_extension_index;
  206. int i;
  207. X509_EXTENSION *sct_extension = NULL;
  208. if (!TEST_ptr(cert = load_pem_cert(fixture->certs_dir,
  209. fixture->certificate_file)))
  210. goto end;
  211. CT_POLICY_EVAL_CTX_set1_cert(ct_policy_ctx, cert);
  212. if (fixture->issuer_file != NULL) {
  213. if (!TEST_ptr(issuer = load_pem_cert(fixture->certs_dir,
  214. fixture->issuer_file)))
  215. goto end;
  216. CT_POLICY_EVAL_CTX_set1_issuer(ct_policy_ctx, issuer);
  217. }
  218. sct_extension_index =
  219. X509_get_ext_by_NID(cert, NID_ct_precert_scts, -1);
  220. sct_extension = X509_get_ext(cert, sct_extension_index);
  221. if (fixture->expected_sct_count > 0) {
  222. if (!TEST_ptr(sct_extension))
  223. goto end;
  224. if (fixture->sct_text_file
  225. && !compare_extension_printout(sct_extension,
  226. expected_sct_text))
  227. goto end;
  228. scts = X509V3_EXT_d2i(sct_extension);
  229. for (i = 0; i < sk_SCT_num(scts); ++i) {
  230. SCT *sct_i = sk_SCT_value(scts, i);
  231. if (!TEST_int_eq(SCT_get_source(sct_i),
  232. SCT_SOURCE_X509V3_EXTENSION)) {
  233. goto end;
  234. }
  235. }
  236. if (fixture->test_validity) {
  237. if (!assert_validity(fixture, scts, ct_policy_ctx))
  238. goto end;
  239. }
  240. } else if (!TEST_ptr_null(sct_extension)) {
  241. goto end;
  242. }
  243. }
  244. if (fixture->tls_sct_list != NULL) {
  245. const unsigned char *p = fixture->tls_sct_list;
  246. if (!TEST_ptr(o2i_SCT_LIST(&scts, &p, fixture->tls_sct_list_len)))
  247. goto end;
  248. if (fixture->test_validity && cert != NULL) {
  249. if (!assert_validity(fixture, scts, ct_policy_ctx))
  250. goto end;
  251. }
  252. if (fixture->sct_text_file
  253. && !compare_sct_list_printout(scts, expected_sct_text)) {
  254. goto end;
  255. }
  256. tls_sct_list_len = i2o_SCT_LIST(scts, &tls_sct_list);
  257. if (!TEST_mem_eq(fixture->tls_sct_list, fixture->tls_sct_list_len,
  258. tls_sct_list, tls_sct_list_len))
  259. goto end;
  260. }
  261. success = 1;
  262. end:
  263. X509_free(cert);
  264. X509_free(issuer);
  265. SCT_LIST_free(scts);
  266. SCT_free(sct);
  267. CT_POLICY_EVAL_CTX_free(ct_policy_ctx);
  268. OPENSSL_free(tls_sct_list);
  269. return success;
  270. }
  271. # define SETUP_CT_TEST_FIXTURE() SETUP_TEST_FIXTURE(CT_TEST_FIXTURE, set_up)
  272. # define EXECUTE_CT_TEST() EXECUTE_TEST(execute_cert_test, tear_down)
  273. static int test_no_scts_in_certificate(void)
  274. {
  275. SETUP_CT_TEST_FIXTURE();
  276. if (fixture == NULL)
  277. return 0;
  278. fixture->certs_dir = certs_dir;
  279. fixture->certificate_file = "leaf.pem";
  280. fixture->issuer_file = "subinterCA.pem";
  281. fixture->expected_sct_count = 0;
  282. EXECUTE_CT_TEST();
  283. return result;
  284. }
  285. static int test_one_sct_in_certificate(void)
  286. {
  287. SETUP_CT_TEST_FIXTURE();
  288. if (fixture == NULL)
  289. return 0;
  290. fixture->certs_dir = certs_dir;
  291. fixture->certificate_file = "embeddedSCTs1.pem";
  292. fixture->issuer_file = "embeddedSCTs1_issuer.pem";
  293. fixture->expected_sct_count = 1;
  294. fixture->sct_dir = certs_dir;
  295. fixture->sct_text_file = "embeddedSCTs1.sct";
  296. EXECUTE_CT_TEST();
  297. return result;
  298. }
  299. static int test_multiple_scts_in_certificate(void)
  300. {
  301. SETUP_CT_TEST_FIXTURE();
  302. if (fixture == NULL)
  303. return 0;
  304. fixture->certs_dir = certs_dir;
  305. fixture->certificate_file = "embeddedSCTs3.pem";
  306. fixture->issuer_file = "embeddedSCTs3_issuer.pem";
  307. fixture->expected_sct_count = 3;
  308. fixture->sct_dir = certs_dir;
  309. fixture->sct_text_file = "embeddedSCTs3.sct";
  310. EXECUTE_CT_TEST();
  311. return result;
  312. }
  313. static int test_verify_one_sct(void)
  314. {
  315. SETUP_CT_TEST_FIXTURE();
  316. if (fixture == NULL)
  317. return 0;
  318. fixture->certs_dir = certs_dir;
  319. fixture->certificate_file = "embeddedSCTs1.pem";
  320. fixture->issuer_file = "embeddedSCTs1_issuer.pem";
  321. fixture->expected_sct_count = fixture->expected_valid_sct_count = 1;
  322. fixture->test_validity = 1;
  323. EXECUTE_CT_TEST();
  324. return result;
  325. }
  326. static int test_verify_multiple_scts(void)
  327. {
  328. SETUP_CT_TEST_FIXTURE();
  329. if (fixture == NULL)
  330. return 0;
  331. fixture->certs_dir = certs_dir;
  332. fixture->certificate_file = "embeddedSCTs3.pem";
  333. fixture->issuer_file = "embeddedSCTs3_issuer.pem";
  334. fixture->expected_sct_count = fixture->expected_valid_sct_count = 3;
  335. fixture->test_validity = 1;
  336. EXECUTE_CT_TEST();
  337. return result;
  338. }
  339. static int test_verify_fails_for_future_sct(void)
  340. {
  341. SETUP_CT_TEST_FIXTURE();
  342. if (fixture == NULL)
  343. return 0;
  344. fixture->epoch_time_in_ms = 1365094800000ULL; /* Apr 4 17:00:00 2013 GMT */
  345. fixture->certs_dir = certs_dir;
  346. fixture->certificate_file = "embeddedSCTs1.pem";
  347. fixture->issuer_file = "embeddedSCTs1_issuer.pem";
  348. fixture->expected_sct_count = 1;
  349. fixture->expected_valid_sct_count = 0;
  350. fixture->test_validity = 1;
  351. EXECUTE_CT_TEST();
  352. return result;
  353. }
  354. static int test_decode_tls_sct(void)
  355. {
  356. const unsigned char tls_sct_list[] = "\x00\x78" /* length of list */
  357. "\x00\x76"
  358. "\x00" /* version */
  359. /* log ID */
  360. "\xDF\x1C\x2E\xC1\x15\x00\x94\x52\x47\xA9\x61\x68\x32\x5D\xDC\x5C\x79"
  361. "\x59\xE8\xF7\xC6\xD3\x88\xFC\x00\x2E\x0B\xBD\x3F\x74\xD7\x64"
  362. "\x00\x00\x01\x3D\xDB\x27\xDF\x93" /* timestamp */
  363. "\x00\x00" /* extensions length */
  364. "" /* extensions */
  365. "\x04\x03" /* hash and signature algorithms */
  366. "\x00\x47" /* signature length */
  367. /* signature */
  368. "\x30\x45\x02\x20\x48\x2F\x67\x51\xAF\x35\xDB\xA6\x54\x36\xBE\x1F\xD6"
  369. "\x64\x0F\x3D\xBF\x9A\x41\x42\x94\x95\x92\x45\x30\x28\x8F\xA3\xE5\xE2"
  370. "\x3E\x06\x02\x21\x00\xE4\xED\xC0\xDB\x3A\xC5\x72\xB1\xE2\xF5\xE8\xAB"
  371. "\x6A\x68\x06\x53\x98\x7D\xCF\x41\x02\x7D\xFE\xFF\xA1\x05\x51\x9D\x89"
  372. "\xED\xBF\x08";
  373. SETUP_CT_TEST_FIXTURE();
  374. if (fixture == NULL)
  375. return 0;
  376. fixture->tls_sct_list = tls_sct_list;
  377. fixture->tls_sct_list_len = 0x7a;
  378. fixture->sct_dir = ct_dir;
  379. fixture->sct_text_file = "tls1.sct";
  380. EXECUTE_CT_TEST();
  381. return result;
  382. }
  383. static int test_encode_tls_sct(void)
  384. {
  385. const char log_id[] = "3xwuwRUAlFJHqWFoMl3cXHlZ6PfG04j8AC4LvT9012Q=";
  386. const uint64_t timestamp = 1;
  387. const char extensions[] = "";
  388. const char signature[] = "BAMARzBAMiBIL2dRrzXbplQ2vh/WZA89v5pBQpSVkkUwKI+j5"
  389. "eI+BgIhAOTtwNs6xXKx4vXoq2poBlOYfc9BAn3+/6EFUZ2J7b8I";
  390. SCT *sct = NULL;
  391. SETUP_CT_TEST_FIXTURE();
  392. if (fixture == NULL)
  393. return 0;
  394. fixture->sct_list = sk_SCT_new_null();
  395. if (!TEST_ptr(sct = SCT_new_from_base64(SCT_VERSION_V1, log_id,
  396. CT_LOG_ENTRY_TYPE_X509, timestamp,
  397. extensions, signature)))
  398. return 0;
  399. sk_SCT_push(fixture->sct_list, sct);
  400. fixture->sct_dir = ct_dir;
  401. fixture->sct_text_file = "tls1.sct";
  402. EXECUTE_CT_TEST();
  403. return result;
  404. }
  405. /*
  406. * Tests that the CT_POLICY_EVAL_CTX default time is approximately now.
  407. * Allow +-10 minutes, as it may compensate for clock skew.
  408. */
  409. static int test_default_ct_policy_eval_ctx_time_is_now(void)
  410. {
  411. int success = 0;
  412. CT_POLICY_EVAL_CTX *ct_policy_ctx = CT_POLICY_EVAL_CTX_new();
  413. const time_t default_time =
  414. (time_t)(CT_POLICY_EVAL_CTX_get_time(ct_policy_ctx) / 1000);
  415. const time_t time_tolerance = 600; /* 10 minutes */
  416. if (!TEST_time_t_le(abs((int)difftime(time(NULL), default_time)),
  417. time_tolerance))
  418. goto end;
  419. success = 1;
  420. end:
  421. CT_POLICY_EVAL_CTX_free(ct_policy_ctx);
  422. return success;
  423. }
  424. static int test_ctlog_from_base64(void)
  425. {
  426. CTLOG *ctlogp = NULL;
  427. const char notb64[] = "\01\02\03\04";
  428. const char pad[] = "====";
  429. const char name[] = "name";
  430. /* We expect these to both fail! */
  431. if (!TEST_true(!CTLOG_new_from_base64(&ctlogp, notb64, name))
  432. || !TEST_true(!CTLOG_new_from_base64(&ctlogp, pad, name)))
  433. return 0;
  434. return 1;
  435. }
  436. #endif
  437. int setup_tests(void)
  438. {
  439. #ifndef OPENSSL_NO_CT
  440. if ((ct_dir = getenv("CT_DIR")) == NULL)
  441. ct_dir = "ct";
  442. if ((certs_dir = getenv("CERTS_DIR")) == NULL)
  443. certs_dir = "certs";
  444. ADD_TEST(test_no_scts_in_certificate);
  445. ADD_TEST(test_one_sct_in_certificate);
  446. ADD_TEST(test_multiple_scts_in_certificate);
  447. ADD_TEST(test_verify_one_sct);
  448. ADD_TEST(test_verify_multiple_scts);
  449. ADD_TEST(test_verify_fails_for_future_sct);
  450. ADD_TEST(test_decode_tls_sct);
  451. ADD_TEST(test_encode_tls_sct);
  452. ADD_TEST(test_default_ct_policy_eval_ctx_time_is_now);
  453. ADD_TEST(test_ctlog_from_base64);
  454. #else
  455. printf("No CT support\n");
  456. #endif
  457. return 1;
  458. }