From 7d054e5ab2aeaead14c0c19b808d62221020b0e1 Mon Sep 17 00:00:00 2001 From: Rob Percival Date: Mon, 29 Feb 2016 17:33:02 +0000 Subject: CT policy validation Specifies a callback that will, in the future, be used by the SSL code to decide whether to abort a connection on Certificate Transparency grounds. Reviewed-by: Ben Laurie Reviewed-by: Rich Salz --- crypto/ct/ct_sct.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) (limited to 'crypto/ct/ct_sct.c') diff --git a/crypto/ct/ct_sct.c b/crypto/ct/ct_sct.c index e75061d..35f8152 100644 --- a/crypto/ct/ct_sct.c +++ b/crypto/ct/ct_sct.c @@ -356,3 +356,94 @@ int SCT_LIST_set0_logs(STACK_OF(SCT) *sct_list, const CTLOG_STORE *ct_logs) return sct_logs_found; } + +sct_validation_status_t SCT_get_validation_status(const SCT *sct) +{ + return sct->validation_status; +} + +int SCT_validate(SCT *sct, const CT_POLICY_EVAL_CTX *ctx) +{ + int is_sct_valid = -1; + SCT_CTX *sctx = NULL; + X509_PUBKEY *pub = NULL, *log_pkey = NULL; + + switch (sct->version) { + case SCT_VERSION_V1: + if (sct->log == NULL) + sct->log = CTLOG_STORE_get0_log_by_id(ctx->log_store, + sct->log_id, + CT_V1_HASHLEN); + break; + default: + sct->validation_status = SCT_VALIDATION_STATUS_UNKNOWN_VERSION; + goto end; + } + + if (sct->log == NULL) { + sct->validation_status = SCT_VALIDATION_STATUS_UNKNOWN_LOG; + goto end; + } + + sctx = SCT_CTX_new(); + if (sctx == NULL) + goto err; + + if (X509_PUBKEY_set(&log_pkey, CTLOG_get0_public_key(sct->log)) != 1) + goto err; + if (SCT_CTX_set1_pubkey(sctx, log_pkey) != 1) + goto err; + + if (SCT_get_log_entry_type(sct) == CT_LOG_ENTRY_TYPE_PRECERT) { + EVP_PKEY *issuer_pkey; + + if (ctx->issuer == NULL) { + sct->validation_status = SCT_VALIDATION_STATUS_UNVERIFIED; + goto end; + } + + issuer_pkey = X509_get_pubkey(ctx->issuer); + + if (X509_PUBKEY_set(&pub, issuer_pkey) != 1) + goto err; + if (SCT_CTX_set1_issuer_pubkey(sctx, pub) != 1) + goto err; + } + + if (SCT_CTX_set1_cert(sctx, ctx->cert, NULL) != 1) + goto err; + + sct->validation_status = SCT_verify(sctx, sct) == 1 ? + 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; + } + + return are_scts_valid; +} -- cgit v1.1