SCT_VALIDATION_STATUS_VALID : SCT_VALIDATION_STATUS_INVALID; end: is_sct_valid = sct->validation_status == SCT_VALIDATION_STATUS_VALID; err: X509_PUBKEY_free(pub); X509_PUBKEY_free(log_pkey); SCT_CTX_free(sctx); return is_sct_valid; } int SCT_LIST_validate(const STACK_OF(SCT) *scts, CT_POLICY_EVAL_CTX *ctx) { int are_scts_valid = 1; int sct_count = scts != NULL ? sk_SCT_num(scts) : 0; int i; for (i = 0; i < sct_count; ++i) { int is_sct_valid = -1; SCT *sct = sk_SCT_value(scts, i); if (sct == NULL) continue; is_sct_valid = SCT_validate(sct, ctx); if (is_sct_valid < 0) return is_sct_valid; are_scts_valid &= is_sct_valid; }
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; }
BIO_printf(out, "\n%*sTimestamp : ", indent + 4, ""); timestamp_print(sct->timestamp, out); BIO_printf(out, "\n%*sExtensions: ", indent + 4, ""); if (sct->ext_len == 0) BIO_printf(out, "none"); else BIO_hex_string(out, indent + 16, 16, sct->ext, sct->ext_len); BIO_printf(out, "\n%*sSignature : ", indent + 4, ""); SCT_signature_algorithms_print(sct, out); BIO_printf(out, "\n%*s ", indent + 4, ""); BIO_hex_string(out, indent + 16, 16, sct->sig, sct->sig_len); } void SCT_LIST_print(const STACK_OF(SCT) *sct_list, BIO *out, int indent, const char *separator, const CTLOG_STORE *log_store) { int sct_count = sk_SCT_num(sct_list); int i; for (i = 0; i < sct_count; ++i) { SCT *sct = sk_SCT_value(sct_list, i); SCT_print(sct, out, indent, log_store); if (i < sk_SCT_num(sct_list) - 1) BIO_printf(out, "%s", separator); } }