diff options
| author | tb <> | 2026-04-07 13:02:50 +0000 |
|---|---|---|
| committer | tb <> | 2026-04-07 13:02:50 +0000 |
| commit | bd035cb5927e4f4359c2ecd94226a2536b0d7773 (patch) | |
| tree | 112a70f4aa92e2228bb940152df65d0a830a31c4 /src/lib | |
| parent | c8f25bd7366a35c48b23230ab0da4f3484424ba2 (diff) | |
| download | openbsd-bd035cb5927e4f4359c2ecd94226a2536b0d7773.tar.gz openbsd-bd035cb5927e4f4359c2ecd94226a2536b0d7773.tar.bz2 openbsd-bd035cb5927e4f4359c2ecd94226a2536b0d7773.zip | |
Refactor and fix ocsp_find_signer_sk()
Instead of reaching deep inside the OCSP_BASICRESP and ignoring its
semantics and then try to untangle things in ocsp_find_signer_sk(),
pass the OCSP_BASICRESP and use OCSP_resp_get0_id() which has the
logic built in. Avoids a crash if you call OCSP_basic_verify() after
OCSP_BASICRESP_new() without OCSP_basic_sign(). This cannot happen on
a deserialized OCSP object.
Prompted by a report by Kamil Frankowicz, Jan Kaminski, Bartosz Michalowski.
ok jsing
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/libcrypto/ocsp/ocsp_vfy.c | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/src/lib/libcrypto/ocsp/ocsp_vfy.c b/src/lib/libcrypto/ocsp/ocsp_vfy.c index 185839f465..f8818fd48d 100644 --- a/src/lib/libcrypto/ocsp/ocsp_vfy.c +++ b/src/lib/libcrypto/ocsp/ocsp_vfy.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ocsp_vfy.c,v 1.25 2025/05/10 05:54:38 tb Exp $ */ | 1 | /* $OpenBSD: ocsp_vfy.c,v 1.26 2026/04/07 13:02:50 tb Exp $ */ |
| 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
| 3 | * project 2000. | 3 | * project 2000. |
| 4 | */ | 4 | */ |
| @@ -65,7 +65,7 @@ | |||
| 65 | 65 | ||
| 66 | static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, | 66 | static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, |
| 67 | STACK_OF(X509) *certs, X509_STORE *st, unsigned long flags); | 67 | STACK_OF(X509) *certs, X509_STORE *st, unsigned long flags); |
| 68 | static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id); | 68 | static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, const OCSP_BASICRESP *id); |
| 69 | static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain, | 69 | static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain, |
| 70 | unsigned long flags); | 70 | unsigned long flags); |
| 71 | static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret); | 71 | static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret); |
| @@ -198,14 +198,13 @@ ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs, | |||
| 198 | X509_STORE *st, unsigned long flags) | 198 | X509_STORE *st, unsigned long flags) |
| 199 | { | 199 | { |
| 200 | X509 *signer; | 200 | X509 *signer; |
| 201 | OCSP_RESPID *rid = bs->tbsResponseData->responderId; | ||
| 202 | 201 | ||
| 203 | if ((signer = ocsp_find_signer_sk(certs, rid))) { | 202 | if ((signer = ocsp_find_signer_sk(certs, bs))) { |
| 204 | *psigner = signer; | 203 | *psigner = signer; |
| 205 | return 2; | 204 | return 2; |
| 206 | } | 205 | } |
| 207 | if (!(flags & OCSP_NOINTERN) && | 206 | if (!(flags & OCSP_NOINTERN) && |
| 208 | (signer = ocsp_find_signer_sk(bs->certs, rid))) { | 207 | (signer = ocsp_find_signer_sk(bs->certs, bs))) { |
| 209 | *psigner = signer; | 208 | *psigner = signer; |
| 210 | return 1; | 209 | return 1; |
| 211 | } | 210 | } |
| @@ -216,22 +215,28 @@ ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs, | |||
| 216 | } | 215 | } |
| 217 | 216 | ||
| 218 | static X509 * | 217 | static X509 * |
| 219 | ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id) | 218 | ocsp_find_signer_sk(STACK_OF(X509) *certs, const OCSP_BASICRESP *bs) |
| 220 | { | 219 | { |
| 221 | int i; | 220 | const ASN1_OCTET_STRING *byKey = NULL; |
| 222 | unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash; | 221 | const X509_NAME *byName = NULL; |
| 222 | const unsigned char *keyhash; | ||
| 223 | unsigned char tmphash[SHA_DIGEST_LENGTH]; | ||
| 223 | X509 *x; | 224 | X509 *x; |
| 225 | int i; | ||
| 226 | |||
| 227 | if (!OCSP_resp_get0_id(bs, &byKey, &byName)) | ||
| 228 | return NULL; | ||
| 224 | 229 | ||
| 225 | /* Easy if lookup by name */ | 230 | /* Easy if lookup by name */ |
| 226 | if (id->type == V_OCSP_RESPID_NAME) | 231 | if (byName != NULL) |
| 227 | return X509_find_by_subject(certs, id->value.byName); | 232 | return X509_find_by_subject(certs, (X509_NAME *)byName); |
| 228 | 233 | ||
| 229 | /* Lookup by key hash */ | 234 | /* Lookup by key hash */ |
| 230 | 235 | ||
| 231 | /* If key hash isn't SHA1 length then forget it */ | 236 | /* If key hash isn't SHA1 length then forget it */ |
| 232 | if (id->value.byKey->length != SHA_DIGEST_LENGTH) | 237 | if (ASN1_STRING_length(byKey) != SHA_DIGEST_LENGTH) |
| 233 | return NULL; | 238 | return NULL; |
| 234 | keyhash = id->value.byKey->data; | 239 | keyhash = ASN1_STRING_get0_data(byKey); |
| 235 | /* Calculate hash of each key and compare */ | 240 | /* Calculate hash of each key and compare */ |
| 236 | for (i = 0; i < sk_X509_num(certs); i++) { | 241 | for (i = 0; i < sk_X509_num(certs); i++) { |
| 237 | x = sk_X509_value(certs, i); | 242 | x = sk_X509_value(certs, i); |
