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