1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci#ifdef OPENSSL_NO_CT 11e1051a39Sopenharmony_ci# error "CT disabled" 12e1051a39Sopenharmony_ci#endif 13e1051a39Sopenharmony_ci 14e1051a39Sopenharmony_ci#include <openssl/ct.h> 15e1051a39Sopenharmony_ci#include <openssl/err.h> 16e1051a39Sopenharmony_ci#include <openssl/evp.h> 17e1051a39Sopenharmony_ci#include <openssl/tls1.h> 18e1051a39Sopenharmony_ci#include <openssl/x509.h> 19e1051a39Sopenharmony_ci 20e1051a39Sopenharmony_ci#include "ct_local.h" 21e1051a39Sopenharmony_ci 22e1051a39Sopenharmony_ciSCT *SCT_new(void) 23e1051a39Sopenharmony_ci{ 24e1051a39Sopenharmony_ci SCT *sct = OPENSSL_zalloc(sizeof(*sct)); 25e1051a39Sopenharmony_ci 26e1051a39Sopenharmony_ci if (sct == NULL) { 27e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); 28e1051a39Sopenharmony_ci return NULL; 29e1051a39Sopenharmony_ci } 30e1051a39Sopenharmony_ci 31e1051a39Sopenharmony_ci sct->entry_type = CT_LOG_ENTRY_TYPE_NOT_SET; 32e1051a39Sopenharmony_ci sct->version = SCT_VERSION_NOT_SET; 33e1051a39Sopenharmony_ci return sct; 34e1051a39Sopenharmony_ci} 35e1051a39Sopenharmony_ci 36e1051a39Sopenharmony_civoid SCT_free(SCT *sct) 37e1051a39Sopenharmony_ci{ 38e1051a39Sopenharmony_ci if (sct == NULL) 39e1051a39Sopenharmony_ci return; 40e1051a39Sopenharmony_ci 41e1051a39Sopenharmony_ci OPENSSL_free(sct->log_id); 42e1051a39Sopenharmony_ci OPENSSL_free(sct->ext); 43e1051a39Sopenharmony_ci OPENSSL_free(sct->sig); 44e1051a39Sopenharmony_ci OPENSSL_free(sct->sct); 45e1051a39Sopenharmony_ci OPENSSL_free(sct); 46e1051a39Sopenharmony_ci} 47e1051a39Sopenharmony_ci 48e1051a39Sopenharmony_civoid SCT_LIST_free(STACK_OF(SCT) *a) 49e1051a39Sopenharmony_ci{ 50e1051a39Sopenharmony_ci sk_SCT_pop_free(a, SCT_free); 51e1051a39Sopenharmony_ci} 52e1051a39Sopenharmony_ci 53e1051a39Sopenharmony_ciint SCT_set_version(SCT *sct, sct_version_t version) 54e1051a39Sopenharmony_ci{ 55e1051a39Sopenharmony_ci if (version != SCT_VERSION_V1) { 56e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CT, CT_R_UNSUPPORTED_VERSION); 57e1051a39Sopenharmony_ci return 0; 58e1051a39Sopenharmony_ci } 59e1051a39Sopenharmony_ci sct->version = version; 60e1051a39Sopenharmony_ci sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; 61e1051a39Sopenharmony_ci return 1; 62e1051a39Sopenharmony_ci} 63e1051a39Sopenharmony_ci 64e1051a39Sopenharmony_ciint SCT_set_log_entry_type(SCT *sct, ct_log_entry_type_t entry_type) 65e1051a39Sopenharmony_ci{ 66e1051a39Sopenharmony_ci sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; 67e1051a39Sopenharmony_ci 68e1051a39Sopenharmony_ci switch (entry_type) { 69e1051a39Sopenharmony_ci case CT_LOG_ENTRY_TYPE_X509: 70e1051a39Sopenharmony_ci case CT_LOG_ENTRY_TYPE_PRECERT: 71e1051a39Sopenharmony_ci sct->entry_type = entry_type; 72e1051a39Sopenharmony_ci return 1; 73e1051a39Sopenharmony_ci case CT_LOG_ENTRY_TYPE_NOT_SET: 74e1051a39Sopenharmony_ci break; 75e1051a39Sopenharmony_ci } 76e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CT, CT_R_UNSUPPORTED_ENTRY_TYPE); 77e1051a39Sopenharmony_ci return 0; 78e1051a39Sopenharmony_ci} 79e1051a39Sopenharmony_ci 80e1051a39Sopenharmony_ciint SCT_set0_log_id(SCT *sct, unsigned char *log_id, size_t log_id_len) 81e1051a39Sopenharmony_ci{ 82e1051a39Sopenharmony_ci if (sct->version == SCT_VERSION_V1 && log_id_len != CT_V1_HASHLEN) { 83e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CT, CT_R_INVALID_LOG_ID_LENGTH); 84e1051a39Sopenharmony_ci return 0; 85e1051a39Sopenharmony_ci } 86e1051a39Sopenharmony_ci 87e1051a39Sopenharmony_ci OPENSSL_free(sct->log_id); 88e1051a39Sopenharmony_ci sct->log_id = log_id; 89e1051a39Sopenharmony_ci sct->log_id_len = log_id_len; 90e1051a39Sopenharmony_ci sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; 91e1051a39Sopenharmony_ci return 1; 92e1051a39Sopenharmony_ci} 93e1051a39Sopenharmony_ci 94e1051a39Sopenharmony_ciint SCT_set1_log_id(SCT *sct, const unsigned char *log_id, size_t log_id_len) 95e1051a39Sopenharmony_ci{ 96e1051a39Sopenharmony_ci if (sct->version == SCT_VERSION_V1 && log_id_len != CT_V1_HASHLEN) { 97e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CT, CT_R_INVALID_LOG_ID_LENGTH); 98e1051a39Sopenharmony_ci return 0; 99e1051a39Sopenharmony_ci } 100e1051a39Sopenharmony_ci 101e1051a39Sopenharmony_ci OPENSSL_free(sct->log_id); 102e1051a39Sopenharmony_ci sct->log_id = NULL; 103e1051a39Sopenharmony_ci sct->log_id_len = 0; 104e1051a39Sopenharmony_ci sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; 105e1051a39Sopenharmony_ci 106e1051a39Sopenharmony_ci if (log_id != NULL && log_id_len > 0) { 107e1051a39Sopenharmony_ci sct->log_id = OPENSSL_memdup(log_id, log_id_len); 108e1051a39Sopenharmony_ci if (sct->log_id == NULL) { 109e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); 110e1051a39Sopenharmony_ci return 0; 111e1051a39Sopenharmony_ci } 112e1051a39Sopenharmony_ci sct->log_id_len = log_id_len; 113e1051a39Sopenharmony_ci } 114e1051a39Sopenharmony_ci return 1; 115e1051a39Sopenharmony_ci} 116e1051a39Sopenharmony_ci 117e1051a39Sopenharmony_ci 118e1051a39Sopenharmony_civoid SCT_set_timestamp(SCT *sct, uint64_t timestamp) 119e1051a39Sopenharmony_ci{ 120e1051a39Sopenharmony_ci sct->timestamp = timestamp; 121e1051a39Sopenharmony_ci sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; 122e1051a39Sopenharmony_ci} 123e1051a39Sopenharmony_ci 124e1051a39Sopenharmony_ciint SCT_set_signature_nid(SCT *sct, int nid) 125e1051a39Sopenharmony_ci{ 126e1051a39Sopenharmony_ci switch (nid) { 127e1051a39Sopenharmony_ci case NID_sha256WithRSAEncryption: 128e1051a39Sopenharmony_ci sct->hash_alg = TLSEXT_hash_sha256; 129e1051a39Sopenharmony_ci sct->sig_alg = TLSEXT_signature_rsa; 130e1051a39Sopenharmony_ci sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; 131e1051a39Sopenharmony_ci return 1; 132e1051a39Sopenharmony_ci case NID_ecdsa_with_SHA256: 133e1051a39Sopenharmony_ci sct->hash_alg = TLSEXT_hash_sha256; 134e1051a39Sopenharmony_ci sct->sig_alg = TLSEXT_signature_ecdsa; 135e1051a39Sopenharmony_ci sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; 136e1051a39Sopenharmony_ci return 1; 137e1051a39Sopenharmony_ci default: 138e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CT, CT_R_UNRECOGNIZED_SIGNATURE_NID); 139e1051a39Sopenharmony_ci return 0; 140e1051a39Sopenharmony_ci } 141e1051a39Sopenharmony_ci} 142e1051a39Sopenharmony_ci 143e1051a39Sopenharmony_civoid SCT_set0_extensions(SCT *sct, unsigned char *ext, size_t ext_len) 144e1051a39Sopenharmony_ci{ 145e1051a39Sopenharmony_ci OPENSSL_free(sct->ext); 146e1051a39Sopenharmony_ci sct->ext = ext; 147e1051a39Sopenharmony_ci sct->ext_len = ext_len; 148e1051a39Sopenharmony_ci sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; 149e1051a39Sopenharmony_ci} 150e1051a39Sopenharmony_ci 151e1051a39Sopenharmony_ciint SCT_set1_extensions(SCT *sct, const unsigned char *ext, size_t ext_len) 152e1051a39Sopenharmony_ci{ 153e1051a39Sopenharmony_ci OPENSSL_free(sct->ext); 154e1051a39Sopenharmony_ci sct->ext = NULL; 155e1051a39Sopenharmony_ci sct->ext_len = 0; 156e1051a39Sopenharmony_ci sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; 157e1051a39Sopenharmony_ci 158e1051a39Sopenharmony_ci if (ext != NULL && ext_len > 0) { 159e1051a39Sopenharmony_ci sct->ext = OPENSSL_memdup(ext, ext_len); 160e1051a39Sopenharmony_ci if (sct->ext == NULL) { 161e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); 162e1051a39Sopenharmony_ci return 0; 163e1051a39Sopenharmony_ci } 164e1051a39Sopenharmony_ci sct->ext_len = ext_len; 165e1051a39Sopenharmony_ci } 166e1051a39Sopenharmony_ci return 1; 167e1051a39Sopenharmony_ci} 168e1051a39Sopenharmony_ci 169e1051a39Sopenharmony_civoid SCT_set0_signature(SCT *sct, unsigned char *sig, size_t sig_len) 170e1051a39Sopenharmony_ci{ 171e1051a39Sopenharmony_ci OPENSSL_free(sct->sig); 172e1051a39Sopenharmony_ci sct->sig = sig; 173e1051a39Sopenharmony_ci sct->sig_len = sig_len; 174e1051a39Sopenharmony_ci sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; 175e1051a39Sopenharmony_ci} 176e1051a39Sopenharmony_ci 177e1051a39Sopenharmony_ciint SCT_set1_signature(SCT *sct, const unsigned char *sig, size_t sig_len) 178e1051a39Sopenharmony_ci{ 179e1051a39Sopenharmony_ci OPENSSL_free(sct->sig); 180e1051a39Sopenharmony_ci sct->sig = NULL; 181e1051a39Sopenharmony_ci sct->sig_len = 0; 182e1051a39Sopenharmony_ci sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; 183e1051a39Sopenharmony_ci 184e1051a39Sopenharmony_ci if (sig != NULL && sig_len > 0) { 185e1051a39Sopenharmony_ci sct->sig = OPENSSL_memdup(sig, sig_len); 186e1051a39Sopenharmony_ci if (sct->sig == NULL) { 187e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_CT, ERR_R_MALLOC_FAILURE); 188e1051a39Sopenharmony_ci return 0; 189e1051a39Sopenharmony_ci } 190e1051a39Sopenharmony_ci sct->sig_len = sig_len; 191e1051a39Sopenharmony_ci } 192e1051a39Sopenharmony_ci return 1; 193e1051a39Sopenharmony_ci} 194e1051a39Sopenharmony_ci 195e1051a39Sopenharmony_cisct_version_t SCT_get_version(const SCT *sct) 196e1051a39Sopenharmony_ci{ 197e1051a39Sopenharmony_ci return sct->version; 198e1051a39Sopenharmony_ci} 199e1051a39Sopenharmony_ci 200e1051a39Sopenharmony_cict_log_entry_type_t SCT_get_log_entry_type(const SCT *sct) 201e1051a39Sopenharmony_ci{ 202e1051a39Sopenharmony_ci return sct->entry_type; 203e1051a39Sopenharmony_ci} 204e1051a39Sopenharmony_ci 205e1051a39Sopenharmony_cisize_t SCT_get0_log_id(const SCT *sct, unsigned char **log_id) 206e1051a39Sopenharmony_ci{ 207e1051a39Sopenharmony_ci *log_id = sct->log_id; 208e1051a39Sopenharmony_ci return sct->log_id_len; 209e1051a39Sopenharmony_ci} 210e1051a39Sopenharmony_ci 211e1051a39Sopenharmony_ciuint64_t SCT_get_timestamp(const SCT *sct) 212e1051a39Sopenharmony_ci{ 213e1051a39Sopenharmony_ci return sct->timestamp; 214e1051a39Sopenharmony_ci} 215e1051a39Sopenharmony_ci 216e1051a39Sopenharmony_ciint SCT_get_signature_nid(const SCT *sct) 217e1051a39Sopenharmony_ci{ 218e1051a39Sopenharmony_ci if (sct->version == SCT_VERSION_V1) { 219e1051a39Sopenharmony_ci if (sct->hash_alg == TLSEXT_hash_sha256) { 220e1051a39Sopenharmony_ci switch (sct->sig_alg) { 221e1051a39Sopenharmony_ci case TLSEXT_signature_ecdsa: 222e1051a39Sopenharmony_ci return NID_ecdsa_with_SHA256; 223e1051a39Sopenharmony_ci case TLSEXT_signature_rsa: 224e1051a39Sopenharmony_ci return NID_sha256WithRSAEncryption; 225e1051a39Sopenharmony_ci default: 226e1051a39Sopenharmony_ci return NID_undef; 227e1051a39Sopenharmony_ci } 228e1051a39Sopenharmony_ci } 229e1051a39Sopenharmony_ci } 230e1051a39Sopenharmony_ci return NID_undef; 231e1051a39Sopenharmony_ci} 232e1051a39Sopenharmony_ci 233e1051a39Sopenharmony_cisize_t SCT_get0_extensions(const SCT *sct, unsigned char **ext) 234e1051a39Sopenharmony_ci{ 235e1051a39Sopenharmony_ci *ext = sct->ext; 236e1051a39Sopenharmony_ci return sct->ext_len; 237e1051a39Sopenharmony_ci} 238e1051a39Sopenharmony_ci 239e1051a39Sopenharmony_cisize_t SCT_get0_signature(const SCT *sct, unsigned char **sig) 240e1051a39Sopenharmony_ci{ 241e1051a39Sopenharmony_ci *sig = sct->sig; 242e1051a39Sopenharmony_ci return sct->sig_len; 243e1051a39Sopenharmony_ci} 244e1051a39Sopenharmony_ci 245e1051a39Sopenharmony_ciint SCT_is_complete(const SCT *sct) 246e1051a39Sopenharmony_ci{ 247e1051a39Sopenharmony_ci switch (sct->version) { 248e1051a39Sopenharmony_ci case SCT_VERSION_NOT_SET: 249e1051a39Sopenharmony_ci return 0; 250e1051a39Sopenharmony_ci case SCT_VERSION_V1: 251e1051a39Sopenharmony_ci return sct->log_id != NULL && SCT_signature_is_complete(sct); 252e1051a39Sopenharmony_ci default: 253e1051a39Sopenharmony_ci return sct->sct != NULL; /* Just need cached encoding */ 254e1051a39Sopenharmony_ci } 255e1051a39Sopenharmony_ci} 256e1051a39Sopenharmony_ci 257e1051a39Sopenharmony_ciint SCT_signature_is_complete(const SCT *sct) 258e1051a39Sopenharmony_ci{ 259e1051a39Sopenharmony_ci return SCT_get_signature_nid(sct) != NID_undef && 260e1051a39Sopenharmony_ci sct->sig != NULL && sct->sig_len > 0; 261e1051a39Sopenharmony_ci} 262e1051a39Sopenharmony_ci 263e1051a39Sopenharmony_cisct_source_t SCT_get_source(const SCT *sct) 264e1051a39Sopenharmony_ci{ 265e1051a39Sopenharmony_ci return sct->source; 266e1051a39Sopenharmony_ci} 267e1051a39Sopenharmony_ci 268e1051a39Sopenharmony_ciint SCT_set_source(SCT *sct, sct_source_t source) 269e1051a39Sopenharmony_ci{ 270e1051a39Sopenharmony_ci sct->source = source; 271e1051a39Sopenharmony_ci sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET; 272e1051a39Sopenharmony_ci switch (source) { 273e1051a39Sopenharmony_ci case SCT_SOURCE_TLS_EXTENSION: 274e1051a39Sopenharmony_ci case SCT_SOURCE_OCSP_STAPLED_RESPONSE: 275e1051a39Sopenharmony_ci return SCT_set_log_entry_type(sct, CT_LOG_ENTRY_TYPE_X509); 276e1051a39Sopenharmony_ci case SCT_SOURCE_X509V3_EXTENSION: 277e1051a39Sopenharmony_ci return SCT_set_log_entry_type(sct, CT_LOG_ENTRY_TYPE_PRECERT); 278e1051a39Sopenharmony_ci case SCT_SOURCE_UNKNOWN: 279e1051a39Sopenharmony_ci break; 280e1051a39Sopenharmony_ci } 281e1051a39Sopenharmony_ci /* if we aren't sure, leave the log entry type alone */ 282e1051a39Sopenharmony_ci return 1; 283e1051a39Sopenharmony_ci} 284e1051a39Sopenharmony_ci 285e1051a39Sopenharmony_cisct_validation_status_t SCT_get_validation_status(const SCT *sct) 286e1051a39Sopenharmony_ci{ 287e1051a39Sopenharmony_ci return sct->validation_status; 288e1051a39Sopenharmony_ci} 289e1051a39Sopenharmony_ci 290e1051a39Sopenharmony_ciint SCT_validate(SCT *sct, const CT_POLICY_EVAL_CTX *ctx) 291e1051a39Sopenharmony_ci{ 292e1051a39Sopenharmony_ci int is_sct_valid = -1; 293e1051a39Sopenharmony_ci SCT_CTX *sctx = NULL; 294e1051a39Sopenharmony_ci X509_PUBKEY *pub = NULL, *log_pkey = NULL; 295e1051a39Sopenharmony_ci const CTLOG *log; 296e1051a39Sopenharmony_ci 297e1051a39Sopenharmony_ci /* 298e1051a39Sopenharmony_ci * With an unrecognized SCT version we don't know what such an SCT means, 299e1051a39Sopenharmony_ci * let alone validate one. So we return validation failure (0). 300e1051a39Sopenharmony_ci */ 301e1051a39Sopenharmony_ci if (sct->version != SCT_VERSION_V1) { 302e1051a39Sopenharmony_ci sct->validation_status = SCT_VALIDATION_STATUS_UNKNOWN_VERSION; 303e1051a39Sopenharmony_ci return 0; 304e1051a39Sopenharmony_ci } 305e1051a39Sopenharmony_ci 306e1051a39Sopenharmony_ci log = CTLOG_STORE_get0_log_by_id(ctx->log_store, 307e1051a39Sopenharmony_ci sct->log_id, sct->log_id_len); 308e1051a39Sopenharmony_ci 309e1051a39Sopenharmony_ci /* Similarly, an SCT from an unknown log also cannot be validated. */ 310e1051a39Sopenharmony_ci if (log == NULL) { 311e1051a39Sopenharmony_ci sct->validation_status = SCT_VALIDATION_STATUS_UNKNOWN_LOG; 312e1051a39Sopenharmony_ci return 0; 313e1051a39Sopenharmony_ci } 314e1051a39Sopenharmony_ci 315e1051a39Sopenharmony_ci sctx = SCT_CTX_new(ctx->libctx, ctx->propq); 316e1051a39Sopenharmony_ci if (sctx == NULL) 317e1051a39Sopenharmony_ci goto err; 318e1051a39Sopenharmony_ci 319e1051a39Sopenharmony_ci if (X509_PUBKEY_set(&log_pkey, CTLOG_get0_public_key(log)) != 1) 320e1051a39Sopenharmony_ci goto err; 321e1051a39Sopenharmony_ci if (SCT_CTX_set1_pubkey(sctx, log_pkey) != 1) 322e1051a39Sopenharmony_ci goto err; 323e1051a39Sopenharmony_ci 324e1051a39Sopenharmony_ci if (SCT_get_log_entry_type(sct) == CT_LOG_ENTRY_TYPE_PRECERT) { 325e1051a39Sopenharmony_ci EVP_PKEY *issuer_pkey; 326e1051a39Sopenharmony_ci 327e1051a39Sopenharmony_ci if (ctx->issuer == NULL) { 328e1051a39Sopenharmony_ci sct->validation_status = SCT_VALIDATION_STATUS_UNVERIFIED; 329e1051a39Sopenharmony_ci goto end; 330e1051a39Sopenharmony_ci } 331e1051a39Sopenharmony_ci 332e1051a39Sopenharmony_ci issuer_pkey = X509_get0_pubkey(ctx->issuer); 333e1051a39Sopenharmony_ci 334e1051a39Sopenharmony_ci if (X509_PUBKEY_set(&pub, issuer_pkey) != 1) 335e1051a39Sopenharmony_ci goto err; 336e1051a39Sopenharmony_ci if (SCT_CTX_set1_issuer_pubkey(sctx, pub) != 1) 337e1051a39Sopenharmony_ci goto err; 338e1051a39Sopenharmony_ci } 339e1051a39Sopenharmony_ci 340e1051a39Sopenharmony_ci SCT_CTX_set_time(sctx, ctx->epoch_time_in_ms); 341e1051a39Sopenharmony_ci 342e1051a39Sopenharmony_ci /* 343e1051a39Sopenharmony_ci * XXX: Potential for optimization. This repeats some idempotent heavy 344e1051a39Sopenharmony_ci * lifting on the certificate for each candidate SCT, and appears to not 345e1051a39Sopenharmony_ci * use any information in the SCT itself, only the certificate is 346e1051a39Sopenharmony_ci * processed. So it may make more sense to do this just once, perhaps 347e1051a39Sopenharmony_ci * associated with the shared (by all SCTs) policy eval ctx. 348e1051a39Sopenharmony_ci * 349e1051a39Sopenharmony_ci * XXX: Failure here is global (SCT independent) and represents either an 350e1051a39Sopenharmony_ci * issue with the certificate (e.g. duplicate extensions) or an out of 351e1051a39Sopenharmony_ci * memory condition. When the certificate is incompatible with CT, we just 352e1051a39Sopenharmony_ci * mark the SCTs invalid, rather than report a failure to determine the 353e1051a39Sopenharmony_ci * validation status. That way, callbacks that want to do "soft" SCT 354e1051a39Sopenharmony_ci * processing will not abort handshakes with false positive internal 355e1051a39Sopenharmony_ci * errors. Since the function does not distinguish between certificate 356e1051a39Sopenharmony_ci * issues (peer's fault) and internal problems (out fault) the safe thing 357e1051a39Sopenharmony_ci * to do is to report a validation failure and let the callback or 358e1051a39Sopenharmony_ci * application decide what to do. 359e1051a39Sopenharmony_ci */ 360e1051a39Sopenharmony_ci if (SCT_CTX_set1_cert(sctx, ctx->cert, NULL) != 1) 361e1051a39Sopenharmony_ci sct->validation_status = SCT_VALIDATION_STATUS_UNVERIFIED; 362e1051a39Sopenharmony_ci else 363e1051a39Sopenharmony_ci sct->validation_status = SCT_CTX_verify(sctx, sct) == 1 ? 364e1051a39Sopenharmony_ci SCT_VALIDATION_STATUS_VALID : SCT_VALIDATION_STATUS_INVALID; 365e1051a39Sopenharmony_ci 366e1051a39Sopenharmony_ciend: 367e1051a39Sopenharmony_ci is_sct_valid = sct->validation_status == SCT_VALIDATION_STATUS_VALID; 368e1051a39Sopenharmony_cierr: 369e1051a39Sopenharmony_ci X509_PUBKEY_free(pub); 370e1051a39Sopenharmony_ci X509_PUBKEY_free(log_pkey); 371e1051a39Sopenharmony_ci SCT_CTX_free(sctx); 372e1051a39Sopenharmony_ci 373e1051a39Sopenharmony_ci return is_sct_valid; 374e1051a39Sopenharmony_ci} 375e1051a39Sopenharmony_ci 376e1051a39Sopenharmony_ciint SCT_LIST_validate(const STACK_OF(SCT) *scts, CT_POLICY_EVAL_CTX *ctx) 377e1051a39Sopenharmony_ci{ 378e1051a39Sopenharmony_ci int are_scts_valid = 1; 379e1051a39Sopenharmony_ci int sct_count = scts != NULL ? sk_SCT_num(scts) : 0; 380e1051a39Sopenharmony_ci int i; 381e1051a39Sopenharmony_ci 382e1051a39Sopenharmony_ci for (i = 0; i < sct_count; ++i) { 383e1051a39Sopenharmony_ci int is_sct_valid = -1; 384e1051a39Sopenharmony_ci SCT *sct = sk_SCT_value(scts, i); 385e1051a39Sopenharmony_ci 386e1051a39Sopenharmony_ci if (sct == NULL) 387e1051a39Sopenharmony_ci continue; 388e1051a39Sopenharmony_ci 389e1051a39Sopenharmony_ci is_sct_valid = SCT_validate(sct, ctx); 390e1051a39Sopenharmony_ci if (is_sct_valid < 0) 391e1051a39Sopenharmony_ci return is_sct_valid; 392e1051a39Sopenharmony_ci are_scts_valid &= is_sct_valid; 393e1051a39Sopenharmony_ci } 394e1051a39Sopenharmony_ci 395e1051a39Sopenharmony_ci return are_scts_valid; 396e1051a39Sopenharmony_ci} 397