diff options
Diffstat (limited to 'src/lib/libcrypto/x509/x509_vfy.c')
-rw-r--r-- | src/lib/libcrypto/x509/x509_vfy.c | 2215 |
1 files changed, 2215 insertions, 0 deletions
diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c new file mode 100644 index 0000000000..87ebf62525 --- /dev/null +++ b/src/lib/libcrypto/x509/x509_vfy.c | |||
@@ -0,0 +1,2215 @@ | |||
1 | /* crypto/x509/x509_vfy.c */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include <time.h> | ||
61 | #include <errno.h> | ||
62 | |||
63 | #include "cryptlib.h" | ||
64 | #include <openssl/crypto.h> | ||
65 | #include <openssl/lhash.h> | ||
66 | #include <openssl/buffer.h> | ||
67 | #include <openssl/evp.h> | ||
68 | #include <openssl/asn1.h> | ||
69 | #include <openssl/x509.h> | ||
70 | #include <openssl/x509v3.h> | ||
71 | #include <openssl/objects.h> | ||
72 | |||
73 | /* CRL score values */ | ||
74 | |||
75 | /* No unhandled critical extensions */ | ||
76 | |||
77 | #define CRL_SCORE_NOCRITICAL 0x100 | ||
78 | |||
79 | /* certificate is within CRL scope */ | ||
80 | |||
81 | #define CRL_SCORE_SCOPE 0x080 | ||
82 | |||
83 | /* CRL times valid */ | ||
84 | |||
85 | #define CRL_SCORE_TIME 0x040 | ||
86 | |||
87 | /* Issuer name matches certificate */ | ||
88 | |||
89 | #define CRL_SCORE_ISSUER_NAME 0x020 | ||
90 | |||
91 | /* If this score or above CRL is probably valid */ | ||
92 | |||
93 | #define CRL_SCORE_VALID (CRL_SCORE_NOCRITICAL|CRL_SCORE_TIME|CRL_SCORE_SCOPE) | ||
94 | |||
95 | /* CRL issuer is certificate issuer */ | ||
96 | |||
97 | #define CRL_SCORE_ISSUER_CERT 0x018 | ||
98 | |||
99 | /* CRL issuer is on certificate path */ | ||
100 | |||
101 | #define CRL_SCORE_SAME_PATH 0x008 | ||
102 | |||
103 | /* CRL issuer matches CRL AKID */ | ||
104 | |||
105 | #define CRL_SCORE_AKID 0x004 | ||
106 | |||
107 | /* Have a delta CRL with valid times */ | ||
108 | |||
109 | #define CRL_SCORE_TIME_DELTA 0x002 | ||
110 | |||
111 | static int null_callback(int ok,X509_STORE_CTX *e); | ||
112 | static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); | ||
113 | static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x); | ||
114 | static int check_chain_extensions(X509_STORE_CTX *ctx); | ||
115 | static int check_name_constraints(X509_STORE_CTX *ctx); | ||
116 | static int check_trust(X509_STORE_CTX *ctx); | ||
117 | static int check_revocation(X509_STORE_CTX *ctx); | ||
118 | static int check_cert(X509_STORE_CTX *ctx); | ||
119 | static int check_policy(X509_STORE_CTX *ctx); | ||
120 | |||
121 | static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, | ||
122 | unsigned int *preasons, | ||
123 | X509_CRL *crl, X509 *x); | ||
124 | static int get_crl_delta(X509_STORE_CTX *ctx, | ||
125 | X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x); | ||
126 | static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pcrl_score, | ||
127 | X509_CRL *base, STACK_OF(X509_CRL) *crls); | ||
128 | static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, | ||
129 | X509 **pissuer, int *pcrl_score); | ||
130 | static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, | ||
131 | unsigned int *preasons); | ||
132 | static int check_crl_path(X509_STORE_CTX *ctx, X509 *x); | ||
133 | static int check_crl_chain(X509_STORE_CTX *ctx, | ||
134 | STACK_OF(X509) *cert_path, | ||
135 | STACK_OF(X509) *crl_path); | ||
136 | |||
137 | static int internal_verify(X509_STORE_CTX *ctx); | ||
138 | const char X509_version[]="X.509" OPENSSL_VERSION_PTEXT; | ||
139 | |||
140 | |||
141 | static int null_callback(int ok, X509_STORE_CTX *e) | ||
142 | { | ||
143 | return ok; | ||
144 | } | ||
145 | |||
146 | #if 0 | ||
147 | static int x509_subject_cmp(X509 **a, X509 **b) | ||
148 | { | ||
149 | return X509_subject_name_cmp(*a,*b); | ||
150 | } | ||
151 | #endif | ||
152 | |||
153 | int X509_verify_cert(X509_STORE_CTX *ctx) | ||
154 | { | ||
155 | X509 *x,*xtmp,*chain_ss=NULL; | ||
156 | X509_NAME *xn; | ||
157 | int bad_chain = 0; | ||
158 | X509_VERIFY_PARAM *param = ctx->param; | ||
159 | int depth,i,ok=0; | ||
160 | int num; | ||
161 | int (*cb)(int xok,X509_STORE_CTX *xctx); | ||
162 | STACK_OF(X509) *sktmp=NULL; | ||
163 | if (ctx->cert == NULL) | ||
164 | { | ||
165 | X509err(X509_F_X509_VERIFY_CERT,X509_R_NO_CERT_SET_FOR_US_TO_VERIFY); | ||
166 | return -1; | ||
167 | } | ||
168 | |||
169 | cb=ctx->verify_cb; | ||
170 | |||
171 | /* first we make sure the chain we are going to build is | ||
172 | * present and that the first entry is in place */ | ||
173 | if (ctx->chain == NULL) | ||
174 | { | ||
175 | if ( ((ctx->chain=sk_X509_new_null()) == NULL) || | ||
176 | (!sk_X509_push(ctx->chain,ctx->cert))) | ||
177 | { | ||
178 | X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE); | ||
179 | goto end; | ||
180 | } | ||
181 | CRYPTO_add(&ctx->cert->references,1,CRYPTO_LOCK_X509); | ||
182 | ctx->last_untrusted=1; | ||
183 | } | ||
184 | |||
185 | /* We use a temporary STACK so we can chop and hack at it */ | ||
186 | if (ctx->untrusted != NULL | ||
187 | && (sktmp=sk_X509_dup(ctx->untrusted)) == NULL) | ||
188 | { | ||
189 | X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE); | ||
190 | goto end; | ||
191 | } | ||
192 | |||
193 | num=sk_X509_num(ctx->chain); | ||
194 | x=sk_X509_value(ctx->chain,num-1); | ||
195 | depth=param->depth; | ||
196 | |||
197 | |||
198 | for (;;) | ||
199 | { | ||
200 | /* If we have enough, we break */ | ||
201 | if (depth < num) break; /* FIXME: If this happens, we should take | ||
202 | * note of it and, if appropriate, use the | ||
203 | * X509_V_ERR_CERT_CHAIN_TOO_LONG error | ||
204 | * code later. | ||
205 | */ | ||
206 | |||
207 | /* If we are self signed, we break */ | ||
208 | xn=X509_get_issuer_name(x); | ||
209 | if (ctx->check_issued(ctx, x,x)) break; | ||
210 | |||
211 | /* If we were passed a cert chain, use it first */ | ||
212 | if (ctx->untrusted != NULL) | ||
213 | { | ||
214 | xtmp=find_issuer(ctx, sktmp,x); | ||
215 | if (xtmp != NULL) | ||
216 | { | ||
217 | if (!sk_X509_push(ctx->chain,xtmp)) | ||
218 | { | ||
219 | X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE); | ||
220 | goto end; | ||
221 | } | ||
222 | CRYPTO_add(&xtmp->references,1,CRYPTO_LOCK_X509); | ||
223 | (void)sk_X509_delete_ptr(sktmp,xtmp); | ||
224 | ctx->last_untrusted++; | ||
225 | x=xtmp; | ||
226 | num++; | ||
227 | /* reparse the full chain for | ||
228 | * the next one */ | ||
229 | continue; | ||
230 | } | ||
231 | } | ||
232 | break; | ||
233 | } | ||
234 | |||
235 | /* at this point, chain should contain a list of untrusted | ||
236 | * certificates. We now need to add at least one trusted one, | ||
237 | * if possible, otherwise we complain. */ | ||
238 | |||
239 | /* Examine last certificate in chain and see if it | ||
240 | * is self signed. | ||
241 | */ | ||
242 | |||
243 | i=sk_X509_num(ctx->chain); | ||
244 | x=sk_X509_value(ctx->chain,i-1); | ||
245 | xn = X509_get_subject_name(x); | ||
246 | if (ctx->check_issued(ctx, x, x)) | ||
247 | { | ||
248 | /* we have a self signed certificate */ | ||
249 | if (sk_X509_num(ctx->chain) == 1) | ||
250 | { | ||
251 | /* We have a single self signed certificate: see if | ||
252 | * we can find it in the store. We must have an exact | ||
253 | * match to avoid possible impersonation. | ||
254 | */ | ||
255 | ok = ctx->get_issuer(&xtmp, ctx, x); | ||
256 | if ((ok <= 0) || X509_cmp(x, xtmp)) | ||
257 | { | ||
258 | ctx->error=X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; | ||
259 | ctx->current_cert=x; | ||
260 | ctx->error_depth=i-1; | ||
261 | if (ok == 1) X509_free(xtmp); | ||
262 | bad_chain = 1; | ||
263 | ok=cb(0,ctx); | ||
264 | if (!ok) goto end; | ||
265 | } | ||
266 | else | ||
267 | { | ||
268 | /* We have a match: replace certificate with store version | ||
269 | * so we get any trust settings. | ||
270 | */ | ||
271 | X509_free(x); | ||
272 | x = xtmp; | ||
273 | (void)sk_X509_set(ctx->chain, i - 1, x); | ||
274 | ctx->last_untrusted=0; | ||
275 | } | ||
276 | } | ||
277 | else | ||
278 | { | ||
279 | /* extract and save self signed certificate for later use */ | ||
280 | chain_ss=sk_X509_pop(ctx->chain); | ||
281 | ctx->last_untrusted--; | ||
282 | num--; | ||
283 | x=sk_X509_value(ctx->chain,num-1); | ||
284 | } | ||
285 | } | ||
286 | |||
287 | /* We now lookup certs from the certificate store */ | ||
288 | for (;;) | ||
289 | { | ||
290 | /* If we have enough, we break */ | ||
291 | if (depth < num) break; | ||
292 | |||
293 | /* If we are self signed, we break */ | ||
294 | xn=X509_get_issuer_name(x); | ||
295 | if (ctx->check_issued(ctx,x,x)) break; | ||
296 | |||
297 | ok = ctx->get_issuer(&xtmp, ctx, x); | ||
298 | |||
299 | if (ok < 0) return ok; | ||
300 | if (ok == 0) break; | ||
301 | |||
302 | x = xtmp; | ||
303 | if (!sk_X509_push(ctx->chain,x)) | ||
304 | { | ||
305 | X509_free(xtmp); | ||
306 | X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE); | ||
307 | return 0; | ||
308 | } | ||
309 | num++; | ||
310 | } | ||
311 | |||
312 | /* we now have our chain, lets check it... */ | ||
313 | xn=X509_get_issuer_name(x); | ||
314 | |||
315 | /* Is last certificate looked up self signed? */ | ||
316 | if (!ctx->check_issued(ctx,x,x)) | ||
317 | { | ||
318 | if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) | ||
319 | { | ||
320 | if (ctx->last_untrusted >= num) | ||
321 | ctx->error=X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; | ||
322 | else | ||
323 | ctx->error=X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT; | ||
324 | ctx->current_cert=x; | ||
325 | } | ||
326 | else | ||
327 | { | ||
328 | |||
329 | sk_X509_push(ctx->chain,chain_ss); | ||
330 | num++; | ||
331 | ctx->last_untrusted=num; | ||
332 | ctx->current_cert=chain_ss; | ||
333 | ctx->error=X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; | ||
334 | chain_ss=NULL; | ||
335 | } | ||
336 | |||
337 | ctx->error_depth=num-1; | ||
338 | bad_chain = 1; | ||
339 | ok=cb(0,ctx); | ||
340 | if (!ok) goto end; | ||
341 | } | ||
342 | |||
343 | /* We have the chain complete: now we need to check its purpose */ | ||
344 | ok = check_chain_extensions(ctx); | ||
345 | |||
346 | if (!ok) goto end; | ||
347 | |||
348 | /* Check name constraints */ | ||
349 | |||
350 | ok = check_name_constraints(ctx); | ||
351 | |||
352 | if (!ok) goto end; | ||
353 | |||
354 | /* The chain extensions are OK: check trust */ | ||
355 | |||
356 | if (param->trust > 0) ok = check_trust(ctx); | ||
357 | |||
358 | if (!ok) goto end; | ||
359 | |||
360 | /* We may as well copy down any DSA parameters that are required */ | ||
361 | X509_get_pubkey_parameters(NULL,ctx->chain); | ||
362 | |||
363 | /* Check revocation status: we do this after copying parameters | ||
364 | * because they may be needed for CRL signature verification. | ||
365 | */ | ||
366 | |||
367 | ok = ctx->check_revocation(ctx); | ||
368 | if(!ok) goto end; | ||
369 | |||
370 | /* At this point, we have a chain and need to verify it */ | ||
371 | if (ctx->verify != NULL) | ||
372 | ok=ctx->verify(ctx); | ||
373 | else | ||
374 | ok=internal_verify(ctx); | ||
375 | if(!ok) goto end; | ||
376 | |||
377 | #ifndef OPENSSL_NO_RFC3779 | ||
378 | /* RFC 3779 path validation, now that CRL check has been done */ | ||
379 | ok = v3_asid_validate_path(ctx); | ||
380 | if (!ok) goto end; | ||
381 | ok = v3_addr_validate_path(ctx); | ||
382 | if (!ok) goto end; | ||
383 | #endif | ||
384 | |||
385 | /* If we get this far evaluate policies */ | ||
386 | if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK)) | ||
387 | ok = ctx->check_policy(ctx); | ||
388 | if(!ok) goto end; | ||
389 | if (0) | ||
390 | { | ||
391 | end: | ||
392 | X509_get_pubkey_parameters(NULL,ctx->chain); | ||
393 | } | ||
394 | if (sktmp != NULL) sk_X509_free(sktmp); | ||
395 | if (chain_ss != NULL) X509_free(chain_ss); | ||
396 | return ok; | ||
397 | } | ||
398 | |||
399 | |||
400 | /* Given a STACK_OF(X509) find the issuer of cert (if any) | ||
401 | */ | ||
402 | |||
403 | static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x) | ||
404 | { | ||
405 | int i; | ||
406 | X509 *issuer; | ||
407 | for (i = 0; i < sk_X509_num(sk); i++) | ||
408 | { | ||
409 | issuer = sk_X509_value(sk, i); | ||
410 | if (ctx->check_issued(ctx, x, issuer)) | ||
411 | return issuer; | ||
412 | } | ||
413 | return NULL; | ||
414 | } | ||
415 | |||
416 | /* Given a possible certificate and issuer check them */ | ||
417 | |||
418 | static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer) | ||
419 | { | ||
420 | int ret; | ||
421 | ret = X509_check_issued(issuer, x); | ||
422 | if (ret == X509_V_OK) | ||
423 | return 1; | ||
424 | /* If we haven't asked for issuer errors don't set ctx */ | ||
425 | if (!(ctx->param->flags & X509_V_FLAG_CB_ISSUER_CHECK)) | ||
426 | return 0; | ||
427 | |||
428 | ctx->error = ret; | ||
429 | ctx->current_cert = x; | ||
430 | ctx->current_issuer = issuer; | ||
431 | return ctx->verify_cb(0, ctx); | ||
432 | return 0; | ||
433 | } | ||
434 | |||
435 | /* Alternative lookup method: look from a STACK stored in other_ctx */ | ||
436 | |||
437 | static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) | ||
438 | { | ||
439 | *issuer = find_issuer(ctx, ctx->other_ctx, x); | ||
440 | if (*issuer) | ||
441 | { | ||
442 | CRYPTO_add(&(*issuer)->references,1,CRYPTO_LOCK_X509); | ||
443 | return 1; | ||
444 | } | ||
445 | else | ||
446 | return 0; | ||
447 | } | ||
448 | |||
449 | |||
450 | /* Check a certificate chains extensions for consistency | ||
451 | * with the supplied purpose | ||
452 | */ | ||
453 | |||
454 | static int check_chain_extensions(X509_STORE_CTX *ctx) | ||
455 | { | ||
456 | #ifdef OPENSSL_NO_CHAIN_VERIFY | ||
457 | return 1; | ||
458 | #else | ||
459 | int i, ok=0, must_be_ca, plen = 0; | ||
460 | X509 *x; | ||
461 | int (*cb)(int xok,X509_STORE_CTX *xctx); | ||
462 | int proxy_path_length = 0; | ||
463 | int purpose; | ||
464 | int allow_proxy_certs; | ||
465 | cb=ctx->verify_cb; | ||
466 | |||
467 | /* must_be_ca can have 1 of 3 values: | ||
468 | -1: we accept both CA and non-CA certificates, to allow direct | ||
469 | use of self-signed certificates (which are marked as CA). | ||
470 | 0: we only accept non-CA certificates. This is currently not | ||
471 | used, but the possibility is present for future extensions. | ||
472 | 1: we only accept CA certificates. This is currently used for | ||
473 | all certificates in the chain except the leaf certificate. | ||
474 | */ | ||
475 | must_be_ca = -1; | ||
476 | |||
477 | /* CRL path validation */ | ||
478 | if (ctx->parent) | ||
479 | { | ||
480 | allow_proxy_certs = 0; | ||
481 | purpose = X509_PURPOSE_CRL_SIGN; | ||
482 | } | ||
483 | else | ||
484 | { | ||
485 | allow_proxy_certs = | ||
486 | !!(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS); | ||
487 | /* A hack to keep people who don't want to modify their | ||
488 | software happy */ | ||
489 | if (getenv("OPENSSL_ALLOW_PROXY_CERTS")) | ||
490 | allow_proxy_certs = 1; | ||
491 | purpose = ctx->param->purpose; | ||
492 | } | ||
493 | |||
494 | /* Check all untrusted certificates */ | ||
495 | for (i = 0; i < ctx->last_untrusted; i++) | ||
496 | { | ||
497 | int ret; | ||
498 | x = sk_X509_value(ctx->chain, i); | ||
499 | if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) | ||
500 | && (x->ex_flags & EXFLAG_CRITICAL)) | ||
501 | { | ||
502 | ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION; | ||
503 | ctx->error_depth = i; | ||
504 | ctx->current_cert = x; | ||
505 | ok=cb(0,ctx); | ||
506 | if (!ok) goto end; | ||
507 | } | ||
508 | if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) | ||
509 | { | ||
510 | ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED; | ||
511 | ctx->error_depth = i; | ||
512 | ctx->current_cert = x; | ||
513 | ok=cb(0,ctx); | ||
514 | if (!ok) goto end; | ||
515 | } | ||
516 | ret = X509_check_ca(x); | ||
517 | switch(must_be_ca) | ||
518 | { | ||
519 | case -1: | ||
520 | if ((ctx->param->flags & X509_V_FLAG_X509_STRICT) | ||
521 | && (ret != 1) && (ret != 0)) | ||
522 | { | ||
523 | ret = 0; | ||
524 | ctx->error = X509_V_ERR_INVALID_CA; | ||
525 | } | ||
526 | else | ||
527 | ret = 1; | ||
528 | break; | ||
529 | case 0: | ||
530 | if (ret != 0) | ||
531 | { | ||
532 | ret = 0; | ||
533 | ctx->error = X509_V_ERR_INVALID_NON_CA; | ||
534 | } | ||
535 | else | ||
536 | ret = 1; | ||
537 | break; | ||
538 | default: | ||
539 | if ((ret == 0) | ||
540 | || ((ctx->param->flags & X509_V_FLAG_X509_STRICT) | ||
541 | && (ret != 1))) | ||
542 | { | ||
543 | ret = 0; | ||
544 | ctx->error = X509_V_ERR_INVALID_CA; | ||
545 | } | ||
546 | else | ||
547 | ret = 1; | ||
548 | break; | ||
549 | } | ||
550 | if (ret == 0) | ||
551 | { | ||
552 | ctx->error_depth = i; | ||
553 | ctx->current_cert = x; | ||
554 | ok=cb(0,ctx); | ||
555 | if (!ok) goto end; | ||
556 | } | ||
557 | if (ctx->param->purpose > 0) | ||
558 | { | ||
559 | ret = X509_check_purpose(x, purpose, must_be_ca > 0); | ||
560 | if ((ret == 0) | ||
561 | || ((ctx->param->flags & X509_V_FLAG_X509_STRICT) | ||
562 | && (ret != 1))) | ||
563 | { | ||
564 | ctx->error = X509_V_ERR_INVALID_PURPOSE; | ||
565 | ctx->error_depth = i; | ||
566 | ctx->current_cert = x; | ||
567 | ok=cb(0,ctx); | ||
568 | if (!ok) goto end; | ||
569 | } | ||
570 | } | ||
571 | /* Check pathlen if not self issued */ | ||
572 | if ((i > 1) && !(x->ex_flags & EXFLAG_SI) | ||
573 | && (x->ex_pathlen != -1) | ||
574 | && (plen > (x->ex_pathlen + proxy_path_length + 1))) | ||
575 | { | ||
576 | ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED; | ||
577 | ctx->error_depth = i; | ||
578 | ctx->current_cert = x; | ||
579 | ok=cb(0,ctx); | ||
580 | if (!ok) goto end; | ||
581 | } | ||
582 | /* Increment path length if not self issued */ | ||
583 | if (!(x->ex_flags & EXFLAG_SI)) | ||
584 | plen++; | ||
585 | /* If this certificate is a proxy certificate, the next | ||
586 | certificate must be another proxy certificate or a EE | ||
587 | certificate. If not, the next certificate must be a | ||
588 | CA certificate. */ | ||
589 | if (x->ex_flags & EXFLAG_PROXY) | ||
590 | { | ||
591 | if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen) | ||
592 | { | ||
593 | ctx->error = | ||
594 | X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED; | ||
595 | ctx->error_depth = i; | ||
596 | ctx->current_cert = x; | ||
597 | ok=cb(0,ctx); | ||
598 | if (!ok) goto end; | ||
599 | } | ||
600 | proxy_path_length++; | ||
601 | must_be_ca = 0; | ||
602 | } | ||
603 | else | ||
604 | must_be_ca = 1; | ||
605 | } | ||
606 | ok = 1; | ||
607 | end: | ||
608 | return ok; | ||
609 | #endif | ||
610 | } | ||
611 | |||
612 | static int check_name_constraints(X509_STORE_CTX *ctx) | ||
613 | { | ||
614 | X509 *x; | ||
615 | int i, j, rv; | ||
616 | /* Check name constraints for all certificates */ | ||
617 | for (i = sk_X509_num(ctx->chain) - 1; i >= 0; i--) | ||
618 | { | ||
619 | x = sk_X509_value(ctx->chain, i); | ||
620 | /* Ignore self issued certs unless last in chain */ | ||
621 | if (i && (x->ex_flags & EXFLAG_SI)) | ||
622 | continue; | ||
623 | /* Check against constraints for all certificates higher in | ||
624 | * chain including trust anchor. Trust anchor not strictly | ||
625 | * speaking needed but if it includes constraints it is to be | ||
626 | * assumed it expects them to be obeyed. | ||
627 | */ | ||
628 | for (j = sk_X509_num(ctx->chain) - 1; j > i; j--) | ||
629 | { | ||
630 | NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc; | ||
631 | if (nc) | ||
632 | { | ||
633 | rv = NAME_CONSTRAINTS_check(x, nc); | ||
634 | if (rv != X509_V_OK) | ||
635 | { | ||
636 | ctx->error = rv; | ||
637 | ctx->error_depth = i; | ||
638 | ctx->current_cert = x; | ||
639 | if (!ctx->verify_cb(0,ctx)) | ||
640 | return 0; | ||
641 | } | ||
642 | } | ||
643 | } | ||
644 | } | ||
645 | return 1; | ||
646 | } | ||
647 | |||
648 | static int check_trust(X509_STORE_CTX *ctx) | ||
649 | { | ||
650 | #ifdef OPENSSL_NO_CHAIN_VERIFY | ||
651 | return 1; | ||
652 | #else | ||
653 | int i, ok; | ||
654 | X509 *x; | ||
655 | int (*cb)(int xok,X509_STORE_CTX *xctx); | ||
656 | cb=ctx->verify_cb; | ||
657 | /* For now just check the last certificate in the chain */ | ||
658 | i = sk_X509_num(ctx->chain) - 1; | ||
659 | x = sk_X509_value(ctx->chain, i); | ||
660 | ok = X509_check_trust(x, ctx->param->trust, 0); | ||
661 | if (ok == X509_TRUST_TRUSTED) | ||
662 | return 1; | ||
663 | ctx->error_depth = i; | ||
664 | ctx->current_cert = x; | ||
665 | if (ok == X509_TRUST_REJECTED) | ||
666 | ctx->error = X509_V_ERR_CERT_REJECTED; | ||
667 | else | ||
668 | ctx->error = X509_V_ERR_CERT_UNTRUSTED; | ||
669 | ok = cb(0, ctx); | ||
670 | return ok; | ||
671 | #endif | ||
672 | } | ||
673 | |||
674 | static int check_revocation(X509_STORE_CTX *ctx) | ||
675 | { | ||
676 | int i, last, ok; | ||
677 | if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK)) | ||
678 | return 1; | ||
679 | if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL) | ||
680 | last = sk_X509_num(ctx->chain) - 1; | ||
681 | else | ||
682 | { | ||
683 | /* If checking CRL paths this isn't the EE certificate */ | ||
684 | if (ctx->parent) | ||
685 | return 1; | ||
686 | last = 0; | ||
687 | } | ||
688 | for(i = 0; i <= last; i++) | ||
689 | { | ||
690 | ctx->error_depth = i; | ||
691 | ok = check_cert(ctx); | ||
692 | if (!ok) return ok; | ||
693 | } | ||
694 | return 1; | ||
695 | } | ||
696 | |||
697 | static int check_cert(X509_STORE_CTX *ctx) | ||
698 | { | ||
699 | X509_CRL *crl = NULL, *dcrl = NULL; | ||
700 | X509 *x; | ||
701 | int ok, cnum; | ||
702 | cnum = ctx->error_depth; | ||
703 | x = sk_X509_value(ctx->chain, cnum); | ||
704 | ctx->current_cert = x; | ||
705 | ctx->current_issuer = NULL; | ||
706 | ctx->current_reasons = 0; | ||
707 | while (ctx->current_reasons != CRLDP_ALL_REASONS) | ||
708 | { | ||
709 | /* Try to retrieve relevant CRL */ | ||
710 | if (ctx->get_crl) | ||
711 | ok = ctx->get_crl(ctx, &crl, x); | ||
712 | else | ||
713 | ok = get_crl_delta(ctx, &crl, &dcrl, x); | ||
714 | /* If error looking up CRL, nothing we can do except | ||
715 | * notify callback | ||
716 | */ | ||
717 | if(!ok) | ||
718 | { | ||
719 | ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL; | ||
720 | ok = ctx->verify_cb(0, ctx); | ||
721 | goto err; | ||
722 | } | ||
723 | ctx->current_crl = crl; | ||
724 | ok = ctx->check_crl(ctx, crl); | ||
725 | if (!ok) | ||
726 | goto err; | ||
727 | |||
728 | if (dcrl) | ||
729 | { | ||
730 | ok = ctx->check_crl(ctx, dcrl); | ||
731 | if (!ok) | ||
732 | goto err; | ||
733 | ok = ctx->cert_crl(ctx, dcrl, x); | ||
734 | if (!ok) | ||
735 | goto err; | ||
736 | } | ||
737 | else | ||
738 | ok = 1; | ||
739 | |||
740 | /* Don't look in full CRL if delta reason is removefromCRL */ | ||
741 | if (ok != 2) | ||
742 | { | ||
743 | ok = ctx->cert_crl(ctx, crl, x); | ||
744 | if (!ok) | ||
745 | goto err; | ||
746 | } | ||
747 | |||
748 | X509_CRL_free(crl); | ||
749 | X509_CRL_free(dcrl); | ||
750 | crl = NULL; | ||
751 | dcrl = NULL; | ||
752 | } | ||
753 | err: | ||
754 | X509_CRL_free(crl); | ||
755 | X509_CRL_free(dcrl); | ||
756 | |||
757 | ctx->current_crl = NULL; | ||
758 | return ok; | ||
759 | |||
760 | } | ||
761 | |||
762 | /* Check CRL times against values in X509_STORE_CTX */ | ||
763 | |||
764 | static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) | ||
765 | { | ||
766 | time_t *ptime; | ||
767 | int i; | ||
768 | if (notify) | ||
769 | ctx->current_crl = crl; | ||
770 | if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) | ||
771 | ptime = &ctx->param->check_time; | ||
772 | else | ||
773 | ptime = NULL; | ||
774 | |||
775 | i=X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime); | ||
776 | if (i == 0) | ||
777 | { | ||
778 | if (!notify) | ||
779 | return 0; | ||
780 | ctx->error=X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD; | ||
781 | if (!ctx->verify_cb(0, ctx)) | ||
782 | return 0; | ||
783 | } | ||
784 | |||
785 | if (i > 0) | ||
786 | { | ||
787 | if (!notify) | ||
788 | return 0; | ||
789 | ctx->error=X509_V_ERR_CRL_NOT_YET_VALID; | ||
790 | if (!ctx->verify_cb(0, ctx)) | ||
791 | return 0; | ||
792 | } | ||
793 | |||
794 | if(X509_CRL_get_nextUpdate(crl)) | ||
795 | { | ||
796 | i=X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime); | ||
797 | |||
798 | if (i == 0) | ||
799 | { | ||
800 | if (!notify) | ||
801 | return 0; | ||
802 | ctx->error=X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD; | ||
803 | if (!ctx->verify_cb(0, ctx)) | ||
804 | return 0; | ||
805 | } | ||
806 | /* Ignore expiry of base CRL is delta is valid */ | ||
807 | if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA)) | ||
808 | { | ||
809 | if (!notify) | ||
810 | return 0; | ||
811 | ctx->error=X509_V_ERR_CRL_HAS_EXPIRED; | ||
812 | if (!ctx->verify_cb(0, ctx)) | ||
813 | return 0; | ||
814 | } | ||
815 | } | ||
816 | |||
817 | if (notify) | ||
818 | ctx->current_crl = NULL; | ||
819 | |||
820 | return 1; | ||
821 | } | ||
822 | |||
823 | static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl, | ||
824 | X509 **pissuer, int *pscore, unsigned int *preasons, | ||
825 | STACK_OF(X509_CRL) *crls) | ||
826 | { | ||
827 | int i, crl_score, best_score = *pscore; | ||
828 | unsigned int reasons, best_reasons = 0; | ||
829 | X509 *x = ctx->current_cert; | ||
830 | X509_CRL *crl, *best_crl = NULL; | ||
831 | X509 *crl_issuer = NULL, *best_crl_issuer = NULL; | ||
832 | |||
833 | for (i = 0; i < sk_X509_CRL_num(crls); i++) | ||
834 | { | ||
835 | crl = sk_X509_CRL_value(crls, i); | ||
836 | reasons = *preasons; | ||
837 | crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x); | ||
838 | |||
839 | if (crl_score > best_score) | ||
840 | { | ||
841 | best_crl = crl; | ||
842 | best_crl_issuer = crl_issuer; | ||
843 | best_score = crl_score; | ||
844 | best_reasons = reasons; | ||
845 | } | ||
846 | } | ||
847 | |||
848 | if (best_crl) | ||
849 | { | ||
850 | if (*pcrl) | ||
851 | X509_CRL_free(*pcrl); | ||
852 | *pcrl = best_crl; | ||
853 | *pissuer = best_crl_issuer; | ||
854 | *pscore = best_score; | ||
855 | *preasons = best_reasons; | ||
856 | CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509_CRL); | ||
857 | if (*pdcrl) | ||
858 | { | ||
859 | X509_CRL_free(*pdcrl); | ||
860 | *pdcrl = NULL; | ||
861 | } | ||
862 | get_delta_sk(ctx, pdcrl, pscore, best_crl, crls); | ||
863 | } | ||
864 | |||
865 | if (best_score >= CRL_SCORE_VALID) | ||
866 | return 1; | ||
867 | |||
868 | return 0; | ||
869 | } | ||
870 | |||
871 | /* Compare two CRL extensions for delta checking purposes. They should be | ||
872 | * both present or both absent. If both present all fields must be identical. | ||
873 | */ | ||
874 | |||
875 | static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid) | ||
876 | { | ||
877 | ASN1_OCTET_STRING *exta, *extb; | ||
878 | int i; | ||
879 | i = X509_CRL_get_ext_by_NID(a, nid, 0); | ||
880 | if (i >= 0) | ||
881 | { | ||
882 | /* Can't have multiple occurrences */ | ||
883 | if (X509_CRL_get_ext_by_NID(a, nid, i) != -1) | ||
884 | return 0; | ||
885 | exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i)); | ||
886 | } | ||
887 | else | ||
888 | exta = NULL; | ||
889 | |||
890 | i = X509_CRL_get_ext_by_NID(b, nid, 0); | ||
891 | |||
892 | if (i >= 0) | ||
893 | { | ||
894 | |||
895 | if (X509_CRL_get_ext_by_NID(b, nid, i) != -1) | ||
896 | return 0; | ||
897 | extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i)); | ||
898 | } | ||
899 | else | ||
900 | extb = NULL; | ||
901 | |||
902 | if (!exta && !extb) | ||
903 | return 1; | ||
904 | |||
905 | if (!exta || !extb) | ||
906 | return 0; | ||
907 | |||
908 | |||
909 | if (ASN1_OCTET_STRING_cmp(exta, extb)) | ||
910 | return 0; | ||
911 | |||
912 | return 1; | ||
913 | } | ||
914 | |||
915 | /* See if a base and delta are compatible */ | ||
916 | |||
917 | static int check_delta_base(X509_CRL *delta, X509_CRL *base) | ||
918 | { | ||
919 | /* Delta CRL must be a delta */ | ||
920 | if (!delta->base_crl_number) | ||
921 | return 0; | ||
922 | /* Base must have a CRL number */ | ||
923 | if (!base->crl_number) | ||
924 | return 0; | ||
925 | /* Issuer names must match */ | ||
926 | if (X509_NAME_cmp(X509_CRL_get_issuer(base), | ||
927 | X509_CRL_get_issuer(delta))) | ||
928 | return 0; | ||
929 | /* AKID and IDP must match */ | ||
930 | if (!crl_extension_match(delta, base, NID_authority_key_identifier)) | ||
931 | return 0; | ||
932 | if (!crl_extension_match(delta, base, NID_issuing_distribution_point)) | ||
933 | return 0; | ||
934 | /* Delta CRL base number must not exceed Full CRL number. */ | ||
935 | if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0) | ||
936 | return 0; | ||
937 | /* Delta CRL number must exceed full CRL number */ | ||
938 | if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0) | ||
939 | return 1; | ||
940 | return 0; | ||
941 | } | ||
942 | |||
943 | /* For a given base CRL find a delta... maybe extend to delta scoring | ||
944 | * or retrieve a chain of deltas... | ||
945 | */ | ||
946 | |||
947 | static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore, | ||
948 | X509_CRL *base, STACK_OF(X509_CRL) *crls) | ||
949 | { | ||
950 | X509_CRL *delta; | ||
951 | int i; | ||
952 | if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS)) | ||
953 | return; | ||
954 | if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST)) | ||
955 | return; | ||
956 | for (i = 0; i < sk_X509_CRL_num(crls); i++) | ||
957 | { | ||
958 | delta = sk_X509_CRL_value(crls, i); | ||
959 | if (check_delta_base(delta, base)) | ||
960 | { | ||
961 | if (check_crl_time(ctx, delta, 0)) | ||
962 | *pscore |= CRL_SCORE_TIME_DELTA; | ||
963 | CRYPTO_add(&delta->references, 1, CRYPTO_LOCK_X509_CRL); | ||
964 | *dcrl = delta; | ||
965 | return; | ||
966 | } | ||
967 | } | ||
968 | *dcrl = NULL; | ||
969 | } | ||
970 | |||
971 | /* For a given CRL return how suitable it is for the supplied certificate 'x'. | ||
972 | * The return value is a mask of several criteria. | ||
973 | * If the issuer is not the certificate issuer this is returned in *pissuer. | ||
974 | * The reasons mask is also used to determine if the CRL is suitable: if | ||
975 | * no new reasons the CRL is rejected, otherwise reasons is updated. | ||
976 | */ | ||
977 | |||
978 | static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, | ||
979 | unsigned int *preasons, | ||
980 | X509_CRL *crl, X509 *x) | ||
981 | { | ||
982 | |||
983 | int crl_score = 0; | ||
984 | unsigned int tmp_reasons = *preasons, crl_reasons; | ||
985 | |||
986 | /* First see if we can reject CRL straight away */ | ||
987 | |||
988 | /* Invalid IDP cannot be processed */ | ||
989 | if (crl->idp_flags & IDP_INVALID) | ||
990 | return 0; | ||
991 | /* Reason codes or indirect CRLs need extended CRL support */ | ||
992 | if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) | ||
993 | { | ||
994 | if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS)) | ||
995 | return 0; | ||
996 | } | ||
997 | else if (crl->idp_flags & IDP_REASONS) | ||
998 | { | ||
999 | /* If no new reasons reject */ | ||
1000 | if (!(crl->idp_reasons & ~tmp_reasons)) | ||
1001 | return 0; | ||
1002 | } | ||
1003 | /* Don't process deltas at this stage */ | ||
1004 | else if (crl->base_crl_number) | ||
1005 | return 0; | ||
1006 | /* If issuer name doesn't match certificate need indirect CRL */ | ||
1007 | if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) | ||
1008 | { | ||
1009 | if (!(crl->idp_flags & IDP_INDIRECT)) | ||
1010 | return 0; | ||
1011 | } | ||
1012 | else | ||
1013 | crl_score |= CRL_SCORE_ISSUER_NAME; | ||
1014 | |||
1015 | if (!(crl->flags & EXFLAG_CRITICAL)) | ||
1016 | crl_score |= CRL_SCORE_NOCRITICAL; | ||
1017 | |||
1018 | /* Check expiry */ | ||
1019 | if (check_crl_time(ctx, crl, 0)) | ||
1020 | crl_score |= CRL_SCORE_TIME; | ||
1021 | |||
1022 | /* Check authority key ID and locate certificate issuer */ | ||
1023 | crl_akid_check(ctx, crl, pissuer, &crl_score); | ||
1024 | |||
1025 | /* If we can't locate certificate issuer at this point forget it */ | ||
1026 | |||
1027 | if (!(crl_score & CRL_SCORE_AKID)) | ||
1028 | return 0; | ||
1029 | |||
1030 | /* Check cert for matching CRL distribution points */ | ||
1031 | |||
1032 | if (crl_crldp_check(x, crl, crl_score, &crl_reasons)) | ||
1033 | { | ||
1034 | /* If no new reasons reject */ | ||
1035 | if (!(crl_reasons & ~tmp_reasons)) | ||
1036 | return 0; | ||
1037 | tmp_reasons |= crl_reasons; | ||
1038 | crl_score |= CRL_SCORE_SCOPE; | ||
1039 | } | ||
1040 | |||
1041 | *preasons = tmp_reasons; | ||
1042 | |||
1043 | return crl_score; | ||
1044 | |||
1045 | } | ||
1046 | |||
1047 | static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, | ||
1048 | X509 **pissuer, int *pcrl_score) | ||
1049 | { | ||
1050 | X509 *crl_issuer = NULL; | ||
1051 | X509_NAME *cnm = X509_CRL_get_issuer(crl); | ||
1052 | int cidx = ctx->error_depth; | ||
1053 | int i; | ||
1054 | |||
1055 | if (cidx != sk_X509_num(ctx->chain) - 1) | ||
1056 | cidx++; | ||
1057 | |||
1058 | crl_issuer = sk_X509_value(ctx->chain, cidx); | ||
1059 | |||
1060 | if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) | ||
1061 | { | ||
1062 | if (*pcrl_score & CRL_SCORE_ISSUER_NAME) | ||
1063 | { | ||
1064 | *pcrl_score |= CRL_SCORE_AKID|CRL_SCORE_ISSUER_CERT; | ||
1065 | *pissuer = crl_issuer; | ||
1066 | return; | ||
1067 | } | ||
1068 | } | ||
1069 | |||
1070 | for (cidx++; cidx < sk_X509_num(ctx->chain); cidx++) | ||
1071 | { | ||
1072 | crl_issuer = sk_X509_value(ctx->chain, cidx); | ||
1073 | if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) | ||
1074 | continue; | ||
1075 | if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) | ||
1076 | { | ||
1077 | *pcrl_score |= CRL_SCORE_AKID|CRL_SCORE_SAME_PATH; | ||
1078 | *pissuer = crl_issuer; | ||
1079 | return; | ||
1080 | } | ||
1081 | } | ||
1082 | |||
1083 | /* Anything else needs extended CRL support */ | ||
1084 | |||
1085 | if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) | ||
1086 | return; | ||
1087 | |||
1088 | /* Otherwise the CRL issuer is not on the path. Look for it in the | ||
1089 | * set of untrusted certificates. | ||
1090 | */ | ||
1091 | for (i = 0; i < sk_X509_num(ctx->untrusted); i++) | ||
1092 | { | ||
1093 | crl_issuer = sk_X509_value(ctx->untrusted, i); | ||
1094 | if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) | ||
1095 | continue; | ||
1096 | if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) | ||
1097 | { | ||
1098 | *pissuer = crl_issuer; | ||
1099 | *pcrl_score |= CRL_SCORE_AKID; | ||
1100 | return; | ||
1101 | } | ||
1102 | } | ||
1103 | } | ||
1104 | |||
1105 | /* Check the path of a CRL issuer certificate. This creates a new | ||
1106 | * X509_STORE_CTX and populates it with most of the parameters from the | ||
1107 | * parent. This could be optimised somewhat since a lot of path checking | ||
1108 | * will be duplicated by the parent, but this will rarely be used in | ||
1109 | * practice. | ||
1110 | */ | ||
1111 | |||
1112 | static int check_crl_path(X509_STORE_CTX *ctx, X509 *x) | ||
1113 | { | ||
1114 | X509_STORE_CTX crl_ctx; | ||
1115 | int ret; | ||
1116 | /* Don't allow recursive CRL path validation */ | ||
1117 | if (ctx->parent) | ||
1118 | return 0; | ||
1119 | if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted)) | ||
1120 | return -1; | ||
1121 | |||
1122 | crl_ctx.crls = ctx->crls; | ||
1123 | /* Copy verify params across */ | ||
1124 | X509_STORE_CTX_set0_param(&crl_ctx, ctx->param); | ||
1125 | |||
1126 | crl_ctx.parent = ctx; | ||
1127 | crl_ctx.verify_cb = ctx->verify_cb; | ||
1128 | |||
1129 | /* Verify CRL issuer */ | ||
1130 | ret = X509_verify_cert(&crl_ctx); | ||
1131 | |||
1132 | if (ret <= 0) | ||
1133 | goto err; | ||
1134 | |||
1135 | /* Check chain is acceptable */ | ||
1136 | |||
1137 | ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain); | ||
1138 | err: | ||
1139 | X509_STORE_CTX_cleanup(&crl_ctx); | ||
1140 | return ret; | ||
1141 | } | ||
1142 | |||
1143 | /* RFC3280 says nothing about the relationship between CRL path | ||
1144 | * and certificate path, which could lead to situations where a | ||
1145 | * certificate could be revoked or validated by a CA not authorised | ||
1146 | * to do so. RFC5280 is more strict and states that the two paths must | ||
1147 | * end in the same trust anchor, though some discussions remain... | ||
1148 | * until this is resolved we use the RFC5280 version | ||
1149 | */ | ||
1150 | |||
1151 | static int check_crl_chain(X509_STORE_CTX *ctx, | ||
1152 | STACK_OF(X509) *cert_path, | ||
1153 | STACK_OF(X509) *crl_path) | ||
1154 | { | ||
1155 | X509 *cert_ta, *crl_ta; | ||
1156 | cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1); | ||
1157 | crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1); | ||
1158 | if (!X509_cmp(cert_ta, crl_ta)) | ||
1159 | return 1; | ||
1160 | return 0; | ||
1161 | } | ||
1162 | |||
1163 | /* Check for match between two dist point names: three separate cases. | ||
1164 | * 1. Both are relative names and compare X509_NAME types. | ||
1165 | * 2. One full, one relative. Compare X509_NAME to GENERAL_NAMES. | ||
1166 | * 3. Both are full names and compare two GENERAL_NAMES. | ||
1167 | * 4. One is NULL: automatic match. | ||
1168 | */ | ||
1169 | |||
1170 | |||
1171 | static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b) | ||
1172 | { | ||
1173 | X509_NAME *nm = NULL; | ||
1174 | GENERAL_NAMES *gens = NULL; | ||
1175 | GENERAL_NAME *gena, *genb; | ||
1176 | int i, j; | ||
1177 | if (!a || !b) | ||
1178 | return 1; | ||
1179 | if (a->type == 1) | ||
1180 | { | ||
1181 | if (!a->dpname) | ||
1182 | return 0; | ||
1183 | /* Case 1: two X509_NAME */ | ||
1184 | if (b->type == 1) | ||
1185 | { | ||
1186 | if (!b->dpname) | ||
1187 | return 0; | ||
1188 | if (!X509_NAME_cmp(a->dpname, b->dpname)) | ||
1189 | return 1; | ||
1190 | else | ||
1191 | return 0; | ||
1192 | } | ||
1193 | /* Case 2: set name and GENERAL_NAMES appropriately */ | ||
1194 | nm = a->dpname; | ||
1195 | gens = b->name.fullname; | ||
1196 | } | ||
1197 | else if (b->type == 1) | ||
1198 | { | ||
1199 | if (!b->dpname) | ||
1200 | return 0; | ||
1201 | /* Case 2: set name and GENERAL_NAMES appropriately */ | ||
1202 | gens = a->name.fullname; | ||
1203 | nm = b->dpname; | ||
1204 | } | ||
1205 | |||
1206 | /* Handle case 2 with one GENERAL_NAMES and one X509_NAME */ | ||
1207 | if (nm) | ||
1208 | { | ||
1209 | for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) | ||
1210 | { | ||
1211 | gena = sk_GENERAL_NAME_value(gens, i); | ||
1212 | if (gena->type != GEN_DIRNAME) | ||
1213 | continue; | ||
1214 | if (!X509_NAME_cmp(nm, gena->d.directoryName)) | ||
1215 | return 1; | ||
1216 | } | ||
1217 | return 0; | ||
1218 | } | ||
1219 | |||
1220 | /* Else case 3: two GENERAL_NAMES */ | ||
1221 | |||
1222 | for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++) | ||
1223 | { | ||
1224 | gena = sk_GENERAL_NAME_value(a->name.fullname, i); | ||
1225 | for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++) | ||
1226 | { | ||
1227 | genb = sk_GENERAL_NAME_value(b->name.fullname, j); | ||
1228 | if (!GENERAL_NAME_cmp(gena, genb)) | ||
1229 | return 1; | ||
1230 | } | ||
1231 | } | ||
1232 | |||
1233 | return 0; | ||
1234 | |||
1235 | } | ||
1236 | |||
1237 | static int crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score) | ||
1238 | { | ||
1239 | int i; | ||
1240 | X509_NAME *nm = X509_CRL_get_issuer(crl); | ||
1241 | /* If no CRLissuer return is successful iff don't need a match */ | ||
1242 | if (!dp->CRLissuer) | ||
1243 | return !!(crl_score & CRL_SCORE_ISSUER_NAME); | ||
1244 | for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) | ||
1245 | { | ||
1246 | GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); | ||
1247 | if (gen->type != GEN_DIRNAME) | ||
1248 | continue; | ||
1249 | if (!X509_NAME_cmp(gen->d.directoryName, nm)) | ||
1250 | return 1; | ||
1251 | } | ||
1252 | return 0; | ||
1253 | } | ||
1254 | |||
1255 | /* Check CRLDP and IDP */ | ||
1256 | |||
1257 | static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, | ||
1258 | unsigned int *preasons) | ||
1259 | { | ||
1260 | int i; | ||
1261 | if (crl->idp_flags & IDP_ONLYATTR) | ||
1262 | return 0; | ||
1263 | if (x->ex_flags & EXFLAG_CA) | ||
1264 | { | ||
1265 | if (crl->idp_flags & IDP_ONLYUSER) | ||
1266 | return 0; | ||
1267 | } | ||
1268 | else | ||
1269 | { | ||
1270 | if (crl->idp_flags & IDP_ONLYCA) | ||
1271 | return 0; | ||
1272 | } | ||
1273 | *preasons = crl->idp_reasons; | ||
1274 | for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) | ||
1275 | { | ||
1276 | DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i); | ||
1277 | if (crldp_check_crlissuer(dp, crl, crl_score)) | ||
1278 | { | ||
1279 | if (!crl->idp || | ||
1280 | idp_check_dp(dp->distpoint, crl->idp->distpoint)) | ||
1281 | { | ||
1282 | *preasons &= dp->dp_reasons; | ||
1283 | return 1; | ||
1284 | } | ||
1285 | } | ||
1286 | } | ||
1287 | if ((!crl->idp || !crl->idp->distpoint) && (crl_score & CRL_SCORE_ISSUER_NAME)) | ||
1288 | return 1; | ||
1289 | return 0; | ||
1290 | } | ||
1291 | |||
1292 | /* Retrieve CRL corresponding to current certificate. | ||
1293 | * If deltas enabled try to find a delta CRL too | ||
1294 | */ | ||
1295 | |||
1296 | static int get_crl_delta(X509_STORE_CTX *ctx, | ||
1297 | X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x) | ||
1298 | { | ||
1299 | int ok; | ||
1300 | X509 *issuer = NULL; | ||
1301 | int crl_score = 0; | ||
1302 | unsigned int reasons; | ||
1303 | X509_CRL *crl = NULL, *dcrl = NULL; | ||
1304 | STACK_OF(X509_CRL) *skcrl; | ||
1305 | X509_NAME *nm = X509_get_issuer_name(x); | ||
1306 | reasons = ctx->current_reasons; | ||
1307 | ok = get_crl_sk(ctx, &crl, &dcrl, | ||
1308 | &issuer, &crl_score, &reasons, ctx->crls); | ||
1309 | |||
1310 | if (ok) | ||
1311 | goto done; | ||
1312 | |||
1313 | /* Lookup CRLs from store */ | ||
1314 | |||
1315 | skcrl = ctx->lookup_crls(ctx, nm); | ||
1316 | |||
1317 | /* If no CRLs found and a near match from get_crl_sk use that */ | ||
1318 | if (!skcrl && crl) | ||
1319 | goto done; | ||
1320 | |||
1321 | get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl); | ||
1322 | |||
1323 | sk_X509_CRL_pop_free(skcrl, X509_CRL_free); | ||
1324 | |||
1325 | done: | ||
1326 | |||
1327 | /* If we got any kind of CRL use it and return success */ | ||
1328 | if (crl) | ||
1329 | { | ||
1330 | ctx->current_issuer = issuer; | ||
1331 | ctx->current_crl_score = crl_score; | ||
1332 | ctx->current_reasons = reasons; | ||
1333 | *pcrl = crl; | ||
1334 | *pdcrl = dcrl; | ||
1335 | return 1; | ||
1336 | } | ||
1337 | |||
1338 | return 0; | ||
1339 | } | ||
1340 | |||
1341 | /* Check CRL validity */ | ||
1342 | static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) | ||
1343 | { | ||
1344 | X509 *issuer = NULL; | ||
1345 | EVP_PKEY *ikey = NULL; | ||
1346 | int ok = 0, chnum, cnum; | ||
1347 | cnum = ctx->error_depth; | ||
1348 | chnum = sk_X509_num(ctx->chain) - 1; | ||
1349 | /* if we have an alternative CRL issuer cert use that */ | ||
1350 | if (ctx->current_issuer) | ||
1351 | issuer = ctx->current_issuer; | ||
1352 | |||
1353 | /* Else find CRL issuer: if not last certificate then issuer | ||
1354 | * is next certificate in chain. | ||
1355 | */ | ||
1356 | else if (cnum < chnum) | ||
1357 | issuer = sk_X509_value(ctx->chain, cnum + 1); | ||
1358 | else | ||
1359 | { | ||
1360 | issuer = sk_X509_value(ctx->chain, chnum); | ||
1361 | /* If not self signed, can't check signature */ | ||
1362 | if(!ctx->check_issued(ctx, issuer, issuer)) | ||
1363 | { | ||
1364 | ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER; | ||
1365 | ok = ctx->verify_cb(0, ctx); | ||
1366 | if(!ok) goto err; | ||
1367 | } | ||
1368 | } | ||
1369 | |||
1370 | if(issuer) | ||
1371 | { | ||
1372 | /* Skip most tests for deltas because they have already | ||
1373 | * been done | ||
1374 | */ | ||
1375 | if (!crl->base_crl_number) | ||
1376 | { | ||
1377 | /* Check for cRLSign bit if keyUsage present */ | ||
1378 | if ((issuer->ex_flags & EXFLAG_KUSAGE) && | ||
1379 | !(issuer->ex_kusage & KU_CRL_SIGN)) | ||
1380 | { | ||
1381 | ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN; | ||
1382 | ok = ctx->verify_cb(0, ctx); | ||
1383 | if(!ok) goto err; | ||
1384 | } | ||
1385 | |||
1386 | if (!(ctx->current_crl_score & CRL_SCORE_SCOPE)) | ||
1387 | { | ||
1388 | ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE; | ||
1389 | ok = ctx->verify_cb(0, ctx); | ||
1390 | if(!ok) goto err; | ||
1391 | } | ||
1392 | |||
1393 | if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH)) | ||
1394 | { | ||
1395 | if (check_crl_path(ctx, ctx->current_issuer) <= 0) | ||
1396 | { | ||
1397 | ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR; | ||
1398 | ok = ctx->verify_cb(0, ctx); | ||
1399 | if(!ok) goto err; | ||
1400 | } | ||
1401 | } | ||
1402 | |||
1403 | if (crl->idp_flags & IDP_INVALID) | ||
1404 | { | ||
1405 | ctx->error = X509_V_ERR_INVALID_EXTENSION; | ||
1406 | ok = ctx->verify_cb(0, ctx); | ||
1407 | if(!ok) goto err; | ||
1408 | } | ||
1409 | |||
1410 | |||
1411 | } | ||
1412 | |||
1413 | if (!(ctx->current_crl_score & CRL_SCORE_TIME)) | ||
1414 | { | ||
1415 | ok = check_crl_time(ctx, crl, 1); | ||
1416 | if (!ok) | ||
1417 | goto err; | ||
1418 | } | ||
1419 | |||
1420 | /* Attempt to get issuer certificate public key */ | ||
1421 | ikey = X509_get_pubkey(issuer); | ||
1422 | |||
1423 | if(!ikey) | ||
1424 | { | ||
1425 | ctx->error=X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; | ||
1426 | ok = ctx->verify_cb(0, ctx); | ||
1427 | if (!ok) goto err; | ||
1428 | } | ||
1429 | else | ||
1430 | { | ||
1431 | /* Verify CRL signature */ | ||
1432 | if(X509_CRL_verify(crl, ikey) <= 0) | ||
1433 | { | ||
1434 | ctx->error=X509_V_ERR_CRL_SIGNATURE_FAILURE; | ||
1435 | ok = ctx->verify_cb(0, ctx); | ||
1436 | if (!ok) goto err; | ||
1437 | } | ||
1438 | } | ||
1439 | } | ||
1440 | |||
1441 | ok = 1; | ||
1442 | |||
1443 | err: | ||
1444 | EVP_PKEY_free(ikey); | ||
1445 | return ok; | ||
1446 | } | ||
1447 | |||
1448 | /* Check certificate against CRL */ | ||
1449 | static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) | ||
1450 | { | ||
1451 | int ok; | ||
1452 | X509_REVOKED *rev; | ||
1453 | /* The rules changed for this... previously if a CRL contained | ||
1454 | * unhandled critical extensions it could still be used to indicate | ||
1455 | * a certificate was revoked. This has since been changed since | ||
1456 | * critical extension can change the meaning of CRL entries. | ||
1457 | */ | ||
1458 | if (crl->flags & EXFLAG_CRITICAL) | ||
1459 | { | ||
1460 | if (ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) | ||
1461 | return 1; | ||
1462 | ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION; | ||
1463 | ok = ctx->verify_cb(0, ctx); | ||
1464 | if(!ok) | ||
1465 | return 0; | ||
1466 | } | ||
1467 | /* Look for serial number of certificate in CRL | ||
1468 | * If found make sure reason is not removeFromCRL. | ||
1469 | */ | ||
1470 | if (X509_CRL_get0_by_cert(crl, &rev, x)) | ||
1471 | { | ||
1472 | if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) | ||
1473 | return 2; | ||
1474 | ctx->error = X509_V_ERR_CERT_REVOKED; | ||
1475 | ok = ctx->verify_cb(0, ctx); | ||
1476 | if (!ok) | ||
1477 | return 0; | ||
1478 | } | ||
1479 | |||
1480 | return 1; | ||
1481 | } | ||
1482 | |||
1483 | static int check_policy(X509_STORE_CTX *ctx) | ||
1484 | { | ||
1485 | int ret; | ||
1486 | if (ctx->parent) | ||
1487 | return 1; | ||
1488 | ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain, | ||
1489 | ctx->param->policies, ctx->param->flags); | ||
1490 | if (ret == 0) | ||
1491 | { | ||
1492 | X509err(X509_F_CHECK_POLICY,ERR_R_MALLOC_FAILURE); | ||
1493 | return 0; | ||
1494 | } | ||
1495 | /* Invalid or inconsistent extensions */ | ||
1496 | if (ret == -1) | ||
1497 | { | ||
1498 | /* Locate certificates with bad extensions and notify | ||
1499 | * callback. | ||
1500 | */ | ||
1501 | X509 *x; | ||
1502 | int i; | ||
1503 | for (i = 1; i < sk_X509_num(ctx->chain); i++) | ||
1504 | { | ||
1505 | x = sk_X509_value(ctx->chain, i); | ||
1506 | if (!(x->ex_flags & EXFLAG_INVALID_POLICY)) | ||
1507 | continue; | ||
1508 | ctx->current_cert = x; | ||
1509 | ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION; | ||
1510 | if(!ctx->verify_cb(0, ctx)) | ||
1511 | return 0; | ||
1512 | } | ||
1513 | return 1; | ||
1514 | } | ||
1515 | if (ret == -2) | ||
1516 | { | ||
1517 | ctx->current_cert = NULL; | ||
1518 | ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY; | ||
1519 | return ctx->verify_cb(0, ctx); | ||
1520 | } | ||
1521 | |||
1522 | if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) | ||
1523 | { | ||
1524 | ctx->current_cert = NULL; | ||
1525 | ctx->error = X509_V_OK; | ||
1526 | if (!ctx->verify_cb(2, ctx)) | ||
1527 | return 0; | ||
1528 | } | ||
1529 | |||
1530 | return 1; | ||
1531 | } | ||
1532 | |||
1533 | static int check_cert_time(X509_STORE_CTX *ctx, X509 *x) | ||
1534 | { | ||
1535 | time_t *ptime; | ||
1536 | int i; | ||
1537 | |||
1538 | if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) | ||
1539 | ptime = &ctx->param->check_time; | ||
1540 | else | ||
1541 | ptime = NULL; | ||
1542 | |||
1543 | i=X509_cmp_time(X509_get_notBefore(x), ptime); | ||
1544 | if (i == 0) | ||
1545 | { | ||
1546 | ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; | ||
1547 | ctx->current_cert=x; | ||
1548 | if (!ctx->verify_cb(0, ctx)) | ||
1549 | return 0; | ||
1550 | } | ||
1551 | |||
1552 | if (i > 0) | ||
1553 | { | ||
1554 | ctx->error=X509_V_ERR_CERT_NOT_YET_VALID; | ||
1555 | ctx->current_cert=x; | ||
1556 | if (!ctx->verify_cb(0, ctx)) | ||
1557 | return 0; | ||
1558 | } | ||
1559 | |||
1560 | i=X509_cmp_time(X509_get_notAfter(x), ptime); | ||
1561 | if (i == 0) | ||
1562 | { | ||
1563 | ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD; | ||
1564 | ctx->current_cert=x; | ||
1565 | if (!ctx->verify_cb(0, ctx)) | ||
1566 | return 0; | ||
1567 | } | ||
1568 | |||
1569 | if (i < 0) | ||
1570 | { | ||
1571 | ctx->error=X509_V_ERR_CERT_HAS_EXPIRED; | ||
1572 | ctx->current_cert=x; | ||
1573 | if (!ctx->verify_cb(0, ctx)) | ||
1574 | return 0; | ||
1575 | } | ||
1576 | |||
1577 | return 1; | ||
1578 | } | ||
1579 | |||
1580 | static int internal_verify(X509_STORE_CTX *ctx) | ||
1581 | { | ||
1582 | int ok=0,n; | ||
1583 | X509 *xs,*xi; | ||
1584 | EVP_PKEY *pkey=NULL; | ||
1585 | int (*cb)(int xok,X509_STORE_CTX *xctx); | ||
1586 | |||
1587 | cb=ctx->verify_cb; | ||
1588 | |||
1589 | n=sk_X509_num(ctx->chain); | ||
1590 | ctx->error_depth=n-1; | ||
1591 | n--; | ||
1592 | xi=sk_X509_value(ctx->chain,n); | ||
1593 | |||
1594 | if (ctx->check_issued(ctx, xi, xi)) | ||
1595 | xs=xi; | ||
1596 | else | ||
1597 | { | ||
1598 | if (n <= 0) | ||
1599 | { | ||
1600 | ctx->error=X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE; | ||
1601 | ctx->current_cert=xi; | ||
1602 | ok=cb(0,ctx); | ||
1603 | goto end; | ||
1604 | } | ||
1605 | else | ||
1606 | { | ||
1607 | n--; | ||
1608 | ctx->error_depth=n; | ||
1609 | xs=sk_X509_value(ctx->chain,n); | ||
1610 | } | ||
1611 | } | ||
1612 | |||
1613 | /* ctx->error=0; not needed */ | ||
1614 | while (n >= 0) | ||
1615 | { | ||
1616 | ctx->error_depth=n; | ||
1617 | |||
1618 | /* Skip signature check for self signed certificates unless | ||
1619 | * explicitly asked for. It doesn't add any security and | ||
1620 | * just wastes time. | ||
1621 | */ | ||
1622 | if (!xs->valid && (xs != xi || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE))) | ||
1623 | { | ||
1624 | if ((pkey=X509_get_pubkey(xi)) == NULL) | ||
1625 | { | ||
1626 | ctx->error=X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; | ||
1627 | ctx->current_cert=xi; | ||
1628 | ok=(*cb)(0,ctx); | ||
1629 | if (!ok) goto end; | ||
1630 | } | ||
1631 | else if (X509_verify(xs,pkey) <= 0) | ||
1632 | { | ||
1633 | ctx->error=X509_V_ERR_CERT_SIGNATURE_FAILURE; | ||
1634 | ctx->current_cert=xs; | ||
1635 | ok=(*cb)(0,ctx); | ||
1636 | if (!ok) | ||
1637 | { | ||
1638 | EVP_PKEY_free(pkey); | ||
1639 | goto end; | ||
1640 | } | ||
1641 | } | ||
1642 | EVP_PKEY_free(pkey); | ||
1643 | pkey=NULL; | ||
1644 | } | ||
1645 | |||
1646 | xs->valid = 1; | ||
1647 | |||
1648 | ok = check_cert_time(ctx, xs); | ||
1649 | if (!ok) | ||
1650 | goto end; | ||
1651 | |||
1652 | /* The last error (if any) is still in the error value */ | ||
1653 | ctx->current_issuer=xi; | ||
1654 | ctx->current_cert=xs; | ||
1655 | ok=(*cb)(1,ctx); | ||
1656 | if (!ok) goto end; | ||
1657 | |||
1658 | n--; | ||
1659 | if (n >= 0) | ||
1660 | { | ||
1661 | xi=xs; | ||
1662 | xs=sk_X509_value(ctx->chain,n); | ||
1663 | } | ||
1664 | } | ||
1665 | ok=1; | ||
1666 | end: | ||
1667 | return ok; | ||
1668 | } | ||
1669 | |||
1670 | int X509_cmp_current_time(const ASN1_TIME *ctm) | ||
1671 | { | ||
1672 | return X509_cmp_time(ctm, NULL); | ||
1673 | } | ||
1674 | |||
1675 | int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) | ||
1676 | { | ||
1677 | char *str; | ||
1678 | ASN1_TIME atm; | ||
1679 | long offset; | ||
1680 | char buff1[24],buff2[24],*p; | ||
1681 | int i,j; | ||
1682 | |||
1683 | p=buff1; | ||
1684 | i=ctm->length; | ||
1685 | str=(char *)ctm->data; | ||
1686 | if (ctm->type == V_ASN1_UTCTIME) | ||
1687 | { | ||
1688 | if ((i < 11) || (i > 17)) return 0; | ||
1689 | memcpy(p,str,10); | ||
1690 | p+=10; | ||
1691 | str+=10; | ||
1692 | } | ||
1693 | else | ||
1694 | { | ||
1695 | if (i < 13) return 0; | ||
1696 | memcpy(p,str,12); | ||
1697 | p+=12; | ||
1698 | str+=12; | ||
1699 | } | ||
1700 | |||
1701 | if ((*str == 'Z') || (*str == '-') || (*str == '+')) | ||
1702 | { *(p++)='0'; *(p++)='0'; } | ||
1703 | else | ||
1704 | { | ||
1705 | *(p++)= *(str++); | ||
1706 | *(p++)= *(str++); | ||
1707 | /* Skip any fractional seconds... */ | ||
1708 | if (*str == '.') | ||
1709 | { | ||
1710 | str++; | ||
1711 | while ((*str >= '0') && (*str <= '9')) str++; | ||
1712 | } | ||
1713 | |||
1714 | } | ||
1715 | *(p++)='Z'; | ||
1716 | *(p++)='\0'; | ||
1717 | |||
1718 | if (*str == 'Z') | ||
1719 | offset=0; | ||
1720 | else | ||
1721 | { | ||
1722 | if ((*str != '+') && (*str != '-')) | ||
1723 | return 0; | ||
1724 | offset=((str[1]-'0')*10+(str[2]-'0'))*60; | ||
1725 | offset+=(str[3]-'0')*10+(str[4]-'0'); | ||
1726 | if (*str == '-') | ||
1727 | offset= -offset; | ||
1728 | } | ||
1729 | atm.type=ctm->type; | ||
1730 | atm.flags = 0; | ||
1731 | atm.length=sizeof(buff2); | ||
1732 | atm.data=(unsigned char *)buff2; | ||
1733 | |||
1734 | if (X509_time_adj(&atm,-offset*60, cmp_time) == NULL) | ||
1735 | return 0; | ||
1736 | |||
1737 | if (ctm->type == V_ASN1_UTCTIME) | ||
1738 | { | ||
1739 | i=(buff1[0]-'0')*10+(buff1[1]-'0'); | ||
1740 | if (i < 50) i+=100; /* cf. RFC 2459 */ | ||
1741 | j=(buff2[0]-'0')*10+(buff2[1]-'0'); | ||
1742 | if (j < 50) j+=100; | ||
1743 | |||
1744 | if (i < j) return -1; | ||
1745 | if (i > j) return 1; | ||
1746 | } | ||
1747 | i=strcmp(buff1,buff2); | ||
1748 | if (i == 0) /* wait a second then return younger :-) */ | ||
1749 | return -1; | ||
1750 | else | ||
1751 | return i; | ||
1752 | } | ||
1753 | |||
1754 | ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj) | ||
1755 | { | ||
1756 | return X509_time_adj(s, adj, NULL); | ||
1757 | } | ||
1758 | |||
1759 | ASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_tm) | ||
1760 | { | ||
1761 | return X509_time_adj_ex(s, 0, offset_sec, in_tm); | ||
1762 | } | ||
1763 | |||
1764 | ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s, | ||
1765 | int offset_day, long offset_sec, time_t *in_tm) | ||
1766 | { | ||
1767 | time_t t; | ||
1768 | |||
1769 | if (in_tm) t = *in_tm; | ||
1770 | else time(&t); | ||
1771 | |||
1772 | if (s && !(s->flags & ASN1_STRING_FLAG_MSTRING)) | ||
1773 | { | ||
1774 | if (s->type == V_ASN1_UTCTIME) | ||
1775 | return ASN1_UTCTIME_adj(s,t, offset_day, offset_sec); | ||
1776 | if (s->type == V_ASN1_GENERALIZEDTIME) | ||
1777 | return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, | ||
1778 | offset_sec); | ||
1779 | } | ||
1780 | return ASN1_TIME_adj(s, t, offset_day, offset_sec); | ||
1781 | } | ||
1782 | |||
1783 | int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain) | ||
1784 | { | ||
1785 | EVP_PKEY *ktmp=NULL,*ktmp2; | ||
1786 | int i,j; | ||
1787 | |||
1788 | if ((pkey != NULL) && !EVP_PKEY_missing_parameters(pkey)) return 1; | ||
1789 | |||
1790 | for (i=0; i<sk_X509_num(chain); i++) | ||
1791 | { | ||
1792 | ktmp=X509_get_pubkey(sk_X509_value(chain,i)); | ||
1793 | if (ktmp == NULL) | ||
1794 | { | ||
1795 | X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY); | ||
1796 | return 0; | ||
1797 | } | ||
1798 | if (!EVP_PKEY_missing_parameters(ktmp)) | ||
1799 | break; | ||
1800 | else | ||
1801 | { | ||
1802 | EVP_PKEY_free(ktmp); | ||
1803 | ktmp=NULL; | ||
1804 | } | ||
1805 | } | ||
1806 | if (ktmp == NULL) | ||
1807 | { | ||
1808 | X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN); | ||
1809 | return 0; | ||
1810 | } | ||
1811 | |||
1812 | /* first, populate the other certs */ | ||
1813 | for (j=i-1; j >= 0; j--) | ||
1814 | { | ||
1815 | ktmp2=X509_get_pubkey(sk_X509_value(chain,j)); | ||
1816 | EVP_PKEY_copy_parameters(ktmp2,ktmp); | ||
1817 | EVP_PKEY_free(ktmp2); | ||
1818 | } | ||
1819 | |||
1820 | if (pkey != NULL) EVP_PKEY_copy_parameters(pkey,ktmp); | ||
1821 | EVP_PKEY_free(ktmp); | ||
1822 | return 1; | ||
1823 | } | ||
1824 | |||
1825 | int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, | ||
1826 | CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) | ||
1827 | { | ||
1828 | /* This function is (usually) called only once, by | ||
1829 | * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c). */ | ||
1830 | return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, argl, argp, | ||
1831 | new_func, dup_func, free_func); | ||
1832 | } | ||
1833 | |||
1834 | int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data) | ||
1835 | { | ||
1836 | return CRYPTO_set_ex_data(&ctx->ex_data,idx,data); | ||
1837 | } | ||
1838 | |||
1839 | void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx) | ||
1840 | { | ||
1841 | return CRYPTO_get_ex_data(&ctx->ex_data,idx); | ||
1842 | } | ||
1843 | |||
1844 | int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx) | ||
1845 | { | ||
1846 | return ctx->error; | ||
1847 | } | ||
1848 | |||
1849 | void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err) | ||
1850 | { | ||
1851 | ctx->error=err; | ||
1852 | } | ||
1853 | |||
1854 | int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx) | ||
1855 | { | ||
1856 | return ctx->error_depth; | ||
1857 | } | ||
1858 | |||
1859 | X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx) | ||
1860 | { | ||
1861 | return ctx->current_cert; | ||
1862 | } | ||
1863 | |||
1864 | STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx) | ||
1865 | { | ||
1866 | return ctx->chain; | ||
1867 | } | ||
1868 | |||
1869 | STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx) | ||
1870 | { | ||
1871 | int i; | ||
1872 | X509 *x; | ||
1873 | STACK_OF(X509) *chain; | ||
1874 | if (!ctx->chain || !(chain = sk_X509_dup(ctx->chain))) return NULL; | ||
1875 | for (i = 0; i < sk_X509_num(chain); i++) | ||
1876 | { | ||
1877 | x = sk_X509_value(chain, i); | ||
1878 | CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); | ||
1879 | } | ||
1880 | return chain; | ||
1881 | } | ||
1882 | |||
1883 | X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx) | ||
1884 | { | ||
1885 | return ctx->current_issuer; | ||
1886 | } | ||
1887 | |||
1888 | X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx) | ||
1889 | { | ||
1890 | return ctx->current_crl; | ||
1891 | } | ||
1892 | |||
1893 | X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx) | ||
1894 | { | ||
1895 | return ctx->parent; | ||
1896 | } | ||
1897 | |||
1898 | void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x) | ||
1899 | { | ||
1900 | ctx->cert=x; | ||
1901 | } | ||
1902 | |||
1903 | void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) | ||
1904 | { | ||
1905 | ctx->untrusted=sk; | ||
1906 | } | ||
1907 | |||
1908 | void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk) | ||
1909 | { | ||
1910 | ctx->crls=sk; | ||
1911 | } | ||
1912 | |||
1913 | int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose) | ||
1914 | { | ||
1915 | return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0); | ||
1916 | } | ||
1917 | |||
1918 | int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust) | ||
1919 | { | ||
1920 | return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust); | ||
1921 | } | ||
1922 | |||
1923 | /* This function is used to set the X509_STORE_CTX purpose and trust | ||
1924 | * values. This is intended to be used when another structure has its | ||
1925 | * own trust and purpose values which (if set) will be inherited by | ||
1926 | * the ctx. If they aren't set then we will usually have a default | ||
1927 | * purpose in mind which should then be used to set the trust value. | ||
1928 | * An example of this is SSL use: an SSL structure will have its own | ||
1929 | * purpose and trust settings which the application can set: if they | ||
1930 | * aren't set then we use the default of SSL client/server. | ||
1931 | */ | ||
1932 | |||
1933 | int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, | ||
1934 | int purpose, int trust) | ||
1935 | { | ||
1936 | int idx; | ||
1937 | /* If purpose not set use default */ | ||
1938 | if (!purpose) purpose = def_purpose; | ||
1939 | /* If we have a purpose then check it is valid */ | ||
1940 | if (purpose) | ||
1941 | { | ||
1942 | X509_PURPOSE *ptmp; | ||
1943 | idx = X509_PURPOSE_get_by_id(purpose); | ||
1944 | if (idx == -1) | ||
1945 | { | ||
1946 | X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, | ||
1947 | X509_R_UNKNOWN_PURPOSE_ID); | ||
1948 | return 0; | ||
1949 | } | ||
1950 | ptmp = X509_PURPOSE_get0(idx); | ||
1951 | if (ptmp->trust == X509_TRUST_DEFAULT) | ||
1952 | { | ||
1953 | idx = X509_PURPOSE_get_by_id(def_purpose); | ||
1954 | if (idx == -1) | ||
1955 | { | ||
1956 | X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, | ||
1957 | X509_R_UNKNOWN_PURPOSE_ID); | ||
1958 | return 0; | ||
1959 | } | ||
1960 | ptmp = X509_PURPOSE_get0(idx); | ||
1961 | } | ||
1962 | /* If trust not set then get from purpose default */ | ||
1963 | if (!trust) trust = ptmp->trust; | ||
1964 | } | ||
1965 | if (trust) | ||
1966 | { | ||
1967 | idx = X509_TRUST_get_by_id(trust); | ||
1968 | if (idx == -1) | ||
1969 | { | ||
1970 | X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, | ||
1971 | X509_R_UNKNOWN_TRUST_ID); | ||
1972 | return 0; | ||
1973 | } | ||
1974 | } | ||
1975 | |||
1976 | if (purpose && !ctx->param->purpose) ctx->param->purpose = purpose; | ||
1977 | if (trust && !ctx->param->trust) ctx->param->trust = trust; | ||
1978 | return 1; | ||
1979 | } | ||
1980 | |||
1981 | X509_STORE_CTX *X509_STORE_CTX_new(void) | ||
1982 | { | ||
1983 | X509_STORE_CTX *ctx; | ||
1984 | ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX)); | ||
1985 | if (!ctx) | ||
1986 | { | ||
1987 | X509err(X509_F_X509_STORE_CTX_NEW,ERR_R_MALLOC_FAILURE); | ||
1988 | return NULL; | ||
1989 | } | ||
1990 | memset(ctx, 0, sizeof(X509_STORE_CTX)); | ||
1991 | return ctx; | ||
1992 | } | ||
1993 | |||
1994 | void X509_STORE_CTX_free(X509_STORE_CTX *ctx) | ||
1995 | { | ||
1996 | X509_STORE_CTX_cleanup(ctx); | ||
1997 | OPENSSL_free(ctx); | ||
1998 | } | ||
1999 | |||
2000 | int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, | ||
2001 | STACK_OF(X509) *chain) | ||
2002 | { | ||
2003 | int ret = 1; | ||
2004 | ctx->ctx=store; | ||
2005 | ctx->current_method=0; | ||
2006 | ctx->cert=x509; | ||
2007 | ctx->untrusted=chain; | ||
2008 | ctx->crls = NULL; | ||
2009 | ctx->last_untrusted=0; | ||
2010 | ctx->other_ctx=NULL; | ||
2011 | ctx->valid=0; | ||
2012 | ctx->chain=NULL; | ||
2013 | ctx->error=0; | ||
2014 | ctx->explicit_policy=0; | ||
2015 | ctx->error_depth=0; | ||
2016 | ctx->current_cert=NULL; | ||
2017 | ctx->current_issuer=NULL; | ||
2018 | ctx->tree = NULL; | ||
2019 | ctx->parent = NULL; | ||
2020 | |||
2021 | ctx->param = X509_VERIFY_PARAM_new(); | ||
2022 | |||
2023 | if (!ctx->param) | ||
2024 | { | ||
2025 | X509err(X509_F_X509_STORE_CTX_INIT,ERR_R_MALLOC_FAILURE); | ||
2026 | return 0; | ||
2027 | } | ||
2028 | |||
2029 | /* Inherit callbacks and flags from X509_STORE if not set | ||
2030 | * use defaults. | ||
2031 | */ | ||
2032 | |||
2033 | |||
2034 | if (store) | ||
2035 | ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param); | ||
2036 | else | ||
2037 | ctx->param->flags |= X509_VP_FLAG_DEFAULT|X509_VP_FLAG_ONCE; | ||
2038 | |||
2039 | if (store) | ||
2040 | { | ||
2041 | ctx->verify_cb = store->verify_cb; | ||
2042 | ctx->cleanup = store->cleanup; | ||
2043 | } | ||
2044 | else | ||
2045 | ctx->cleanup = 0; | ||
2046 | |||
2047 | if (ret) | ||
2048 | ret = X509_VERIFY_PARAM_inherit(ctx->param, | ||
2049 | X509_VERIFY_PARAM_lookup("default")); | ||
2050 | |||
2051 | if (ret == 0) | ||
2052 | { | ||
2053 | X509err(X509_F_X509_STORE_CTX_INIT,ERR_R_MALLOC_FAILURE); | ||
2054 | return 0; | ||
2055 | } | ||
2056 | |||
2057 | if (store && store->check_issued) | ||
2058 | ctx->check_issued = store->check_issued; | ||
2059 | else | ||
2060 | ctx->check_issued = check_issued; | ||
2061 | |||
2062 | if (store && store->get_issuer) | ||
2063 | ctx->get_issuer = store->get_issuer; | ||
2064 | else | ||
2065 | ctx->get_issuer = X509_STORE_CTX_get1_issuer; | ||
2066 | |||
2067 | if (store && store->verify_cb) | ||
2068 | ctx->verify_cb = store->verify_cb; | ||
2069 | else | ||
2070 | ctx->verify_cb = null_callback; | ||
2071 | |||
2072 | if (store && store->verify) | ||
2073 | ctx->verify = store->verify; | ||
2074 | else | ||
2075 | ctx->verify = internal_verify; | ||
2076 | |||
2077 | if (store && store->check_revocation) | ||
2078 | ctx->check_revocation = store->check_revocation; | ||
2079 | else | ||
2080 | ctx->check_revocation = check_revocation; | ||
2081 | |||
2082 | if (store && store->get_crl) | ||
2083 | ctx->get_crl = store->get_crl; | ||
2084 | else | ||
2085 | ctx->get_crl = NULL; | ||
2086 | |||
2087 | if (store && store->check_crl) | ||
2088 | ctx->check_crl = store->check_crl; | ||
2089 | else | ||
2090 | ctx->check_crl = check_crl; | ||
2091 | |||
2092 | if (store && store->cert_crl) | ||
2093 | ctx->cert_crl = store->cert_crl; | ||
2094 | else | ||
2095 | ctx->cert_crl = cert_crl; | ||
2096 | |||
2097 | if (store && store->lookup_certs) | ||
2098 | ctx->lookup_certs = store->lookup_certs; | ||
2099 | else | ||
2100 | ctx->lookup_certs = X509_STORE_get1_certs; | ||
2101 | |||
2102 | if (store && store->lookup_crls) | ||
2103 | ctx->lookup_crls = store->lookup_crls; | ||
2104 | else | ||
2105 | ctx->lookup_crls = X509_STORE_get1_crls; | ||
2106 | |||
2107 | ctx->check_policy = check_policy; | ||
2108 | |||
2109 | |||
2110 | /* This memset() can't make any sense anyway, so it's removed. As | ||
2111 | * X509_STORE_CTX_cleanup does a proper "free" on the ex_data, we put a | ||
2112 | * corresponding "new" here and remove this bogus initialisation. */ | ||
2113 | /* memset(&(ctx->ex_data),0,sizeof(CRYPTO_EX_DATA)); */ | ||
2114 | if(!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, | ||
2115 | &(ctx->ex_data))) | ||
2116 | { | ||
2117 | OPENSSL_free(ctx); | ||
2118 | X509err(X509_F_X509_STORE_CTX_INIT,ERR_R_MALLOC_FAILURE); | ||
2119 | return 0; | ||
2120 | } | ||
2121 | return 1; | ||
2122 | } | ||
2123 | |||
2124 | /* Set alternative lookup method: just a STACK of trusted certificates. | ||
2125 | * This avoids X509_STORE nastiness where it isn't needed. | ||
2126 | */ | ||
2127 | |||
2128 | void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) | ||
2129 | { | ||
2130 | ctx->other_ctx = sk; | ||
2131 | ctx->get_issuer = get_issuer_sk; | ||
2132 | } | ||
2133 | |||
2134 | void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx) | ||
2135 | { | ||
2136 | if (ctx->cleanup) ctx->cleanup(ctx); | ||
2137 | if (ctx->param != NULL) | ||
2138 | { | ||
2139 | if (ctx->parent == NULL) | ||
2140 | X509_VERIFY_PARAM_free(ctx->param); | ||
2141 | ctx->param=NULL; | ||
2142 | } | ||
2143 | if (ctx->tree != NULL) | ||
2144 | { | ||
2145 | X509_policy_tree_free(ctx->tree); | ||
2146 | ctx->tree=NULL; | ||
2147 | } | ||
2148 | if (ctx->chain != NULL) | ||
2149 | { | ||
2150 | sk_X509_pop_free(ctx->chain,X509_free); | ||
2151 | ctx->chain=NULL; | ||
2152 | } | ||
2153 | CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, &(ctx->ex_data)); | ||
2154 | memset(&ctx->ex_data,0,sizeof(CRYPTO_EX_DATA)); | ||
2155 | } | ||
2156 | |||
2157 | void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth) | ||
2158 | { | ||
2159 | X509_VERIFY_PARAM_set_depth(ctx->param, depth); | ||
2160 | } | ||
2161 | |||
2162 | void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags) | ||
2163 | { | ||
2164 | X509_VERIFY_PARAM_set_flags(ctx->param, flags); | ||
2165 | } | ||
2166 | |||
2167 | void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, time_t t) | ||
2168 | { | ||
2169 | X509_VERIFY_PARAM_set_time(ctx->param, t); | ||
2170 | } | ||
2171 | |||
2172 | void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, | ||
2173 | int (*verify_cb)(int, X509_STORE_CTX *)) | ||
2174 | { | ||
2175 | ctx->verify_cb=verify_cb; | ||
2176 | } | ||
2177 | |||
2178 | X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx) | ||
2179 | { | ||
2180 | return ctx->tree; | ||
2181 | } | ||
2182 | |||
2183 | int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx) | ||
2184 | { | ||
2185 | return ctx->explicit_policy; | ||
2186 | } | ||
2187 | |||
2188 | int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name) | ||
2189 | { | ||
2190 | const X509_VERIFY_PARAM *param; | ||
2191 | param = X509_VERIFY_PARAM_lookup(name); | ||
2192 | if (!param) | ||
2193 | return 0; | ||
2194 | return X509_VERIFY_PARAM_inherit(ctx->param, param); | ||
2195 | } | ||
2196 | |||
2197 | X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx) | ||
2198 | { | ||
2199 | return ctx->param; | ||
2200 | } | ||
2201 | |||
2202 | void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param) | ||
2203 | { | ||
2204 | if (ctx->param) | ||
2205 | X509_VERIFY_PARAM_free(ctx->param); | ||
2206 | ctx->param = param; | ||
2207 | } | ||
2208 | |||
2209 | IMPLEMENT_STACK_OF(X509) | ||
2210 | IMPLEMENT_ASN1_SET_OF(X509) | ||
2211 | |||
2212 | IMPLEMENT_STACK_OF(X509_NAME) | ||
2213 | |||
2214 | IMPLEMENT_STACK_OF(X509_ATTRIBUTE) | ||
2215 | IMPLEMENT_ASN1_SET_OF(X509_ATTRIBUTE) | ||