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