356c79768fb2839caa939ab230c6eaf6f5013162
[openssl.git] / crypto / ocsp / ocsp_vfy.c
1 /*
2  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
3  * 2000.
4  */
5 /* ====================================================================
6  * Copyright (c) 2000-2004 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 <openssl/ocsp.h>
60 #include "ocsp_lcl.h"
61 #include <openssl/err.h>
62 #include <string.h>
63
64 static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs,
65                             STACK_OF(X509) *certs, unsigned long flags);
66 static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id);
67 static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain);
68 static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp,
69                           OCSP_CERTID **ret);
70 static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid,
71                                STACK_OF(OCSP_SINGLERESP) *sresp);
72 static int ocsp_check_delegated(X509 *x);
73 static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req,
74                                 X509_NAME *nm, STACK_OF(X509) *certs,
75                                 unsigned long flags);
76
77 /* Verify a basic response message */
78
79 int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
80                       X509_STORE *st, unsigned long flags)
81 {
82     X509 *signer, *x;
83     STACK_OF(X509) *chain = NULL;
84     STACK_OF(X509) *untrusted = NULL;
85     X509_STORE_CTX ctx;
86     int i, ret = ocsp_find_signer(&signer, bs, certs, flags);
87
88     if (!ret) {
89         OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,
90                 OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND);
91         goto end;
92     }
93     if ((ret == 2) && (flags & OCSP_TRUSTOTHER))
94         flags |= OCSP_NOVERIFY;
95     if (!(flags & OCSP_NOSIGS)) {
96         EVP_PKEY *skey;
97         skey = X509_get0_pubkey(signer);
98         if (skey)
99             ret = OCSP_BASICRESP_verify(bs, skey, 0);
100         if (!skey || ret <= 0) {
101             OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNATURE_FAILURE);
102             goto end;
103         }
104     }
105     if (!(flags & OCSP_NOVERIFY)) {
106         int init_res;
107         if (flags & OCSP_NOCHAIN) {
108             untrusted = NULL;
109         } else if (bs->certs && certs) {
110             untrusted = sk_X509_dup(bs->certs);
111             for (i = 0; i < sk_X509_num(certs); i++) {
112                 if (!sk_X509_push(untrusted, sk_X509_value(certs, i))) {
113                     OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_MALLOC_FAILURE);
114                     goto end;
115                 }
116             }
117         } else {
118             untrusted = bs->certs;
119         }
120         init_res = X509_STORE_CTX_init(&ctx, st, signer, untrusted);
121         if (!init_res) {
122             ret = -1;
123             OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_X509_LIB);
124             goto end;
125         }
126
127         X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER);
128         ret = X509_verify_cert(&ctx);
129         chain = X509_STORE_CTX_get1_chain(&ctx);
130         X509_STORE_CTX_cleanup(&ctx);
131         if (ret <= 0) {
132             i = X509_STORE_CTX_get_error(&ctx);
133             OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,
134                     OCSP_R_CERTIFICATE_VERIFY_ERROR);
135             ERR_add_error_data(2, "Verify error:",
136                                X509_verify_cert_error_string(i));
137             goto end;
138         }
139         if (flags & OCSP_NOCHECKS) {
140             ret = 1;
141             goto end;
142         }
143         /*
144          * At this point we have a valid certificate chain need to verify it
145          * against the OCSP issuer criteria.
146          */
147         ret = ocsp_check_issuer(bs, chain);
148
149         /* If fatal error or valid match then finish */
150         if (ret != 0)
151             goto end;
152
153         /*
154          * Easy case: explicitly trusted. Get root CA and check for explicit
155          * trust
156          */
157         if (flags & OCSP_NOEXPLICIT)
158             goto end;
159
160         x = sk_X509_value(chain, sk_X509_num(chain) - 1);
161         if (X509_check_trust(x, NID_OCSP_sign, 0) != X509_TRUST_TRUSTED) {
162             OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_ROOT_CA_NOT_TRUSTED);
163             goto end;
164         }
165         ret = 1;
166     }
167
168  end:
169     sk_X509_pop_free(chain, X509_free);
170     if (bs->certs && certs)
171         sk_X509_free(untrusted);
172     return ret;
173 }
174
175 static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs,
176                             STACK_OF(X509) *certs, unsigned long flags)
177 {
178     X509 *signer;
179     OCSP_RESPID *rid = &bs->tbsResponseData.responderId;
180     if ((signer = ocsp_find_signer_sk(certs, rid))) {
181         *psigner = signer;
182         return 2;
183     }
184     if (!(flags & OCSP_NOINTERN) &&
185         (signer = ocsp_find_signer_sk(bs->certs, rid))) {
186         *psigner = signer;
187         return 1;
188     }
189     /* Maybe lookup from store if by subject name */
190
191     *psigner = NULL;
192     return 0;
193 }
194
195 static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id)
196 {
197     int i;
198     unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash;
199     X509 *x;
200
201     /* Easy if lookup by name */
202     if (id->type == V_OCSP_RESPID_NAME)
203         return X509_find_by_subject(certs, id->value.byName);
204
205     /* Lookup by key hash */
206
207     /* If key hash isn't SHA1 length then forget it */
208     if (id->value.byKey->length != SHA_DIGEST_LENGTH)
209         return NULL;
210     keyhash = id->value.byKey->data;
211     /* Calculate hash of each key and compare */
212     for (i = 0; i < sk_X509_num(certs); i++) {
213         x = sk_X509_value(certs, i);
214         X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL);
215         if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH))
216             return x;
217     }
218     return NULL;
219 }
220
221 static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain)
222 {
223     STACK_OF(OCSP_SINGLERESP) *sresp;
224     X509 *signer, *sca;
225     OCSP_CERTID *caid = NULL;
226     int i;
227     sresp = bs->tbsResponseData.responses;
228
229     if (sk_X509_num(chain) <= 0) {
230         OCSPerr(OCSP_F_OCSP_CHECK_ISSUER, OCSP_R_NO_CERTIFICATES_IN_CHAIN);
231         return -1;
232     }
233
234     /* See if the issuer IDs match. */
235     i = ocsp_check_ids(sresp, &caid);
236
237     /* If ID mismatch or other error then return */
238     if (i <= 0)
239         return i;
240
241     signer = sk_X509_value(chain, 0);
242     /* Check to see if OCSP responder CA matches request CA */
243     if (sk_X509_num(chain) > 1) {
244         sca = sk_X509_value(chain, 1);
245         i = ocsp_match_issuerid(sca, caid, sresp);
246         if (i < 0)
247             return i;
248         if (i) {
249             /* We have a match, if extensions OK then success */
250             if (ocsp_check_delegated(signer))
251                 return 1;
252             return 0;
253         }
254     }
255
256     /* Otherwise check if OCSP request signed directly by request CA */
257     return ocsp_match_issuerid(signer, caid, sresp);
258 }
259
260 /*
261  * Check the issuer certificate IDs for equality. If there is a mismatch with
262  * the same algorithm then there's no point trying to match any certificates
263  * against the issuer. If the issuer IDs all match then we just need to check
264  * equality against one of them.
265  */
266
267 static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret)
268 {
269     OCSP_CERTID *tmpid, *cid;
270     int i, idcount;
271
272     idcount = sk_OCSP_SINGLERESP_num(sresp);
273     if (idcount <= 0) {
274         OCSPerr(OCSP_F_OCSP_CHECK_IDS,
275                 OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA);
276         return -1;
277     }
278
279     cid = sk_OCSP_SINGLERESP_value(sresp, 0)->certId;
280
281     *ret = NULL;
282
283     for (i = 1; i < idcount; i++) {
284         tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId;
285         /* Check to see if IDs match */
286         if (OCSP_id_issuer_cmp(cid, tmpid)) {
287             /* If algorithm mismatch let caller deal with it */
288             if (OBJ_cmp(tmpid->hashAlgorithm.algorithm,
289                         cid->hashAlgorithm.algorithm))
290                 return 2;
291             /* Else mismatch */
292             return 0;
293         }
294     }
295
296     /* All IDs match: only need to check one ID */
297     *ret = cid;
298     return 1;
299 }
300
301 static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid,
302                                STACK_OF(OCSP_SINGLERESP) *sresp)
303 {
304     /* If only one ID to match then do it */
305     if (cid) {
306         const EVP_MD *dgst;
307         X509_NAME *iname;
308         int mdlen;
309         unsigned char md[EVP_MAX_MD_SIZE];
310         if ((dgst = EVP_get_digestbyobj(cid->hashAlgorithm.algorithm))
311                 == NULL) {
312             OCSPerr(OCSP_F_OCSP_MATCH_ISSUERID,
313                     OCSP_R_UNKNOWN_MESSAGE_DIGEST);
314             return -1;
315         }
316
317         mdlen = EVP_MD_size(dgst);
318         if (mdlen < 0)
319             return -1;
320         if ((cid->issuerNameHash.length != mdlen) ||
321             (cid->issuerKeyHash.length != mdlen))
322             return 0;
323         iname = X509_get_subject_name(cert);
324         if (!X509_NAME_digest(iname, dgst, md, NULL))
325             return -1;
326         if (memcmp(md, cid->issuerNameHash.data, mdlen))
327             return 0;
328         X509_pubkey_digest(cert, dgst, md, NULL);
329         if (memcmp(md, cid->issuerKeyHash.data, mdlen))
330             return 0;
331
332         return 1;
333
334     } else {
335         /* We have to match the whole lot */
336         int i, ret;
337         OCSP_CERTID *tmpid;
338         for (i = 0; i < sk_OCSP_SINGLERESP_num(sresp); i++) {
339             tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId;
340             ret = ocsp_match_issuerid(cert, tmpid, NULL);
341             if (ret <= 0)
342                 return ret;
343         }
344         return 1;
345     }
346
347 }
348
349 static int ocsp_check_delegated(X509 *x)
350 {
351     if ((X509_get_extension_flags(x) & EXFLAG_XKUSAGE)
352         && (X509_get_extended_key_usage(x) & XKU_OCSP_SIGN))
353         return 1;
354     OCSPerr(OCSP_F_OCSP_CHECK_DELEGATED, OCSP_R_MISSING_OCSPSIGNING_USAGE);
355     return 0;
356 }
357
358 /*
359  * Verify an OCSP request. This is fortunately much easier than OCSP response
360  * verify. Just find the signers certificate and verify it against a given
361  * trust value.
362  */
363
364 int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs,
365                         X509_STORE *store, unsigned long flags)
366 {
367     X509 *signer;
368     X509_NAME *nm;
369     GENERAL_NAME *gen;
370     int ret;
371     X509_STORE_CTX ctx;
372     if (!req->optionalSignature) {
373         OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_REQUEST_NOT_SIGNED);
374         return 0;
375     }
376     gen = req->tbsRequest.requestorName;
377     if (!gen || gen->type != GEN_DIRNAME) {
378         OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY,
379                 OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE);
380         return 0;
381     }
382     nm = gen->d.directoryName;
383     ret = ocsp_req_find_signer(&signer, req, nm, certs, flags);
384     if (ret <= 0) {
385         OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY,
386                 OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND);
387         return 0;
388     }
389     if ((ret == 2) && (flags & OCSP_TRUSTOTHER))
390         flags |= OCSP_NOVERIFY;
391     if (!(flags & OCSP_NOSIGS)) {
392         EVP_PKEY *skey;
393         skey = X509_get0_pubkey(signer);
394         ret = OCSP_REQUEST_verify(req, skey);
395         if (ret <= 0) {
396             OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_SIGNATURE_FAILURE);
397             return 0;
398         }
399     }
400     if (!(flags & OCSP_NOVERIFY)) {
401         int init_res;
402         if (flags & OCSP_NOCHAIN)
403             init_res = X509_STORE_CTX_init(&ctx, store, signer, NULL);
404         else
405             init_res = X509_STORE_CTX_init(&ctx, store, signer,
406                                            req->optionalSignature->certs);
407         if (!init_res) {
408             OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, ERR_R_X509_LIB);
409             return 0;
410         }
411
412         X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER);
413         X509_STORE_CTX_set_trust(&ctx, X509_TRUST_OCSP_REQUEST);
414         ret = X509_verify_cert(&ctx);
415         X509_STORE_CTX_cleanup(&ctx);
416         if (ret <= 0) {
417             ret = X509_STORE_CTX_get_error(&ctx);
418             OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY,
419                     OCSP_R_CERTIFICATE_VERIFY_ERROR);
420             ERR_add_error_data(2, "Verify error:",
421                                X509_verify_cert_error_string(ret));
422             return 0;
423         }
424     }
425     return 1;
426 }
427
428 static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req,
429                                 X509_NAME *nm, STACK_OF(X509) *certs,
430                                 unsigned long flags)
431 {
432     X509 *signer;
433     if (!(flags & OCSP_NOINTERN)) {
434         signer = X509_find_by_subject(req->optionalSignature->certs, nm);
435         if (signer) {
436             *psigner = signer;
437             return 1;
438         }
439     }
440
441     signer = X509_find_by_subject(certs, nm);
442     if (signer) {
443         *psigner = signer;
444         return 2;
445     }
446     return 0;
447 }