diff options
author | Rob Percival <robpercival@google.com> | 2016-02-29 17:33:02 +0000 |
---|---|---|
committer | Rob Percival <robpercival@google.com> | 2016-03-01 20:03:25 +0000 |
commit | 7d054e5ab2aeaead14c0c19b808d62221020b0e1 (patch) | |
tree | 655006eea9d0fe60879b36d09e9046be5a3749de /crypto/ct/ct_sct.c | |
parent | 7852414967b87400b08bfdf321732cfbd07286e2 (diff) | |
download | openssl-7d054e5ab2aeaead14c0c19b808d62221020b0e1.zip openssl-7d054e5ab2aeaead14c0c19b808d62221020b0e1.tar.gz openssl-7d054e5ab2aeaead14c0c19b808d62221020b0e1.tar.bz2 |
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 <ben@openssl.org>
Reviewed-by: Rich Salz <rsalz@openssl.org>
Diffstat (limited to 'crypto/ct/ct_sct.c')
-rw-r--r-- | crypto/ct/ct_sct.c | 91 |
1 files changed, 91 insertions, 0 deletions
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; +} |