From 989541ef5e501dd160105f4c80a6f4dfb1ca0027 Mon Sep 17 00:00:00 2001 From: jsing Date: Thu, 6 Jan 2022 14:34:40 +0000 Subject: [PATCH] Convert SCT verification to CBB. ok inoguchi@ tb@ --- lib/libcrypto/ct/ct_vfy.c | 113 +++++++++++++++++++------------------- 1 file changed, 57 insertions(+), 56 deletions(-) diff --git a/lib/libcrypto/ct/ct_vfy.c b/lib/libcrypto/ct/ct_vfy.c index e88f9394b86..424117263a0 100644 --- a/lib/libcrypto/ct/ct_vfy.c +++ b/lib/libcrypto/ct/ct_vfy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ct_vfy.c,v 1.5 2021/12/18 16:34:52 tb Exp $ */ +/* $OpenBSD: ct_vfy.c,v 1.6 2022/01/06 14:34:40 jsing Exp $ */ /* * Written by Rob Stradling (rob@comodo.com) and Stephen Henson * (steve@openssl.org) for the OpenSSL project 2014. @@ -79,70 +79,72 @@ typedef enum sct_signature_type_t { static int sct_ctx_update(EVP_MD_CTX *ctx, const SCT_CTX *sctx, const SCT *sct) { - unsigned char tmpbuf[12]; - unsigned char *p, *der; - size_t derlen; - - /*+ - * digitally-signed struct { - * (1 byte) Version sct_version; - * (1 byte) SignatureType signature_type = certificate_timestamp; - * (8 bytes) uint64 timestamp; - * (2 bytes) LogEntryType entry_type; - * (? bytes) select(entry_type) { - * case x509_entry: ASN.1Cert; - * case precert_entry: PreCert; - * } signed_entry; - * (2 bytes + sct->ext_len) CtExtensions extensions; - * } - */ + CBB cbb, entry, extensions; + uint8_t *data = NULL; + size_t data_len; + int ret = 0; + + memset(&cbb, 0, sizeof(cbb)); + if (sct->entry_type == CT_LOG_ENTRY_TYPE_NOT_SET) - return 0; + goto err; if (sct->entry_type == CT_LOG_ENTRY_TYPE_PRECERT && sctx->ihash == NULL) - return 0; + goto err; - p = tmpbuf; - *p++ = sct->version; - *p++ = SIGNATURE_TYPE_CERT_TIMESTAMP; - l2n8(sct->timestamp, p); - s2n(sct->entry_type, p); + if (!CBB_init(&cbb, 0)) + goto err; - if (!EVP_DigestUpdate(ctx, tmpbuf, p - tmpbuf)) - return 0; + /* + * Build the digitally-signed struct per RFC 6962 section 3.2. + */ + if (!CBB_add_u8(&cbb, sct->version)) + goto err; + if (!CBB_add_u8(&cbb, SIGNATURE_TYPE_CERT_TIMESTAMP)) + goto err; + if (!CBB_add_u64(&cbb, sct->timestamp)) + goto err; + if (!CBB_add_u16(&cbb, sct->entry_type)) + goto err; + + if (sct->entry_type == CT_LOG_ENTRY_TYPE_PRECERT) { + if (!CBB_add_bytes(&cbb, sctx->ihash, sctx->ihashlen)) + goto err; + } - if (sct->entry_type == CT_LOG_ENTRY_TYPE_X509) { - der = sctx->certder; - derlen = sctx->certderlen; + if (!CBB_add_u24_length_prefixed(&cbb, &entry)) + goto err; + if (sct->entry_type == CT_LOG_ENTRY_TYPE_PRECERT) { + if (sctx->preder == NULL) + goto err; + if (!CBB_add_bytes(&entry, sctx->preder, sctx->prederlen)) + goto err; } else { - if (!EVP_DigestUpdate(ctx, sctx->ihash, sctx->ihashlen)) - return 0; - der = sctx->preder; - derlen = sctx->prederlen; + if (sctx->certder == NULL) + goto err; + if (!CBB_add_bytes(&entry, sctx->certder, sctx->certderlen)) + goto err; } - /* If no encoding available, fatal error */ - if (der == NULL) - return 0; + if (!CBB_add_u16_length_prefixed(&cbb, &extensions)) + goto err; + if (sct->ext_len > 0) { + if (!CBB_add_bytes(&extensions, sct->ext, sct->ext_len)) + goto err; + } - /* Include length first */ - p = tmpbuf; - l2n3(derlen, p); + if (!CBB_finish(&cbb, &data, &data_len)) + goto err; - if (!EVP_DigestUpdate(ctx, tmpbuf, 3)) - return 0; - if (!EVP_DigestUpdate(ctx, der, derlen)) - return 0; + if (!EVP_DigestUpdate(ctx, data, data_len)) + goto err; - /* Add any extensions */ - p = tmpbuf; - s2n(sct->ext_len, p); - if (!EVP_DigestUpdate(ctx, tmpbuf, 2)) - return 0; + ret = 1; - if (sct->ext_len && !EVP_DigestUpdate(ctx, sct->ext, sct->ext_len)) - return 0; + err: + CBB_cleanup(&cbb); + free(data); - return 1; + return ret; } int @@ -172,8 +174,7 @@ SCT_CTX_verify(const SCT_CTX *sctx, const SCT *sct) return 0; } - ctx = EVP_MD_CTX_new(); - if (ctx == NULL) + if ((ctx = EVP_MD_CTX_new()) == NULL) goto end; if (!EVP_DigestVerifyInit(ctx, NULL, EVP_sha256(), NULL, sctx->pkey)) @@ -183,12 +184,12 @@ SCT_CTX_verify(const SCT_CTX *sctx, const SCT *sct) goto end; /* Verify signature */ - ret = EVP_DigestVerifyFinal(ctx, sct->sig, sct->sig_len); /* If ret < 0 some other error: fall through without setting error */ - if (ret == 0) + if ((ret = EVP_DigestVerifyFinal(ctx, sct->sig, sct->sig_len)) == 0) CTerror(CT_R_SCT_INVALID_SIGNATURE); end: EVP_MD_CTX_free(ctx); + return ret; } -- 2.20.1