2 * Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the OpenSSL license (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
10 #include <openssl/ocsp.h>
12 #include <openssl/err.h>
15 static int ocsp_find_signer(X509
**psigner
, OCSP_BASICRESP
*bs
,
16 STACK_OF(X509
) *certs
, unsigned long flags
);
17 static X509
*ocsp_find_signer_sk(STACK_OF(X509
) *certs
, OCSP_RESPID
*id
);
18 static int ocsp_check_issuer(OCSP_BASICRESP
*bs
, STACK_OF(X509
) *chain
);
19 static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP
) *sresp
,
21 static int ocsp_match_issuerid(X509
*cert
, OCSP_CERTID
*cid
,
22 STACK_OF(OCSP_SINGLERESP
) *sresp
);
23 static int ocsp_check_delegated(X509
*x
);
24 static int ocsp_req_find_signer(X509
**psigner
, OCSP_REQUEST
*req
,
25 X509_NAME
*nm
, STACK_OF(X509
) *certs
,
28 /* Verify a basic response message */
30 int OCSP_basic_verify(OCSP_BASICRESP
*bs
, STACK_OF(X509
) *certs
,
31 X509_STORE
*st
, unsigned long flags
)
34 STACK_OF(X509
) *chain
= NULL
;
35 STACK_OF(X509
) *untrusted
= NULL
;
36 X509_STORE_CTX
*ctx
= NULL
;
37 int i
, ret
= ocsp_find_signer(&signer
, bs
, certs
, flags
);
40 OCSPerr(OCSP_F_OCSP_BASIC_VERIFY
,
41 OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND
);
44 ctx
= X509_STORE_CTX_new();
46 OCSPerr(OCSP_F_OCSP_BASIC_VERIFY
, ERR_R_MALLOC_FAILURE
);
49 if ((ret
== 2) && (flags
& OCSP_TRUSTOTHER
))
50 flags
|= OCSP_NOVERIFY
;
51 if (!(flags
& OCSP_NOSIGS
)) {
53 skey
= X509_get0_pubkey(signer
);
55 OCSPerr(OCSP_F_OCSP_BASIC_VERIFY
, OCSP_R_NO_SIGNER_KEY
);
58 ret
= OCSP_BASICRESP_verify(bs
, skey
, 0);
60 OCSPerr(OCSP_F_OCSP_BASIC_VERIFY
, OCSP_R_SIGNATURE_FAILURE
);
64 if (!(flags
& OCSP_NOVERIFY
)) {
66 if (flags
& OCSP_NOCHAIN
) {
68 } else if (bs
->certs
&& certs
) {
69 untrusted
= sk_X509_dup(bs
->certs
);
70 for (i
= 0; i
< sk_X509_num(certs
); i
++) {
71 if (!sk_X509_push(untrusted
, sk_X509_value(certs
, i
))) {
72 OCSPerr(OCSP_F_OCSP_BASIC_VERIFY
, ERR_R_MALLOC_FAILURE
);
76 } else if (certs
!= NULL
) {
79 untrusted
= bs
->certs
;
81 init_res
= X509_STORE_CTX_init(ctx
, st
, signer
, untrusted
);
83 OCSPerr(OCSP_F_OCSP_BASIC_VERIFY
, ERR_R_X509_LIB
);
87 X509_STORE_CTX_set_purpose(ctx
, X509_PURPOSE_OCSP_HELPER
);
88 ret
= X509_verify_cert(ctx
);
89 chain
= X509_STORE_CTX_get1_chain(ctx
);
91 i
= X509_STORE_CTX_get_error(ctx
);
92 OCSPerr(OCSP_F_OCSP_BASIC_VERIFY
,
93 OCSP_R_CERTIFICATE_VERIFY_ERROR
);
94 ERR_add_error_data(2, "Verify error:",
95 X509_verify_cert_error_string(i
));
98 if (flags
& OCSP_NOCHECKS
) {
103 * At this point we have a valid certificate chain need to verify it
104 * against the OCSP issuer criteria.
106 ret
= ocsp_check_issuer(bs
, chain
);
108 /* If fatal error or valid match then finish */
113 * Easy case: explicitly trusted. Get root CA and check for explicit
116 if (flags
& OCSP_NOEXPLICIT
)
119 x
= sk_X509_value(chain
, sk_X509_num(chain
) - 1);
120 if (X509_check_trust(x
, NID_OCSP_sign
, 0) != X509_TRUST_TRUSTED
) {
121 OCSPerr(OCSP_F_OCSP_BASIC_VERIFY
, OCSP_R_ROOT_CA_NOT_TRUSTED
);
127 X509_STORE_CTX_free(ctx
);
128 sk_X509_pop_free(chain
, X509_free
);
129 if (bs
->certs
&& certs
)
130 sk_X509_free(untrusted
);
141 int OCSP_resp_get0_signer(OCSP_BASICRESP
*bs
, X509
**signer
,
142 STACK_OF(X509
) *extra_certs
)
146 ret
= ocsp_find_signer(signer
, bs
, extra_certs
, 0);
147 return (ret
> 0) ? 1 : 0;
150 static int ocsp_find_signer(X509
**psigner
, OCSP_BASICRESP
*bs
,
151 STACK_OF(X509
) *certs
, unsigned long flags
)
154 OCSP_RESPID
*rid
= &bs
->tbsResponseData
.responderId
;
155 if ((signer
= ocsp_find_signer_sk(certs
, rid
))) {
159 if (!(flags
& OCSP_NOINTERN
) &&
160 (signer
= ocsp_find_signer_sk(bs
->certs
, rid
))) {
164 /* Maybe lookup from store if by subject name */
170 static X509
*ocsp_find_signer_sk(STACK_OF(X509
) *certs
, OCSP_RESPID
*id
)
173 unsigned char tmphash
[SHA_DIGEST_LENGTH
], *keyhash
;
176 /* Easy if lookup by name */
177 if (id
->type
== V_OCSP_RESPID_NAME
)
178 return X509_find_by_subject(certs
, id
->value
.byName
);
180 /* Lookup by key hash */
182 /* If key hash isn't SHA1 length then forget it */
183 if (id
->value
.byKey
->length
!= SHA_DIGEST_LENGTH
)
185 keyhash
= id
->value
.byKey
->data
;
186 /* Calculate hash of each key and compare */
187 for (i
= 0; i
< sk_X509_num(certs
); i
++) {
188 x
= sk_X509_value(certs
, i
);
189 X509_pubkey_digest(x
, EVP_sha1(), tmphash
, NULL
);
190 if (!memcmp(keyhash
, tmphash
, SHA_DIGEST_LENGTH
))
196 static int ocsp_check_issuer(OCSP_BASICRESP
*bs
, STACK_OF(X509
) *chain
)
198 STACK_OF(OCSP_SINGLERESP
) *sresp
;
200 OCSP_CERTID
*caid
= NULL
;
202 sresp
= bs
->tbsResponseData
.responses
;
204 if (sk_X509_num(chain
) <= 0) {
205 OCSPerr(OCSP_F_OCSP_CHECK_ISSUER
, OCSP_R_NO_CERTIFICATES_IN_CHAIN
);
209 /* See if the issuer IDs match. */
210 i
= ocsp_check_ids(sresp
, &caid
);
212 /* If ID mismatch or other error then return */
216 signer
= sk_X509_value(chain
, 0);
217 /* Check to see if OCSP responder CA matches request CA */
218 if (sk_X509_num(chain
) > 1) {
219 sca
= sk_X509_value(chain
, 1);
220 i
= ocsp_match_issuerid(sca
, caid
, sresp
);
224 /* We have a match, if extensions OK then success */
225 if (ocsp_check_delegated(signer
))
231 /* Otherwise check if OCSP request signed directly by request CA */
232 return ocsp_match_issuerid(signer
, caid
, sresp
);
236 * Check the issuer certificate IDs for equality. If there is a mismatch with
237 * the same algorithm then there's no point trying to match any certificates
238 * against the issuer. If the issuer IDs all match then we just need to check
239 * equality against one of them.
242 static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP
) *sresp
, OCSP_CERTID
**ret
)
244 OCSP_CERTID
*tmpid
, *cid
;
247 idcount
= sk_OCSP_SINGLERESP_num(sresp
);
249 OCSPerr(OCSP_F_OCSP_CHECK_IDS
,
250 OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA
);
254 cid
= sk_OCSP_SINGLERESP_value(sresp
, 0)->certId
;
258 for (i
= 1; i
< idcount
; i
++) {
259 tmpid
= sk_OCSP_SINGLERESP_value(sresp
, i
)->certId
;
260 /* Check to see if IDs match */
261 if (OCSP_id_issuer_cmp(cid
, tmpid
)) {
262 /* If algorithm mismatch let caller deal with it */
263 if (OBJ_cmp(tmpid
->hashAlgorithm
.algorithm
,
264 cid
->hashAlgorithm
.algorithm
))
271 /* All IDs match: only need to check one ID */
276 static int ocsp_match_issuerid(X509
*cert
, OCSP_CERTID
*cid
,
277 STACK_OF(OCSP_SINGLERESP
) *sresp
)
279 /* If only one ID to match then do it */
284 unsigned char md
[EVP_MAX_MD_SIZE
];
285 if ((dgst
= EVP_get_digestbyobj(cid
->hashAlgorithm
.algorithm
))
287 OCSPerr(OCSP_F_OCSP_MATCH_ISSUERID
,
288 OCSP_R_UNKNOWN_MESSAGE_DIGEST
);
292 mdlen
= EVP_MD_size(dgst
);
295 if ((cid
->issuerNameHash
.length
!= mdlen
) ||
296 (cid
->issuerKeyHash
.length
!= mdlen
))
298 iname
= X509_get_subject_name(cert
);
299 if (!X509_NAME_digest(iname
, dgst
, md
, NULL
))
301 if (memcmp(md
, cid
->issuerNameHash
.data
, mdlen
))
303 X509_pubkey_digest(cert
, dgst
, md
, NULL
);
304 if (memcmp(md
, cid
->issuerKeyHash
.data
, mdlen
))
310 /* We have to match the whole lot */
313 for (i
= 0; i
< sk_OCSP_SINGLERESP_num(sresp
); i
++) {
314 tmpid
= sk_OCSP_SINGLERESP_value(sresp
, i
)->certId
;
315 ret
= ocsp_match_issuerid(cert
, tmpid
, NULL
);
324 static int ocsp_check_delegated(X509
*x
)
326 if ((X509_get_extension_flags(x
) & EXFLAG_XKUSAGE
)
327 && (X509_get_extended_key_usage(x
) & XKU_OCSP_SIGN
))
329 OCSPerr(OCSP_F_OCSP_CHECK_DELEGATED
, OCSP_R_MISSING_OCSPSIGNING_USAGE
);
334 * Verify an OCSP request. This is fortunately much easier than OCSP response
335 * verify. Just find the signers certificate and verify it against a given
339 int OCSP_request_verify(OCSP_REQUEST
*req
, STACK_OF(X509
) *certs
,
340 X509_STORE
*store
, unsigned long flags
)
346 X509_STORE_CTX
*ctx
= X509_STORE_CTX_new();
349 OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY
, ERR_R_MALLOC_FAILURE
);
353 if (!req
->optionalSignature
) {
354 OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY
, OCSP_R_REQUEST_NOT_SIGNED
);
357 gen
= req
->tbsRequest
.requestorName
;
358 if (!gen
|| gen
->type
!= GEN_DIRNAME
) {
359 OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY
,
360 OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE
);
363 nm
= gen
->d
.directoryName
;
364 ret
= ocsp_req_find_signer(&signer
, req
, nm
, certs
, flags
);
366 OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY
,
367 OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND
);
370 if ((ret
== 2) && (flags
& OCSP_TRUSTOTHER
))
371 flags
|= OCSP_NOVERIFY
;
372 if (!(flags
& OCSP_NOSIGS
)) {
374 skey
= X509_get0_pubkey(signer
);
375 ret
= OCSP_REQUEST_verify(req
, skey
);
377 OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY
, OCSP_R_SIGNATURE_FAILURE
);
381 if (!(flags
& OCSP_NOVERIFY
)) {
383 if (flags
& OCSP_NOCHAIN
)
384 init_res
= X509_STORE_CTX_init(ctx
, store
, signer
, NULL
);
386 init_res
= X509_STORE_CTX_init(ctx
, store
, signer
,
387 req
->optionalSignature
->certs
);
389 OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY
, ERR_R_X509_LIB
);
393 X509_STORE_CTX_set_purpose(ctx
, X509_PURPOSE_OCSP_HELPER
);
394 X509_STORE_CTX_set_trust(ctx
, X509_TRUST_OCSP_REQUEST
);
395 ret
= X509_verify_cert(ctx
);
397 ret
= X509_STORE_CTX_get_error(ctx
);
398 OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY
,
399 OCSP_R_CERTIFICATE_VERIFY_ERROR
);
400 ERR_add_error_data(2, "Verify error:",
401 X509_verify_cert_error_string(ret
));
411 X509_STORE_CTX_free(ctx
);
416 static int ocsp_req_find_signer(X509
**psigner
, OCSP_REQUEST
*req
,
417 X509_NAME
*nm
, STACK_OF(X509
) *certs
,
421 if (!(flags
& OCSP_NOINTERN
)) {
422 signer
= X509_find_by_subject(req
->optionalSignature
->certs
, nm
);
429 signer
= X509_find_by_subject(certs
, nm
);