const char *SCT_validation_status_string(const SCT *sct) { switch (SCT_get_validation_status(sct)) { case SCT_VALIDATION_STATUS_NOT_SET: return "not set"; case SCT_VALIDATION_STATUS_UNKNOWN_VERSION: return "unknown version"; case SCT_VALIDATION_STATUS_UNKNOWN_LOG: return "unknown log"; case SCT_VALIDATION_STATUS_UNVERIFIED: return "unverified"; case SCT_VALIDATION_STATUS_INVALID: return "invalid"; case SCT_VALIDATION_STATUS_VALID: return "valid"; } return "unknown status"; }
static int execute_cert_test(CT_TEST_FIXTURE fixture) { int test_failed = 0; X509 *cert = NULL, *issuer = NULL; STACK_OF(SCT) *scts = NULL; SCT *sct = NULL; char expected_sct_text[CT_TEST_MAX_FILE_SIZE]; int sct_text_len = 0; unsigned char *tls_sct = NULL; size_t tls_sct_len = 0; CT_POLICY_EVAL_CTX *ct_policy_ctx = CT_POLICY_EVAL_CTX_new(); if (fixture.sct_text_file_path != NULL) { sct_text_len = read_text_file( fixture.sct_text_file_path, expected_sct_text, CT_TEST_MAX_FILE_SIZE - 1); if (sct_text_len < 0) { test_failed = 1; fprintf(stderr, "Test data file not found: %s\n", fixture.sct_text_file_path); goto end; } expected_sct_text[sct_text_len] = '\0'; } CT_POLICY_EVAL_CTX_set0_log_store(ct_policy_ctx, fixture.ctlog_store); if (fixture.certificate_file_path != NULL) { int sct_extension_index; X509_EXTENSION *sct_extension = NULL; cert = load_pem_cert(fixture.certificate_file_path); if (cert == NULL) { test_failed = 1; fprintf(stderr, "Unable to load certificate: %s\n", fixture.certificate_file_path); goto end; } CT_POLICY_EVAL_CTX_set0_cert(ct_policy_ctx, cert); if (fixture.issuer_file_path != NULL) { issuer = load_pem_cert(fixture.issuer_file_path); if (issuer == NULL) { test_failed = 1; fprintf(stderr, "Unable to load issuer certificate: %s\n", fixture.issuer_file_path); goto end; } CT_POLICY_EVAL_CTX_set0_issuer(ct_policy_ctx, issuer); } sct_extension_index = X509_get_ext_by_NID(cert, NID_ct_precert_scts, -1); sct_extension = X509_get_ext(cert, sct_extension_index); if (fixture.expected_sct_count > 0) { if (sct_extension == NULL) { test_failed = 1; fprintf(stderr, "SCT extension not found in: %s\n", fixture.certificate_file_path); goto end; } if (fixture.sct_text_file_path) { test_failed = compare_extension_printout(sct_extension, expected_sct_text); if (test_failed != 0) goto end; } if (fixture.test_validity) { int are_scts_validated = 0; scts = X509V3_EXT_d2i(sct_extension); SCT_LIST_set_source(scts, SCT_SOURCE_X509V3_EXTENSION); are_scts_validated = SCT_LIST_validate(scts, ct_policy_ctx); if (are_scts_validated < 0) { fprintf(stderr, "Error verifying SCTs\n"); test_failed = 1; } else if (!are_scts_validated) { int invalid_sct_count = 0; int valid_sct_count = 0; int i; for (i = 0; i < sk_SCT_num(scts); ++i) { SCT *sct_i = sk_SCT_value(scts, i); switch (SCT_get_validation_status(sct_i)) { case SCT_VALIDATION_STATUS_VALID: ++valid_sct_count; break; case SCT_VALIDATION_STATUS_INVALID: ++invalid_sct_count; break; default: /* Ignore other validation statuses. */ break; } } if (valid_sct_count != fixture.expected_sct_count) { int unverified_sct_count = sk_SCT_num(scts) - invalid_sct_count - valid_sct_count; fprintf(stderr, "%d SCTs failed verification\n" "%d SCTs passed verification (%d expected)\n" "%d SCTs were unverified\n", invalid_sct_count, valid_sct_count, fixture.expected_sct_count, unverified_sct_count); } test_failed = 1; } if (test_failed != 0) goto end; } } else if (sct_extension != NULL) { test_failed = 1; fprintf(stderr, "Expected no SCTs, but found SCT extension in: %s\n", fixture.certificate_file_path); goto end; } } if (fixture.tls_sct != NULL) { const unsigned char *p = fixture.tls_sct; if (o2i_SCT(&sct, &p, fixture.tls_sct_len) == NULL) { test_failed = 1; fprintf(stderr, "Failed to decode SCT from TLS format\n"); goto end; } if (fixture.sct_text_file_path) { test_failed = compare_sct_printout(sct, expected_sct_text); if (test_failed != 0) goto end; } tls_sct_len = i2o_SCT(sct, &tls_sct); if (tls_sct_len != fixture.tls_sct_len || memcmp(fixture.tls_sct, tls_sct, tls_sct_len) != 0) { test_failed = 1; fprintf(stderr, "Failed to encode SCT into TLS format correctly\n"); goto end; } if (fixture.test_validity && cert != NULL) { int is_sct_validated = SCT_validate(sct, ct_policy_ctx); if (is_sct_validated < 0) { test_failed = 1; fprintf(stderr, "Error validating SCT\n"); goto end; } else if (!is_sct_validated) { test_failed = 1; fprintf(stderr, "SCT failed verification\n"); goto end; } } } end: X509_free(cert); X509_free(issuer); SCT_LIST_free(scts); SCT_free(sct); CT_POLICY_EVAL_CTX_free(ct_policy_ctx); OPENSSL_free(tls_sct); return test_failed; }