xref: /freebsd/crypto/openssl/crypto/ocsp/ocsp_vfy.c (revision b077aed33b7b6aefca7b17ddb250cf521f938613)
1 /*
2  * Copyright 2001-2022 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 #include <string.h>
11 #include <openssl/ocsp.h>
12 #include <openssl/err.h>
13 #include "internal/sizes.h"
14 #include "ocsp_local.h"
15 
16 static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs,
17                             STACK_OF(X509) *certs, unsigned long flags);
18 static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id);
19 static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain);
20 static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp,
21                           OCSP_CERTID **ret);
22 static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid,
23                                STACK_OF(OCSP_SINGLERESP) *sresp);
24 static int ocsp_check_delegated(X509 *x);
25 static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req,
26                                 const X509_NAME *nm, STACK_OF(X509) *certs,
27                                 unsigned long flags);
28 
29 /* Returns 1 on success, 0 on failure, or -1 on fatal error */
ocsp_verify_signer(X509 * signer,int response,X509_STORE * st,unsigned long flags,STACK_OF (X509)* untrusted,STACK_OF (X509)** chain)30 static int ocsp_verify_signer(X509 *signer, int response,
31                               X509_STORE *st, unsigned long flags,
32                               STACK_OF(X509) *untrusted, STACK_OF(X509) **chain)
33 {
34     X509_STORE_CTX *ctx = X509_STORE_CTX_new();
35     X509_VERIFY_PARAM *vp;
36     int ret = -1;
37 
38     if (ctx == NULL) {
39         ERR_raise(ERR_LIB_OCSP, ERR_R_MALLOC_FAILURE);
40         goto end;
41     }
42     if (!X509_STORE_CTX_init(ctx, st, signer, untrusted)) {
43         ERR_raise(ERR_LIB_OCSP, ERR_R_X509_LIB);
44         goto end;
45     }
46     if ((vp = X509_STORE_CTX_get0_param(ctx)) == NULL)
47         goto end;
48     if ((flags & OCSP_PARTIAL_CHAIN) != 0)
49         X509_VERIFY_PARAM_set_flags(vp, X509_V_FLAG_PARTIAL_CHAIN);
50     if (response
51             && X509_get_ext_by_NID(signer, NID_id_pkix_OCSP_noCheck, -1) >= 0)
52         /*
53          * Locally disable revocation status checking for OCSP responder cert.
54          * Done here for CRLs; should be done also for OCSP-based checks.
55          */
56         X509_VERIFY_PARAM_clear_flags(vp, X509_V_FLAG_CRL_CHECK);
57     X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_OCSP_HELPER);
58     X509_STORE_CTX_set_trust(ctx, X509_TRUST_OCSP_REQUEST);
59 
60     ret = X509_verify_cert(ctx);
61     if (ret <= 0) {
62         int err = X509_STORE_CTX_get_error(ctx);
63 
64         ERR_raise_data(ERR_LIB_OCSP, OCSP_R_CERTIFICATE_VERIFY_ERROR,
65                        "Verify error: %s", X509_verify_cert_error_string(err));
66         goto end;
67     }
68     if (chain != NULL)
69         *chain = X509_STORE_CTX_get1_chain(ctx);
70 
71  end:
72     X509_STORE_CTX_free(ctx);
73     return ret;
74 }
75 
ocsp_verify(OCSP_REQUEST * req,OCSP_BASICRESP * bs,X509 * signer,unsigned long flags)76 static int ocsp_verify(OCSP_REQUEST *req, OCSP_BASICRESP *bs,
77                        X509 *signer, unsigned long flags)
78 {
79     EVP_PKEY *skey;
80     int ret = 1;
81 
82     if ((flags & OCSP_NOSIGS) == 0) {
83         if ((skey = X509_get0_pubkey(signer)) == NULL) {
84             ERR_raise(ERR_LIB_OCSP, OCSP_R_NO_SIGNER_KEY);
85             return -1;
86         }
87         if (req != NULL)
88             ret = OCSP_REQUEST_verify(req, skey, signer->libctx, signer->propq);
89         else
90             ret = OCSP_BASICRESP_verify(bs, skey, signer->libctx, signer->propq);
91         if (ret <= 0)
92             ERR_raise(ERR_LIB_OCSP, OCSP_R_SIGNATURE_FAILURE);
93     }
94     return ret;
95 }
96 
97 /* Verify a basic response message */
OCSP_basic_verify(OCSP_BASICRESP * bs,STACK_OF (X509)* certs,X509_STORE * st,unsigned long flags)98 int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
99                       X509_STORE *st, unsigned long flags)
100 {
101     X509 *signer, *x;
102     STACK_OF(X509) *chain = NULL;
103     STACK_OF(X509) *untrusted = NULL;
104     int ret = ocsp_find_signer(&signer, bs, certs, flags);
105 
106     if (ret == 0) {
107         ERR_raise(ERR_LIB_OCSP, OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND);
108         goto end;
109     }
110     if ((ret == 2) && (flags & OCSP_TRUSTOTHER) != 0)
111         flags |= OCSP_NOVERIFY;
112 
113     if ((ret = ocsp_verify(NULL, bs, signer, flags)) <= 0)
114         goto end;
115     if ((flags & OCSP_NOVERIFY) == 0) {
116         ret = -1;
117         if ((flags & OCSP_NOCHAIN) == 0) {
118             if ((untrusted = sk_X509_dup(bs->certs)) == NULL)
119                 goto end;
120             if (!X509_add_certs(untrusted, certs, X509_ADD_FLAG_DEFAULT))
121                 goto end;
122         }
123         ret = ocsp_verify_signer(signer, 1, st, flags, untrusted, &chain);
124         if (ret <= 0)
125             goto end;
126         if ((flags & OCSP_NOCHECKS) != 0) {
127             ret = 1;
128             goto end;
129         }
130         /*
131          * At this point we have a valid certificate chain need to verify it
132          * against the OCSP issuer criteria.
133          */
134         ret = ocsp_check_issuer(bs, chain);
135 
136         /* If fatal error or valid match then finish */
137         if (ret != 0)
138             goto end;
139 
140         /*
141          * Easy case: explicitly trusted. Get root CA and check for explicit
142          * trust
143          */
144         if ((flags & OCSP_NOEXPLICIT) != 0)
145             goto end;
146 
147         x = sk_X509_value(chain, sk_X509_num(chain) - 1);
148         if (X509_check_trust(x, NID_OCSP_sign, 0) != X509_TRUST_TRUSTED) {
149             ERR_raise(ERR_LIB_OCSP, OCSP_R_ROOT_CA_NOT_TRUSTED);
150             ret = 0;
151             goto end;
152         }
153         ret = 1;
154     }
155 
156  end:
157     sk_X509_pop_free(chain, X509_free);
158     sk_X509_free(untrusted);
159     return ret;
160 }
161 
OCSP_resp_get0_signer(OCSP_BASICRESP * bs,X509 ** signer,STACK_OF (X509)* extra_certs)162 int OCSP_resp_get0_signer(OCSP_BASICRESP *bs, X509 **signer,
163                           STACK_OF(X509) *extra_certs)
164 {
165     return ocsp_find_signer(signer, bs, extra_certs, 0) > 0;
166 }
167 
ocsp_find_signer(X509 ** psigner,OCSP_BASICRESP * bs,STACK_OF (X509)* certs,unsigned long flags)168 static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs,
169                             STACK_OF(X509) *certs, unsigned long flags)
170 {
171     X509 *signer;
172     OCSP_RESPID *rid = &bs->tbsResponseData.responderId;
173 
174     if ((signer = ocsp_find_signer_sk(certs, rid)) != NULL) {
175         *psigner = signer;
176         return 2;
177     }
178     if ((flags & OCSP_NOINTERN) == 0 &&
179         (signer = ocsp_find_signer_sk(bs->certs, rid))) {
180         *psigner = signer;
181         return 1;
182     }
183     /* Maybe lookup from store if by subject name */
184 
185     *psigner = NULL;
186     return 0;
187 }
188 
ocsp_find_signer_sk(STACK_OF (X509)* certs,OCSP_RESPID * id)189 static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id)
190 {
191     int i, r;
192     unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash;
193     EVP_MD *md;
194     X509 *x;
195 
196     /* Easy if lookup by name */
197     if (id->type == V_OCSP_RESPID_NAME)
198         return X509_find_by_subject(certs, id->value.byName);
199 
200     /* Lookup by key hash */
201 
202     /* If key hash isn't SHA1 length then forget it */
203     if (id->value.byKey->length != SHA_DIGEST_LENGTH)
204         return NULL;
205     keyhash = id->value.byKey->data;
206     /* Calculate hash of each key and compare */
207     for (i = 0; i < sk_X509_num(certs); i++) {
208         if ((x = sk_X509_value(certs, i)) != NULL) {
209             if ((md = EVP_MD_fetch(x->libctx, SN_sha1, x->propq)) == NULL)
210                 break;
211             r = X509_pubkey_digest(x, md, tmphash, NULL);
212             EVP_MD_free(md);
213             if (!r)
214                 break;
215             if (memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH) == 0)
216                 return x;
217         }
218     }
219     return NULL;
220 }
221 
ocsp_check_issuer(OCSP_BASICRESP * bs,STACK_OF (X509)* chain)222 static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain)
223 {
224     STACK_OF(OCSP_SINGLERESP) *sresp = bs->tbsResponseData.responses;
225     X509 *signer, *sca;
226     OCSP_CERTID *caid = NULL;
227     int ret;
228 
229     if (sk_X509_num(chain) <= 0) {
230         ERR_raise(ERR_LIB_OCSP, OCSP_R_NO_CERTIFICATES_IN_CHAIN);
231         return -1;
232     }
233 
234     /* See if the issuer IDs match. */
235     ret = ocsp_check_ids(sresp, &caid);
236 
237     /* If ID mismatch or other error then return */
238     if (ret <= 0)
239         return ret;
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         ret = ocsp_match_issuerid(sca, caid, sresp);
246         if (ret < 0)
247             return ret;
248         if (ret != 0) {
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 
ocsp_check_ids(STACK_OF (OCSP_SINGLERESP)* sresp,OCSP_CERTID ** ret)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         ERR_raise(ERR_LIB_OCSP, OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA);
275         return -1;
276     }
277 
278     cid = sk_OCSP_SINGLERESP_value(sresp, 0)->certId;
279 
280     *ret = NULL;
281     for (i = 1; i < idcount; i++) {
282         tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId;
283         /* Check to see if IDs match */
284         if (OCSP_id_issuer_cmp(cid, tmpid)) {
285             /* If algorithm mismatch let caller deal with it */
286             if (OBJ_cmp(tmpid->hashAlgorithm.algorithm,
287                         cid->hashAlgorithm.algorithm))
288                 return 2;
289             /* Else mismatch */
290             return 0;
291         }
292     }
293 
294     /* All IDs match: only need to check one ID */
295     *ret = cid;
296     return 1;
297 }
298 
299 /*
300  * Match the certificate issuer ID.
301  * Returns -1 on fatal error, 0 if there is no match and 1 if there is a match.
302  */
ocsp_match_issuerid(X509 * cert,OCSP_CERTID * cid,STACK_OF (OCSP_SINGLERESP)* sresp)303 static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid,
304                                STACK_OF(OCSP_SINGLERESP) *sresp)
305 {
306     int ret = -1;
307     EVP_MD *dgst = NULL;
308 
309     /* If only one ID to match then do it */
310     if (cid != NULL) {
311         char name[OSSL_MAX_NAME_SIZE];
312         const X509_NAME *iname;
313         int mdlen;
314         unsigned char md[EVP_MAX_MD_SIZE];
315 
316         OBJ_obj2txt(name, sizeof(name), cid->hashAlgorithm.algorithm, 0);
317 
318         (void)ERR_set_mark();
319         dgst = EVP_MD_fetch(NULL, name, NULL);
320         if (dgst == NULL)
321             dgst = (EVP_MD *)EVP_get_digestbyname(name);
322 
323         if (dgst == NULL) {
324             (void)ERR_clear_last_mark();
325             ERR_raise(ERR_LIB_OCSP, OCSP_R_UNKNOWN_MESSAGE_DIGEST);
326             goto end;
327         }
328         (void)ERR_pop_to_mark();
329 
330         mdlen = EVP_MD_get_size(dgst);
331         if (mdlen < 0) {
332             ERR_raise(ERR_LIB_OCSP, OCSP_R_DIGEST_SIZE_ERR);
333             goto end;
334         }
335         if (cid->issuerNameHash.length != mdlen ||
336             cid->issuerKeyHash.length != mdlen) {
337             ret = 0;
338             goto end;
339         }
340         iname = X509_get_subject_name(cert);
341         if (!X509_NAME_digest(iname, dgst, md, NULL))
342             goto end;
343         if (memcmp(md, cid->issuerNameHash.data, mdlen) != 0) {
344             ret = 0;
345             goto end;
346         }
347         if (!X509_pubkey_digest(cert, dgst, md, NULL)) {
348             ERR_raise(ERR_LIB_OCSP, OCSP_R_DIGEST_ERR);
349             goto end;
350         }
351         ret = memcmp(md, cid->issuerKeyHash.data, mdlen) == 0;
352         goto end;
353     } else {
354         /* We have to match the whole lot */
355         int i;
356         OCSP_CERTID *tmpid;
357 
358         for (i = 0; i < sk_OCSP_SINGLERESP_num(sresp); i++) {
359             tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId;
360             ret = ocsp_match_issuerid(cert, tmpid, NULL);
361             if (ret <= 0)
362                 return ret;
363         }
364     }
365     return 1;
366 end:
367     EVP_MD_free(dgst);
368     return ret;
369 }
370 
ocsp_check_delegated(X509 * x)371 static int ocsp_check_delegated(X509 *x)
372 {
373     if ((X509_get_extension_flags(x) & EXFLAG_XKUSAGE)
374         && (X509_get_extended_key_usage(x) & XKU_OCSP_SIGN))
375         return 1;
376     ERR_raise(ERR_LIB_OCSP, OCSP_R_MISSING_OCSPSIGNING_USAGE);
377     return 0;
378 }
379 
380 /*
381  * Verify an OCSP request. This is much easier than OCSP response verify.
382  * Just find the signer's certificate and verify it against a given trust value.
383  * Returns 1 on success, 0 on failure and on fatal error.
384  */
OCSP_request_verify(OCSP_REQUEST * req,STACK_OF (X509)* certs,X509_STORE * store,unsigned long flags)385 int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs,
386                         X509_STORE *store, unsigned long flags)
387 {
388     X509 *signer;
389     const X509_NAME *nm;
390     GENERAL_NAME *gen;
391     int ret;
392 
393     if (!req->optionalSignature) {
394         ERR_raise(ERR_LIB_OCSP, OCSP_R_REQUEST_NOT_SIGNED);
395         return 0;
396     }
397     gen = req->tbsRequest.requestorName;
398     if (!gen || gen->type != GEN_DIRNAME) {
399         ERR_raise(ERR_LIB_OCSP, OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE);
400         return 0; /* not returning -1 here for backward compatibility*/
401     }
402     nm = gen->d.directoryName;
403     ret = ocsp_req_find_signer(&signer, req, nm, certs, flags);
404     if (ret <= 0) {
405         ERR_raise(ERR_LIB_OCSP, OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND);
406         return 0; /* not returning -1 here for backward compatibility*/
407     }
408     if ((ret == 2) && (flags & OCSP_TRUSTOTHER) != 0)
409         flags |= OCSP_NOVERIFY;
410 
411     if ((ret = ocsp_verify(req, NULL, signer, flags)) <= 0)
412         return 0; /* not returning 'ret' here for backward compatibility*/
413     if ((flags & OCSP_NOVERIFY) != 0)
414         return 1;
415     return ocsp_verify_signer(signer, 0, store, flags,
416                               (flags & OCSP_NOCHAIN) != 0 ?
417                               NULL : req->optionalSignature->certs, NULL) > 0;
418     /* using '> 0' here to avoid breaking backward compatibility returning -1 */
419 }
420 
ocsp_req_find_signer(X509 ** psigner,OCSP_REQUEST * req,const X509_NAME * nm,STACK_OF (X509)* certs,unsigned long flags)421 static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req,
422                                 const X509_NAME *nm, STACK_OF(X509) *certs,
423                                 unsigned long flags)
424 {
425     X509 *signer;
426 
427     if ((flags & OCSP_NOINTERN) == 0) {
428         signer = X509_find_by_subject(req->optionalSignature->certs, nm);
429         if (signer != NULL) {
430             *psigner = signer;
431             return 1;
432         }
433     }
434 
435     if ((signer = X509_find_by_subject(certs, nm)) != NULL) {
436         *psigner = signer;
437         return 2;
438     }
439     return 0;
440 }
441