1*989541efSjsing /* $OpenBSD: ct_vfy.c,v 1.6 2022/01/06 14:34:40 jsing Exp $ */
2137efc4eSbeck /*
3f732855dStb * Written by Rob Stradling (rob@comodo.com) and Stephen Henson
4f732855dStb * (steve@openssl.org) for the OpenSSL project 2014.
5f732855dStb */
6f732855dStb /* ====================================================================
7f732855dStb * Copyright (c) 2014 The OpenSSL Project. All rights reserved.
8137efc4eSbeck *
9f732855dStb * Redistribution and use in source and binary forms, with or without
10f732855dStb * modification, are permitted provided that the following conditions
11f732855dStb * are met:
12f732855dStb *
13f732855dStb * 1. Redistributions of source code must retain the above copyright
14f732855dStb * notice, this list of conditions and the following disclaimer.
15f732855dStb *
16f732855dStb * 2. Redistributions in binary form must reproduce the above copyright
17f732855dStb * notice, this list of conditions and the following disclaimer in
18f732855dStb * the documentation and/or other materials provided with the
19f732855dStb * distribution.
20f732855dStb *
21f732855dStb * 3. All advertising materials mentioning features or use of this
22f732855dStb * software must display the following acknowledgment:
23f732855dStb * "This product includes software developed by the OpenSSL Project
24f732855dStb * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25f732855dStb *
26f732855dStb * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27f732855dStb * endorse or promote products derived from this software without
28f732855dStb * prior written permission. For written permission, please contact
29f732855dStb * licensing@OpenSSL.org.
30f732855dStb *
31f732855dStb * 5. Products derived from this software may not be called "OpenSSL"
32f732855dStb * nor may "OpenSSL" appear in their names without prior written
33f732855dStb * permission of the OpenSSL Project.
34f732855dStb *
35f732855dStb * 6. Redistributions of any form whatsoever must retain the following
36f732855dStb * acknowledgment:
37f732855dStb * "This product includes software developed by the OpenSSL Project
38f732855dStb * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39f732855dStb *
40f732855dStb * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41f732855dStb * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42f732855dStb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43f732855dStb * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44f732855dStb * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45f732855dStb * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46f732855dStb * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47f732855dStb * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48f732855dStb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49f732855dStb * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50f732855dStb * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51f732855dStb * OF THE POSSIBILITY OF SUCH DAMAGE.
52f732855dStb * ====================================================================
53f732855dStb *
54f732855dStb * This product includes cryptographic software written by Eric Young
55f732855dStb * (eay@cryptsoft.com). This product includes software written by Tim
56f732855dStb * Hudson (tjh@cryptsoft.com).
57f732855dStb *
58137efc4eSbeck */
59137efc4eSbeck
60137efc4eSbeck #include <string.h>
61137efc4eSbeck
62137efc4eSbeck #include <openssl/ct.h>
63137efc4eSbeck #include <openssl/err.h>
64137efc4eSbeck #include <openssl/evp.h>
65137efc4eSbeck #include <openssl/x509.h>
66137efc4eSbeck
67137efc4eSbeck #include "ct_local.h"
68137efc4eSbeck
69137efc4eSbeck typedef enum sct_signature_type_t {
70137efc4eSbeck SIGNATURE_TYPE_NOT_SET = -1,
71137efc4eSbeck SIGNATURE_TYPE_CERT_TIMESTAMP,
72137efc4eSbeck SIGNATURE_TYPE_TREE_HASH
73137efc4eSbeck } SCT_SIGNATURE_TYPE;
74137efc4eSbeck
75137efc4eSbeck /*
76137efc4eSbeck * Update encoding for SCT signature verification/generation to supplied
77137efc4eSbeck * EVP_MD_CTX.
78137efc4eSbeck */
794c53c909Sbeck static int
sct_ctx_update(EVP_MD_CTX * ctx,const SCT_CTX * sctx,const SCT * sct)804c53c909Sbeck sct_ctx_update(EVP_MD_CTX *ctx, const SCT_CTX *sctx, const SCT *sct)
81137efc4eSbeck {
82*989541efSjsing CBB cbb, entry, extensions;
83*989541efSjsing uint8_t *data = NULL;
84*989541efSjsing size_t data_len;
85*989541efSjsing int ret = 0;
8632d9a10fSbeck
87*989541efSjsing memset(&cbb, 0, sizeof(cbb));
88*989541efSjsing
89137efc4eSbeck if (sct->entry_type == CT_LOG_ENTRY_TYPE_NOT_SET)
90*989541efSjsing goto err;
91137efc4eSbeck if (sct->entry_type == CT_LOG_ENTRY_TYPE_PRECERT && sctx->ihash == NULL)
92*989541efSjsing goto err;
93137efc4eSbeck
94*989541efSjsing if (!CBB_init(&cbb, 0))
95*989541efSjsing goto err;
96137efc4eSbeck
97*989541efSjsing /*
98*989541efSjsing * Build the digitally-signed struct per RFC 6962 section 3.2.
99*989541efSjsing */
100*989541efSjsing if (!CBB_add_u8(&cbb, sct->version))
101*989541efSjsing goto err;
102*989541efSjsing if (!CBB_add_u8(&cbb, SIGNATURE_TYPE_CERT_TIMESTAMP))
103*989541efSjsing goto err;
104*989541efSjsing if (!CBB_add_u64(&cbb, sct->timestamp))
105*989541efSjsing goto err;
106*989541efSjsing if (!CBB_add_u16(&cbb, sct->entry_type))
107*989541efSjsing goto err;
108137efc4eSbeck
109*989541efSjsing if (sct->entry_type == CT_LOG_ENTRY_TYPE_PRECERT) {
110*989541efSjsing if (!CBB_add_bytes(&cbb, sctx->ihash, sctx->ihashlen))
111*989541efSjsing goto err;
112137efc4eSbeck }
113137efc4eSbeck
114*989541efSjsing if (!CBB_add_u24_length_prefixed(&cbb, &entry))
115*989541efSjsing goto err;
116*989541efSjsing if (sct->entry_type == CT_LOG_ENTRY_TYPE_PRECERT) {
117*989541efSjsing if (sctx->preder == NULL)
118*989541efSjsing goto err;
119*989541efSjsing if (!CBB_add_bytes(&entry, sctx->preder, sctx->prederlen))
120*989541efSjsing goto err;
121*989541efSjsing } else {
122*989541efSjsing if (sctx->certder == NULL)
123*989541efSjsing goto err;
124*989541efSjsing if (!CBB_add_bytes(&entry, sctx->certder, sctx->certderlen))
125*989541efSjsing goto err;
126*989541efSjsing }
127137efc4eSbeck
128*989541efSjsing if (!CBB_add_u16_length_prefixed(&cbb, &extensions))
129*989541efSjsing goto err;
130*989541efSjsing if (sct->ext_len > 0) {
131*989541efSjsing if (!CBB_add_bytes(&extensions, sct->ext, sct->ext_len))
132*989541efSjsing goto err;
133*989541efSjsing }
134137efc4eSbeck
135*989541efSjsing if (!CBB_finish(&cbb, &data, &data_len))
136*989541efSjsing goto err;
137137efc4eSbeck
138*989541efSjsing if (!EVP_DigestUpdate(ctx, data, data_len))
139*989541efSjsing goto err;
140137efc4eSbeck
141*989541efSjsing ret = 1;
142137efc4eSbeck
143*989541efSjsing err:
144*989541efSjsing CBB_cleanup(&cbb);
145*989541efSjsing free(data);
146*989541efSjsing
147*989541efSjsing return ret;
148137efc4eSbeck }
149137efc4eSbeck
1504c53c909Sbeck int
SCT_CTX_verify(const SCT_CTX * sctx,const SCT * sct)1514c53c909Sbeck SCT_CTX_verify(const SCT_CTX *sctx, const SCT *sct)
152137efc4eSbeck {
153137efc4eSbeck EVP_MD_CTX *ctx = NULL;
154137efc4eSbeck int ret = 0;
155137efc4eSbeck
156137efc4eSbeck if (!SCT_is_complete(sct) || sctx->pkey == NULL ||
157137efc4eSbeck sct->entry_type == CT_LOG_ENTRY_TYPE_NOT_SET ||
15832d9a10fSbeck (sct->entry_type == CT_LOG_ENTRY_TYPE_PRECERT &&
15932d9a10fSbeck sctx->ihash == NULL)) {
16032d9a10fSbeck CTerror(CT_R_SCT_NOT_SET);
161137efc4eSbeck return 0;
162137efc4eSbeck }
163137efc4eSbeck if (sct->version != SCT_VERSION_V1) {
16432d9a10fSbeck CTerror(CT_R_SCT_UNSUPPORTED_VERSION);
165137efc4eSbeck return 0;
166137efc4eSbeck }
167137efc4eSbeck if (sct->log_id_len != sctx->pkeyhashlen ||
168137efc4eSbeck memcmp(sct->log_id, sctx->pkeyhash, sctx->pkeyhashlen) != 0) {
16932d9a10fSbeck CTerror(CT_R_SCT_LOG_ID_MISMATCH);
170137efc4eSbeck return 0;
171137efc4eSbeck }
172137efc4eSbeck if (sct->timestamp > sctx->epoch_time_in_ms) {
17332d9a10fSbeck CTerror(CT_R_SCT_FUTURE_TIMESTAMP);
174137efc4eSbeck return 0;
175137efc4eSbeck }
176137efc4eSbeck
177*989541efSjsing if ((ctx = EVP_MD_CTX_new()) == NULL)
178137efc4eSbeck goto end;
179137efc4eSbeck
180137efc4eSbeck if (!EVP_DigestVerifyInit(ctx, NULL, EVP_sha256(), NULL, sctx->pkey))
181137efc4eSbeck goto end;
182137efc4eSbeck
183137efc4eSbeck if (!sct_ctx_update(ctx, sctx, sct))
184137efc4eSbeck goto end;
185137efc4eSbeck
186137efc4eSbeck /* Verify signature */
187137efc4eSbeck /* If ret < 0 some other error: fall through without setting error */
188*989541efSjsing if ((ret = EVP_DigestVerifyFinal(ctx, sct->sig, sct->sig_len)) == 0)
18932d9a10fSbeck CTerror(CT_R_SCT_INVALID_SIGNATURE);
190137efc4eSbeck
191137efc4eSbeck end:
192137efc4eSbeck EVP_MD_CTX_free(ctx);
193*989541efSjsing
194137efc4eSbeck return ret;
195137efc4eSbeck }
196