2
0

ct_test.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. /*
  2. * Copyright 2016-2022 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 = 1580335307000ULL; /* Wed 29 Jan 2020 10:01:47 PM UTC */
  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 \n because it's easier to create files that end with one. */
  138. if (!TEST_true(BIO_write(text_buffer, "\n", 1)))
  139. goto end;
  140. /* Append \0 because we're about to use the buffer contents as a string. */
  141. if (!TEST_true(BIO_write(text_buffer, "\0", 1)))
  142. goto end;
  143. BIO_get_mem_data(text_buffer, &actual_output);
  144. if (!TEST_str_eq(actual_output, expected_output))
  145. goto end;
  146. result = 1;
  147. end:
  148. BIO_free(text_buffer);
  149. return result;
  150. }
  151. static int assert_validity(CT_TEST_FIXTURE *fixture, STACK_OF(SCT) *scts,
  152. CT_POLICY_EVAL_CTX *policy_ctx)
  153. {
  154. int invalid_sct_count = 0;
  155. int valid_sct_count = 0;
  156. int i;
  157. if (!TEST_int_ge(SCT_LIST_validate(scts, policy_ctx), 0))
  158. return 0;
  159. for (i = 0; i < sk_SCT_num(scts); ++i) {
  160. SCT *sct_i = sk_SCT_value(scts, i);
  161. switch (SCT_get_validation_status(sct_i)) {
  162. case SCT_VALIDATION_STATUS_VALID:
  163. ++valid_sct_count;
  164. break;
  165. case SCT_VALIDATION_STATUS_INVALID:
  166. ++invalid_sct_count;
  167. break;
  168. case SCT_VALIDATION_STATUS_NOT_SET:
  169. case SCT_VALIDATION_STATUS_UNKNOWN_LOG:
  170. case SCT_VALIDATION_STATUS_UNVERIFIED:
  171. case SCT_VALIDATION_STATUS_UNKNOWN_VERSION:
  172. /* Ignore other validation statuses. */
  173. break;
  174. }
  175. }
  176. if (!TEST_int_eq(valid_sct_count, fixture->expected_valid_sct_count)) {
  177. int unverified_sct_count = sk_SCT_num(scts) -
  178. invalid_sct_count - valid_sct_count;
  179. TEST_info("%d SCTs failed, %d SCTs unverified",
  180. invalid_sct_count, unverified_sct_count);
  181. return 0;
  182. }
  183. return 1;
  184. }
  185. static int execute_cert_test(CT_TEST_FIXTURE *fixture)
  186. {
  187. int success = 0;
  188. X509 *cert = NULL, *issuer = NULL;
  189. STACK_OF(SCT) *scts = NULL;
  190. SCT *sct = NULL;
  191. char expected_sct_text[CT_TEST_MAX_FILE_SIZE];
  192. int sct_text_len = 0;
  193. unsigned char *tls_sct_list = NULL;
  194. size_t tls_sct_list_len = 0;
  195. CT_POLICY_EVAL_CTX *ct_policy_ctx = CT_POLICY_EVAL_CTX_new();
  196. if (fixture->sct_text_file != NULL) {
  197. sct_text_len = read_text_file(fixture->sct_dir, fixture->sct_text_file,
  198. expected_sct_text,
  199. CT_TEST_MAX_FILE_SIZE - 1);
  200. if (!TEST_int_ge(sct_text_len, 0))
  201. goto end;
  202. expected_sct_text[sct_text_len] = '\0';
  203. }
  204. CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE(
  205. ct_policy_ctx, fixture->ctlog_store);
  206. CT_POLICY_EVAL_CTX_set_time(ct_policy_ctx, fixture->epoch_time_in_ms);
  207. if (fixture->certificate_file != NULL) {
  208. int sct_extension_index;
  209. int i;
  210. X509_EXTENSION *sct_extension = NULL;
  211. if (!TEST_ptr(cert = load_pem_cert(fixture->certs_dir,
  212. fixture->certificate_file)))
  213. goto end;
  214. CT_POLICY_EVAL_CTX_set1_cert(ct_policy_ctx, cert);
  215. if (fixture->issuer_file != NULL) {
  216. if (!TEST_ptr(issuer = load_pem_cert(fixture->certs_dir,
  217. fixture->issuer_file)))
  218. goto end;
  219. CT_POLICY_EVAL_CTX_set1_issuer(ct_policy_ctx, issuer);
  220. }
  221. sct_extension_index =
  222. X509_get_ext_by_NID(cert, NID_ct_precert_scts, -1);
  223. sct_extension = X509_get_ext(cert, sct_extension_index);
  224. if (fixture->expected_sct_count > 0) {
  225. if (!TEST_ptr(sct_extension))
  226. goto end;
  227. if (fixture->sct_text_file
  228. && !compare_extension_printout(sct_extension,
  229. expected_sct_text))
  230. goto end;
  231. scts = X509V3_EXT_d2i(sct_extension);
  232. for (i = 0; i < sk_SCT_num(scts); ++i) {
  233. SCT *sct_i = sk_SCT_value(scts, i);
  234. if (!TEST_int_eq(SCT_get_source(sct_i),
  235. SCT_SOURCE_X509V3_EXTENSION)) {
  236. goto end;
  237. }
  238. }
  239. if (fixture->test_validity) {
  240. if (!assert_validity(fixture, scts, ct_policy_ctx))
  241. goto end;
  242. }
  243. } else if (!TEST_ptr_null(sct_extension)) {
  244. goto end;
  245. }
  246. }
  247. if (fixture->tls_sct_list != NULL) {
  248. const unsigned char *p = fixture->tls_sct_list;
  249. if (!TEST_ptr(o2i_SCT_LIST(&scts, &p, fixture->tls_sct_list_len)))
  250. goto end;
  251. if (fixture->test_validity && cert != NULL) {
  252. if (!assert_validity(fixture, scts, ct_policy_ctx))
  253. goto end;
  254. }
  255. if (fixture->sct_text_file
  256. && !compare_sct_list_printout(scts, expected_sct_text)) {
  257. goto end;
  258. }
  259. tls_sct_list_len = i2o_SCT_LIST(scts, &tls_sct_list);
  260. if (!TEST_mem_eq(fixture->tls_sct_list, fixture->tls_sct_list_len,
  261. tls_sct_list, tls_sct_list_len))
  262. goto end;
  263. }
  264. success = 1;
  265. end:
  266. X509_free(cert);
  267. X509_free(issuer);
  268. SCT_LIST_free(scts);
  269. SCT_free(sct);
  270. CT_POLICY_EVAL_CTX_free(ct_policy_ctx);
  271. OPENSSL_free(tls_sct_list);
  272. return success;
  273. }
  274. # define SETUP_CT_TEST_FIXTURE() SETUP_TEST_FIXTURE(CT_TEST_FIXTURE, set_up)
  275. # define EXECUTE_CT_TEST() EXECUTE_TEST(execute_cert_test, tear_down)
  276. static int test_no_scts_in_certificate(void)
  277. {
  278. SETUP_CT_TEST_FIXTURE();
  279. fixture->certs_dir = certs_dir;
  280. fixture->certificate_file = "leaf.pem";
  281. fixture->issuer_file = "subinterCA.pem";
  282. fixture->expected_sct_count = 0;
  283. EXECUTE_CT_TEST();
  284. return result;
  285. }
  286. static int test_one_sct_in_certificate(void)
  287. {
  288. SETUP_CT_TEST_FIXTURE();
  289. fixture->certs_dir = certs_dir;
  290. fixture->certificate_file = "embeddedSCTs1.pem";
  291. fixture->issuer_file = "embeddedSCTs1_issuer.pem";
  292. fixture->expected_sct_count = 1;
  293. fixture->sct_dir = certs_dir;
  294. fixture->sct_text_file = "embeddedSCTs1.sct";
  295. EXECUTE_CT_TEST();
  296. return result;
  297. }
  298. static int test_multiple_scts_in_certificate(void)
  299. {
  300. SETUP_CT_TEST_FIXTURE();
  301. fixture->certs_dir = certs_dir;
  302. fixture->certificate_file = "embeddedSCTs3.pem";
  303. fixture->issuer_file = "embeddedSCTs3_issuer.pem";
  304. fixture->expected_sct_count = 3;
  305. fixture->sct_dir = certs_dir;
  306. fixture->sct_text_file = "embeddedSCTs3.sct";
  307. EXECUTE_CT_TEST();
  308. return result;
  309. }
  310. static int test_verify_one_sct(void)
  311. {
  312. SETUP_CT_TEST_FIXTURE();
  313. fixture->certs_dir = certs_dir;
  314. fixture->certificate_file = "embeddedSCTs1.pem";
  315. fixture->issuer_file = "embeddedSCTs1_issuer.pem";
  316. fixture->expected_sct_count = fixture->expected_valid_sct_count = 1;
  317. fixture->test_validity = 1;
  318. EXECUTE_CT_TEST();
  319. return result;
  320. }
  321. static int test_verify_multiple_scts(void)
  322. {
  323. SETUP_CT_TEST_FIXTURE();
  324. fixture->certs_dir = certs_dir;
  325. fixture->certificate_file = "embeddedSCTs3.pem";
  326. fixture->issuer_file = "embeddedSCTs3_issuer.pem";
  327. fixture->expected_sct_count = fixture->expected_valid_sct_count = 3;
  328. fixture->test_validity = 1;
  329. EXECUTE_CT_TEST();
  330. return result;
  331. }
  332. static int test_verify_fails_for_future_sct(void)
  333. {
  334. SETUP_CT_TEST_FIXTURE();
  335. fixture->epoch_time_in_ms = 1365094800000ULL; /* Apr 4 17:00:00 2013 GMT */
  336. fixture->certs_dir = certs_dir;
  337. fixture->certificate_file = "embeddedSCTs1.pem";
  338. fixture->issuer_file = "embeddedSCTs1_issuer.pem";
  339. fixture->expected_sct_count = 1;
  340. fixture->expected_valid_sct_count = 0;
  341. fixture->test_validity = 1;
  342. EXECUTE_CT_TEST();
  343. return result;
  344. }
  345. static int test_decode_tls_sct(void)
  346. {
  347. const unsigned char tls_sct_list[] = "\x00\x78" /* length of list */
  348. "\x00\x76"
  349. "\x00" /* version */
  350. /* log ID */
  351. "\xDF\x1C\x2E\xC1\x15\x00\x94\x52\x47\xA9\x61\x68\x32\x5D\xDC\x5C\x79"
  352. "\x59\xE8\xF7\xC6\xD3\x88\xFC\x00\x2E\x0B\xBD\x3F\x74\xD7\x64"
  353. "\x00\x00\x01\x3D\xDB\x27\xDF\x93" /* timestamp */
  354. "\x00\x00" /* extensions length */
  355. "" /* extensions */
  356. "\x04\x03" /* hash and signature algorithms */
  357. "\x00\x47" /* signature length */
  358. /* signature */
  359. "\x30\x45\x02\x20\x48\x2F\x67\x51\xAF\x35\xDB\xA6\x54\x36\xBE\x1F\xD6"
  360. "\x64\x0F\x3D\xBF\x9A\x41\x42\x94\x95\x92\x45\x30\x28\x8F\xA3\xE5\xE2"
  361. "\x3E\x06\x02\x21\x00\xE4\xED\xC0\xDB\x3A\xC5\x72\xB1\xE2\xF5\xE8\xAB"
  362. "\x6A\x68\x06\x53\x98\x7D\xCF\x41\x02\x7D\xFE\xFF\xA1\x05\x51\x9D\x89"
  363. "\xED\xBF\x08";
  364. SETUP_CT_TEST_FIXTURE();
  365. fixture->tls_sct_list = tls_sct_list;
  366. fixture->tls_sct_list_len = 0x7a;
  367. fixture->sct_dir = ct_dir;
  368. fixture->sct_text_file = "tls1.sct";
  369. EXECUTE_CT_TEST();
  370. return result;
  371. }
  372. static int test_encode_tls_sct(void)
  373. {
  374. const char log_id[] = "3xwuwRUAlFJHqWFoMl3cXHlZ6PfG04j8AC4LvT9012Q=";
  375. const uint64_t timestamp = 1;
  376. const char extensions[] = "";
  377. const char signature[] = "BAMARzBAMiBIL2dRrzXbplQ2vh/WZA89v5pBQpSVkkUwKI+j5"
  378. "eI+BgIhAOTtwNs6xXKx4vXoq2poBlOYfc9BAn3+/6EFUZ2J7b8I";
  379. SCT *sct = NULL;
  380. SETUP_CT_TEST_FIXTURE();
  381. fixture->sct_list = sk_SCT_new_null();
  382. if (fixture->sct_list == NULL)
  383. return 0;
  384. if (!TEST_ptr(sct = SCT_new_from_base64(SCT_VERSION_V1, log_id,
  385. CT_LOG_ENTRY_TYPE_X509, timestamp,
  386. extensions, signature)))
  387. return 0;
  388. sk_SCT_push(fixture->sct_list, sct);
  389. fixture->sct_dir = ct_dir;
  390. fixture->sct_text_file = "tls1.sct";
  391. EXECUTE_CT_TEST();
  392. return result;
  393. }
  394. /*
  395. * Tests that the CT_POLICY_EVAL_CTX default time is approximately now.
  396. * Allow +-10 minutes, as it may compensate for clock skew.
  397. */
  398. static int test_default_ct_policy_eval_ctx_time_is_now(void)
  399. {
  400. int success = 0;
  401. CT_POLICY_EVAL_CTX *ct_policy_ctx = CT_POLICY_EVAL_CTX_new();
  402. const time_t default_time =
  403. (time_t)(CT_POLICY_EVAL_CTX_get_time(ct_policy_ctx) / 1000);
  404. const time_t time_tolerance = 600; /* 10 minutes */
  405. if (!TEST_time_t_le(abs((int)difftime(time(NULL), default_time)),
  406. time_tolerance))
  407. goto end;
  408. success = 1;
  409. end:
  410. CT_POLICY_EVAL_CTX_free(ct_policy_ctx);
  411. return success;
  412. }
  413. static int test_ctlog_from_base64(void)
  414. {
  415. CTLOG *ctlogp = NULL;
  416. const char notb64[] = "\01\02\03\04";
  417. const char pad[] = "====";
  418. const char name[] = "name";
  419. /* We expect these to both fail! */
  420. if (!TEST_true(!CTLOG_new_from_base64(&ctlogp, notb64, name))
  421. || !TEST_true(!CTLOG_new_from_base64(&ctlogp, pad, name)))
  422. return 0;
  423. return 1;
  424. }
  425. #endif
  426. int setup_tests(void)
  427. {
  428. #ifndef OPENSSL_NO_CT
  429. if ((ct_dir = getenv("CT_DIR")) == NULL)
  430. ct_dir = "ct";
  431. if ((certs_dir = getenv("CERTS_DIR")) == NULL)
  432. certs_dir = "certs";
  433. ADD_TEST(test_no_scts_in_certificate);
  434. ADD_TEST(test_one_sct_in_certificate);
  435. ADD_TEST(test_multiple_scts_in_certificate);
  436. ADD_TEST(test_verify_one_sct);
  437. ADD_TEST(test_verify_multiple_scts);
  438. ADD_TEST(test_verify_fails_for_future_sct);
  439. ADD_TEST(test_decode_tls_sct);
  440. ADD_TEST(test_encode_tls_sct);
  441. ADD_TEST(test_default_ct_policy_eval_ctx_time_is_now);
  442. ADD_TEST(test_ctlog_from_base64);
  443. #else
  444. printf("No CT support\n");
  445. #endif
  446. return 1;
  447. }