2
0

ct_test.c 16 KB

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