CT: check some GeneralizedTime return values
[openssl.git] / crypto / ct / ct_vfy.c
1 /*
2  * Written by Rob Stradling (rob@comodo.com) and Stephen Henson
3  * (steve@openssl.org) for the OpenSSL project 2014.
4  */
5 /* ====================================================================
6  * Copyright (c) 2014 The OpenSSL Project.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  *    software must display the following acknowledgment:
22  *    "This product includes software developed by the OpenSSL Project
23  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  *    endorse or promote products derived from this software without
27  *    prior written permission. For written permission, please contact
28  *    licensing@OpenSSL.org.
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  *    nor may "OpenSSL" appear in their names without prior written
32  *    permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  *    acknowledgment:
36  *    "This product includes software developed by the OpenSSL Project
37  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  *
53  * This product includes cryptographic software written by Eric Young
54  * (eay@cryptsoft.com).  This product includes software written by Tim
55  * Hudson (tjh@cryptsoft.com).
56  *
57  */
58
59 #include <string.h>
60
61 #include <openssl/ct.h>
62 #include <openssl/err.h>
63 #include <openssl/evp.h>
64 #include <openssl/x509.h>
65
66 #include "ct_locl.h"
67
68 typedef enum sct_signature_type_t {
69     SIGNATURE_TYPE_NOT_SET = -1,
70     SIGNATURE_TYPE_CERT_TIMESTAMP,
71     SIGNATURE_TYPE_TREE_HASH
72 } SCT_SIGNATURE_TYPE;
73
74 int CT_verify_no_bad_scts(const CT_POLICY_EVAL_CTX *ctx,
75                           const STACK_OF(SCT) *scts, void *arg)
76 {
77     int sct_count = scts != NULL ? sk_SCT_num(scts) : 0;
78     int i;
79
80     for (i = 0; i < sct_count; ++i) {
81         SCT *sct = sk_SCT_value(scts, i);
82
83         switch (SCT_get_validation_status(sct)) {
84             case SCT_VALIDATION_STATUS_INVALID:
85                 return 0;
86             case SCT_VALIDATION_STATUS_NOT_SET:
87                 CTerr(CT_F_CT_VERIFY_NO_BAD_SCTS,
88                       CT_R_SCT_VALIDATION_STATUS_NOT_SET);
89                 return -1;
90             default:
91                 /* Ignore other validation statuses. */
92                 break;
93         }
94     }
95
96     return 1;
97 }
98
99 int CT_verify_at_least_one_good_sct(const CT_POLICY_EVAL_CTX *ctx,
100                                     const STACK_OF(SCT) *scts, void *arg)
101 {
102     int sct_count = scts != NULL ? sk_SCT_num(scts) : 0;
103     int valid_scts = 0;
104     int i;
105
106     for (i = 0; i < sct_count; ++i) {
107         SCT *sct = sk_SCT_value(scts, i);
108
109         switch (SCT_get_validation_status(sct)) {
110             case SCT_VALIDATION_STATUS_VALID:
111                 ++valid_scts;
112                 break;
113             case SCT_VALIDATION_STATUS_INVALID:
114                 return 0;
115             case SCT_VALIDATION_STATUS_NOT_SET:
116                 CTerr(CT_F_CT_VERIFY_AT_LEAST_ONE_GOOD_SCT,
117                       CT_R_SCT_VALIDATION_STATUS_NOT_SET);
118                 return -1;
119             default:
120                 /* Ignore other validation statuses. */
121                 break;
122         }
123     }
124
125     if (valid_scts == 0) {
126         CTerr(CT_F_CT_VERIFY_AT_LEAST_ONE_GOOD_SCT, CT_R_NOT_ENOUGH_SCTS);
127         return 0;
128     }
129
130     return 1;
131 }
132
133 /*
134  * Update encoding for SCT signature verification/generation to supplied
135  * EVP_MD_CTX.
136  */
137 static int sct_ctx_update(EVP_MD_CTX *ctx, const SCT_CTX *sctx, const SCT *sct)
138 {
139     unsigned char tmpbuf[12];
140     unsigned char *p, *der;
141     size_t derlen;
142     /*+
143      * digitally-signed struct {
144      *   (1 byte) Version sct_version;
145      *   (1 byte) SignatureType signature_type = certificate_timestamp;
146      *   (8 bytes) uint64 timestamp;
147      *   (2 bytes) LogEntryType entry_type;
148      *   (? bytes) select(entry_type) {
149      *     case x509_entry: ASN.1Cert;
150      *     case precert_entry: PreCert;
151      *   } signed_entry;
152      *   (2 bytes + sct->ext_len) CtExtensions extensions;
153      * }
154      */
155     if (sct->entry_type == CT_LOG_ENTRY_TYPE_NOT_SET)
156         return 0;
157     if (sct->entry_type == CT_LOG_ENTRY_TYPE_PRECERT && sctx->ihash == NULL)
158         return 0;
159
160     p = tmpbuf;
161     *p++ = sct->version;
162     *p++ = SIGNATURE_TYPE_CERT_TIMESTAMP;
163     l2n8(sct->timestamp, p);
164     s2n(sct->entry_type, p);
165
166     if (!EVP_DigestUpdate(ctx, tmpbuf, p - tmpbuf))
167         return 0;
168
169     if (sct->entry_type == CT_LOG_ENTRY_TYPE_X509) {
170         der = sctx->certder;
171         derlen = sctx->certderlen;
172     } else {
173         if (!EVP_DigestUpdate(ctx, sctx->ihash, sctx->ihashlen))
174             return 0;
175         der = sctx->preder;
176         derlen = sctx->prederlen;
177     }
178
179     /* If no encoding available, fatal error */
180     if (der == NULL)
181         return 0;
182
183     /* Include length first */
184     p = tmpbuf;
185     l2n3(derlen, p);
186
187     if (!EVP_DigestUpdate(ctx, tmpbuf, 3))
188         return 0;
189     if (!EVP_DigestUpdate(ctx, der, derlen))
190         return 0;
191
192     /* Add any extensions */
193     p = tmpbuf;
194     s2n(sct->ext_len, p);
195     if (!EVP_DigestUpdate(ctx, tmpbuf, 2))
196         return 0;
197
198     if (sct->ext_len && !EVP_DigestUpdate(ctx, sct->ext, sct->ext_len))
199         return 0;
200
201     return 1;
202 }
203
204 int SCT_verify(const SCT_CTX *sctx, const SCT *sct)
205 {
206     EVP_MD_CTX *ctx = NULL;
207     int ret = 0;
208
209     if (!SCT_is_complete(sct) || sctx->pkey == NULL ||
210         sct->entry_type == CT_LOG_ENTRY_TYPE_NOT_SET ||
211         (sct->entry_type == CT_LOG_ENTRY_TYPE_PRECERT && sctx->ihash == NULL)) {
212         CTerr(CT_F_SCT_VERIFY, CT_R_SCT_NOT_SET);
213         return 0;
214     }
215     if (sct->version != SCT_VERSION_V1) {
216         CTerr(CT_F_SCT_VERIFY, CT_R_SCT_UNSUPPORTED_VERSION);
217         return 0;
218     }
219     if (sct->log_id_len != sctx->pkeyhashlen ||
220         memcmp(sct->log_id, sctx->pkeyhash, sctx->pkeyhashlen) != 0) {
221         CTerr(CT_F_SCT_VERIFY, CT_R_SCT_LOG_ID_MISMATCH);
222         return 0;
223     }
224
225     ctx = EVP_MD_CTX_new();
226     if (ctx == NULL)
227         goto end;
228
229     if (!EVP_DigestVerifyInit(ctx, NULL, EVP_sha256(), NULL, sctx->pkey))
230         goto end;
231
232     if (!sct_ctx_update(ctx, sctx, sct))
233         goto end;
234
235     /* Verify signature */
236     ret = EVP_DigestVerifyFinal(ctx, sct->sig, sct->sig_len);
237     /* If ret < 0 some other error: fall through without setting error */
238     if (ret == 0)
239         CTerr(CT_F_SCT_VERIFY, CT_R_SCT_INVALID_SIGNATURE);
240
241 end:
242     EVP_MD_CTX_free(ctx);
243     return ret;
244 }
245
246 int SCT_verify_v1(SCT *sct, X509 *cert, X509 *preissuer,
247                   X509_PUBKEY *log_pubkey, X509 *issuer_cert)
248 {
249     int ret = 0;
250     SCT_CTX *sctx = NULL;
251
252     if (!SCT_is_complete(sct)) {
253         CTerr(CT_F_SCT_VERIFY_V1, CT_R_SCT_NOT_SET);
254         return 0;
255     }
256
257     if (sct->version != 0) {
258         CTerr(CT_F_SCT_VERIFY_V1, CT_R_SCT_UNSUPPORTED_VERSION);
259         return 0;
260     }
261
262     sctx = SCT_CTX_new();
263     if (sctx == NULL)
264         goto done;
265
266     if (!SCT_CTX_set1_pubkey(sctx, log_pubkey))
267         goto done;
268
269     if (!SCT_CTX_set1_cert(sctx, cert, preissuer))
270         goto done;
271
272     if (sct->entry_type == CT_LOG_ENTRY_TYPE_PRECERT &&
273         !SCT_CTX_set1_issuer(sctx, issuer_cert))
274         goto done;
275
276     ret = SCT_verify(sctx, sct);
277 done:
278     SCT_CTX_free(sctx);
279     return ret;
280 }