]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/ocsp/ocsp_vfy.c
Stop raising ERR_R_MALLOC_FAILURE in most places
[thirdparty/openssl.git] / crypto / ocsp / ocsp_vfy.c
CommitLineData
0f113f3e 1/*
fecb3aae 2 * Copyright 2001-2022 The OpenSSL Project Authors. All Rights Reserved.
9b4dc830 3 *
0c496700 4 * Licensed under the Apache License 2.0 (the "License"). You may not use
b1322259
RS
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
9b4dc830
DSH
8 */
9
eaf8a40d 10#include <string.h>
9b4dc830
DSH
11#include <openssl/ocsp.h>
12#include <openssl/err.h>
eaf8a40d
TM
13#include "internal/sizes.h"
14#include "ocsp_local.h"
9b4dc830 15
0f113f3e 16static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs,
a773b52a 17 STACK_OF(X509) *certs, unsigned long flags);
9b4dc830 18static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id);
a773b52a 19static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain);
0f113f3e
MC
20static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp,
21 OCSP_CERTID **ret);
22static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid,
23 STACK_OF(OCSP_SINGLERESP) *sresp);
a773b52a 24static int ocsp_check_delegated(X509 *x);
0f113f3e 25static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req,
8cc86b81 26 const X509_NAME *nm, STACK_OF(X509) *certs,
a773b52a 27 unsigned long flags);
9b4dc830 28
4a71bee6 29/* Returns 1 on success, 0 on failure, or -1 on fatal error */
4ff993d7
DDO
30static int ocsp_verify_signer(X509 *signer, int response,
31 X509_STORE *st, unsigned long flags,
4a71bee6
DDO
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;
9b4dc830 37
4a71bee6 38 if (ctx == NULL) {
e077455e 39 ERR_raise(ERR_LIB_OCSP, ERR_R_X509_LIB);
4a71bee6
DDO
40 goto end;
41 }
42 if (!X509_STORE_CTX_init(ctx, st, signer, untrusted)) {
9311d0c4 43 ERR_raise(ERR_LIB_OCSP, ERR_R_X509_LIB);
4a71bee6
DDO
44 goto end;
45 }
4ff993d7
DDO
46 if ((vp = X509_STORE_CTX_get0_param(ctx)) == NULL)
47 goto end;
48 if ((flags & OCSP_PARTIAL_CHAIN) != 0)
4a71bee6 49 X509_VERIFY_PARAM_set_flags(vp, X509_V_FLAG_PARTIAL_CHAIN);
4ff993d7
DDO
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.
126e3771 54 * Done here for CRLs; should be done also for OCSP-based checks.
4ff993d7
DDO
55 */
56 X509_VERIFY_PARAM_clear_flags(vp, X509_V_FLAG_CRL_CHECK);
4a71bee6
DDO
57 X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_OCSP_HELPER);
58 X509_STORE_CTX_set_trust(ctx, X509_TRUST_OCSP_REQUEST);
4a71bee6
DDO
59
60 ret = X509_verify_cert(ctx);
61 if (ret <= 0) {
21f89f54
MC
62 int err = X509_STORE_CTX_get_error(ctx);
63
a150f8e1 64 ERR_raise_data(ERR_LIB_OCSP, OCSP_R_CERTIFICATE_VERIFY_ERROR,
21f89f54 65 "Verify error: %s", X509_verify_cert_error_string(err));
4a71bee6
DDO
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
76static 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) {
9311d0c4 84 ERR_raise(ERR_LIB_OCSP, OCSP_R_NO_SIGNER_KEY);
4a71bee6
DDO
85 return -1;
86 }
87 if (req != NULL)
e6c2f964 88 ret = OCSP_REQUEST_verify(req, skey, signer->libctx, signer->propq);
4a71bee6 89 else
e6c2f964 90 ret = OCSP_BASICRESP_verify(bs, skey, signer->libctx, signer->propq);
4a71bee6 91 if (ret <= 0)
9311d0c4 92 ERR_raise(ERR_LIB_OCSP, OCSP_R_SIGNATURE_FAILURE);
4a71bee6
DDO
93 }
94 return ret;
95}
96
97/* Verify a basic response message */
9b4dc830 98int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
0f113f3e
MC
99 X509_STORE *st, unsigned long flags)
100{
101 X509 *signer, *x;
102 STACK_OF(X509) *chain = NULL;
4ca5efc2 103 STACK_OF(X509) *untrusted = NULL;
4a71bee6 104 int ret = ocsp_find_signer(&signer, bs, certs, flags);
a773b52a 105
4a71bee6 106 if (ret == 0) {
9311d0c4 107 ERR_raise(ERR_LIB_OCSP, OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND);
d32f5d87 108 goto end;
f0e0fd51 109 }
4a71bee6 110 if ((ret == 2) && (flags & OCSP_TRUSTOTHER) != 0)
0f113f3e 111 flags |= OCSP_NOVERIFY;
eeccc237 112
4a71bee6
DDO
113 if ((ret = ocsp_verify(NULL, bs, signer, flags)) <= 0)
114 goto end;
115 if ((flags & OCSP_NOVERIFY) == 0) {
116 ret = -1;
d53b437f
DDO
117 if ((flags & OCSP_NOCHAIN) == 0) {
118 if ((untrusted = sk_X509_dup(bs->certs)) == NULL)
119 goto end;
eeccc237 120 if (!X509_add_certs(untrusted, certs, X509_ADD_FLAG_DEFAULT))
4a71bee6 121 goto end;
4ca5efc2 122 }
4ff993d7 123 ret = ocsp_verify_signer(signer, 1, st, flags, untrusted, &chain);
4a71bee6 124 if (ret <= 0)
d32f5d87 125 goto end;
4a71bee6 126 if ((flags & OCSP_NOCHECKS) != 0) {
0f113f3e
MC
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 */
a773b52a 134 ret = ocsp_check_issuer(bs, chain);
0f113f3e
MC
135
136 /* If fatal error or valid match then finish */
137 if (ret != 0)
64a1385a 138 goto end;
0f113f3e
MC
139
140 /*
141 * Easy case: explicitly trusted. Get root CA and check for explicit
142 * trust
143 */
4a71bee6 144 if ((flags & OCSP_NOEXPLICIT) != 0)
0f113f3e
MC
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) {
9311d0c4 149 ERR_raise(ERR_LIB_OCSP, OCSP_R_ROOT_CA_NOT_TRUSTED);
4a71bee6
DDO
150 ret = 0;
151 goto end;
0f113f3e
MC
152 }
153 ret = 1;
154 }
4a71bee6 155
0f113f3e 156 end:
79b2a2f2 157 OSSL_STACK_OF_X509_free(chain);
d53b437f 158 sk_X509_free(untrusted);
0f113f3e
MC
159 return ret;
160}
161
ce5886dd 162int OCSP_resp_get0_signer(OCSP_BASICRESP *bs, X509 **signer,
eb48052e 163 STACK_OF(X509) *extra_certs)
ce5886dd 164{
4a71bee6 165 return ocsp_find_signer(signer, bs, extra_certs, 0) > 0;
ce5886dd
BK
166}
167
0f113f3e 168static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs,
a773b52a 169 STACK_OF(X509) *certs, unsigned long flags)
0f113f3e
MC
170{
171 X509 *signer;
a332635e 172 OCSP_RESPID *rid = &bs->tbsResponseData.responderId;
c51a8af8 173
4a71bee6 174 if ((signer = ocsp_find_signer_sk(certs, rid)) != NULL) {
0f113f3e
MC
175 *psigner = signer;
176 return 2;
177 }
4a71bee6 178 if ((flags & OCSP_NOINTERN) == 0 &&
0f113f3e
MC
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}
9b4dc830
DSH
188
189static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id)
0f113f3e 190{
e27fea46 191 int i, r;
0f113f3e 192 unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash;
e27fea46 193 EVP_MD *md;
0f113f3e
MC
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++) {
e27fea46
P
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 }
0f113f3e
MC
218 }
219 return NULL;
220}
221
a773b52a 222static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain)
0f113f3e 223{
4a71bee6 224 STACK_OF(OCSP_SINGLERESP) *sresp = bs->tbsResponseData.responses;
0f113f3e
MC
225 X509 *signer, *sca;
226 OCSP_CERTID *caid = NULL;
4a71bee6 227 int ret;
0f113f3e
MC
228
229 if (sk_X509_num(chain) <= 0) {
9311d0c4 230 ERR_raise(ERR_LIB_OCSP, OCSP_R_NO_CERTIFICATES_IN_CHAIN);
0f113f3e
MC
231 return -1;
232 }
233
234 /* See if the issuer IDs match. */
4a71bee6 235 ret = ocsp_check_ids(sresp, &caid);
0f113f3e
MC
236
237 /* If ID mismatch or other error then return */
4a71bee6
DDO
238 if (ret <= 0)
239 return ret;
0f113f3e
MC
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);
4a71bee6
DDO
245 ret = ocsp_match_issuerid(sca, caid, sresp);
246 if (ret < 0)
247 return ret;
248 if (ret != 0) {
0f113f3e 249 /* We have a match, if extensions OK then success */
a773b52a 250 if (ocsp_check_delegated(signer))
0f113f3e
MC
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.
e8af92fc 265 */
0f113f3e 266
e8af92fc 267static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret)
0f113f3e
MC
268{
269 OCSP_CERTID *tmpid, *cid;
270 int i, idcount;
271
272 idcount = sk_OCSP_SINGLERESP_num(sresp);
273 if (idcount <= 0) {
9311d0c4 274 ERR_raise(ERR_LIB_OCSP, OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA);
0f113f3e
MC
275 return -1;
276 }
277
278 cid = sk_OCSP_SINGLERESP_value(sresp, 0)->certId;
279
280 *ret = NULL;
0f113f3e
MC
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)) {
0d4fb843 285 /* If algorithm mismatch let caller deal with it */
a332635e
DSH
286 if (OBJ_cmp(tmpid->hashAlgorithm.algorithm,
287 cid->hashAlgorithm.algorithm))
0f113f3e
MC
288 return 2;
289 /* Else mismatch */
290 return 0;
291 }
292 }
e8af92fc 293
0f113f3e
MC
294 /* All IDs match: only need to check one ID */
295 *ret = cid;
296 return 1;
297}
e8af92fc 298
c51a8af8
P
299/*
300 * Match the certificate issuer ID.
4a71bee6 301 * Returns -1 on fatal error, 0 if there is no match and 1 if there is a match.
c51a8af8 302 */
e8af92fc 303static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid,
0f113f3e
MC
304 STACK_OF(OCSP_SINGLERESP) *sresp)
305{
eaf8a40d
TM
306 int ret = -1;
307 EVP_MD *dgst = NULL;
308
0f113f3e 309 /* If only one ID to match then do it */
c51a8af8 310 if (cid != NULL) {
eaf8a40d 311 char name[OSSL_MAX_NAME_SIZE];
8cc86b81 312 const X509_NAME *iname;
0f113f3e
MC
313 int mdlen;
314 unsigned char md[EVP_MAX_MD_SIZE];
c51a8af8 315
eaf8a40d
TM
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
c51a8af8 323 if (dgst == NULL) {
eaf8a40d 324 (void)ERR_clear_last_mark();
9311d0c4 325 ERR_raise(ERR_LIB_OCSP, OCSP_R_UNKNOWN_MESSAGE_DIGEST);
eaf8a40d 326 goto end;
0f113f3e 327 }
eaf8a40d 328 (void)ERR_pop_to_mark();
0f113f3e 329
ed576acd 330 mdlen = EVP_MD_get_size(dgst);
c51a8af8 331 if (mdlen < 0) {
9311d0c4 332 ERR_raise(ERR_LIB_OCSP, OCSP_R_DIGEST_SIZE_ERR);
eaf8a40d 333 goto end;
c51a8af8
P
334 }
335 if (cid->issuerNameHash.length != mdlen ||
eaf8a40d
TM
336 cid->issuerKeyHash.length != mdlen) {
337 ret = 0;
338 goto end;
339 }
0f113f3e 340 iname = X509_get_subject_name(cert);
eaf8a40d
TM
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;
c51a8af8 346 }
c51a8af8 347 if (!X509_pubkey_digest(cert, dgst, md, NULL)) {
9311d0c4 348 ERR_raise(ERR_LIB_OCSP, OCSP_R_DIGEST_ERR);
eaf8a40d 349 goto end;
c51a8af8 350 }
eaf8a40d
TM
351 ret = memcmp(md, cid->issuerKeyHash.data, mdlen) == 0;
352 goto end;
0f113f3e
MC
353 } else {
354 /* We have to match the whole lot */
eaf8a40d 355 int i;
0f113f3e 356 OCSP_CERTID *tmpid;
c51a8af8 357
0f113f3e
MC
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 }
0f113f3e 364 }
c51a8af8 365 return 1;
eaf8a40d
TM
366end:
367 EVP_MD_free(dgst);
368 return ret;
0f113f3e 369}
e8af92fc 370
a773b52a 371static int ocsp_check_delegated(X509 *x)
0f113f3e 372{
a8d8e06b
DSH
373 if ((X509_get_extension_flags(x) & EXFLAG_XKUSAGE)
374 && (X509_get_extended_key_usage(x) & XKU_OCSP_SIGN))
0f113f3e 375 return 1;
9311d0c4 376 ERR_raise(ERR_LIB_OCSP, OCSP_R_MISSING_OCSPSIGNING_USAGE);
0f113f3e
MC
377 return 0;
378}
379
380/*
4a71bee6
DDO
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.
fafc7f98 384 */
0f113f3e
MC
385int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs,
386 X509_STORE *store, unsigned long flags)
387{
388 X509 *signer;
8cc86b81 389 const X509_NAME *nm;
0f113f3e 390 GENERAL_NAME *gen;
4a71bee6 391 int ret;
f0e0fd51 392
0f113f3e 393 if (!req->optionalSignature) {
9311d0c4 394 ERR_raise(ERR_LIB_OCSP, OCSP_R_REQUEST_NOT_SIGNED);
4a71bee6 395 return 0;
0f113f3e 396 }
a332635e 397 gen = req->tbsRequest.requestorName;
0f113f3e 398 if (!gen || gen->type != GEN_DIRNAME) {
9311d0c4 399 ERR_raise(ERR_LIB_OCSP, OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE);
4a71bee6 400 return 0; /* not returning -1 here for backward compatibility*/
0f113f3e
MC
401 }
402 nm = gen->d.directoryName;
a773b52a 403 ret = ocsp_req_find_signer(&signer, req, nm, certs, flags);
0f113f3e 404 if (ret <= 0) {
9311d0c4 405 ERR_raise(ERR_LIB_OCSP, OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND);
4a71bee6 406 return 0; /* not returning -1 here for backward compatibility*/
0f113f3e 407 }
4a71bee6 408 if ((ret == 2) && (flags & OCSP_TRUSTOTHER) != 0)
0f113f3e 409 flags |= OCSP_NOVERIFY;
f0e0fd51 410
4a71bee6
DDO
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;
4ff993d7 415 return ocsp_verify_signer(signer, 0, store, flags,
4a71bee6
DDO
416 (flags & OCSP_NOCHAIN) != 0 ?
417 NULL : req->optionalSignature->certs, NULL) > 0;
418 /* using '> 0' here to avoid breaking backward compatibility returning -1 */
0f113f3e
MC
419}
420
421static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req,
8cc86b81 422 const X509_NAME *nm, STACK_OF(X509) *certs,
a773b52a 423 unsigned long flags)
0f113f3e
MC
424{
425 X509 *signer;
c51a8af8 426
4a71bee6 427 if ((flags & OCSP_NOINTERN) == 0) {
0f113f3e 428 signer = X509_find_by_subject(req->optionalSignature->certs, nm);
4a71bee6 429 if (signer != NULL) {
0f113f3e
MC
430 *psigner = signer;
431 return 1;
432 }
433 }
434
4a71bee6 435 if ((signer = X509_find_by_subject(certs, nm)) != NULL) {
0f113f3e
MC
436 *psigner = signer;
437 return 2;
438 }
439 return 0;
440}