diff options
Diffstat (limited to 'src/lib/libcrypto/x509/x509_vfy.c')
-rw-r--r-- | src/lib/libcrypto/x509/x509_vfy.c | 481 |
1 files changed, 348 insertions, 133 deletions
diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c index 383e082aba..9a62ebcf67 100644 --- a/src/lib/libcrypto/x509/x509_vfy.c +++ b/src/lib/libcrypto/x509/x509_vfy.c | |||
@@ -77,8 +77,9 @@ static int check_chain_extensions(X509_STORE_CTX *ctx); | |||
77 | static int check_trust(X509_STORE_CTX *ctx); | 77 | static int check_trust(X509_STORE_CTX *ctx); |
78 | static int check_revocation(X509_STORE_CTX *ctx); | 78 | static int check_revocation(X509_STORE_CTX *ctx); |
79 | static int check_cert(X509_STORE_CTX *ctx); | 79 | static int check_cert(X509_STORE_CTX *ctx); |
80 | static int check_policy(X509_STORE_CTX *ctx); | ||
80 | static int internal_verify(X509_STORE_CTX *ctx); | 81 | static int internal_verify(X509_STORE_CTX *ctx); |
81 | const char *X509_version="X.509" OPENSSL_VERSION_PTEXT; | 82 | const char X509_version[]="X.509" OPENSSL_VERSION_PTEXT; |
82 | 83 | ||
83 | 84 | ||
84 | static int null_callback(int ok, X509_STORE_CTX *e) | 85 | static int null_callback(int ok, X509_STORE_CTX *e) |
@@ -97,11 +98,12 @@ int X509_verify_cert(X509_STORE_CTX *ctx) | |||
97 | { | 98 | { |
98 | X509 *x,*xtmp,*chain_ss=NULL; | 99 | X509 *x,*xtmp,*chain_ss=NULL; |
99 | X509_NAME *xn; | 100 | X509_NAME *xn; |
101 | int bad_chain = 0; | ||
102 | X509_VERIFY_PARAM *param = ctx->param; | ||
100 | int depth,i,ok=0; | 103 | int depth,i,ok=0; |
101 | int num; | 104 | int num; |
102 | int (*cb)(); | 105 | int (*cb)(int xok,X509_STORE_CTX *xctx); |
103 | STACK_OF(X509) *sktmp=NULL; | 106 | STACK_OF(X509) *sktmp=NULL; |
104 | |||
105 | if (ctx->cert == NULL) | 107 | if (ctx->cert == NULL) |
106 | { | 108 | { |
107 | X509err(X509_F_X509_VERIFY_CERT,X509_R_NO_CERT_SET_FOR_US_TO_VERIFY); | 109 | X509err(X509_F_X509_VERIFY_CERT,X509_R_NO_CERT_SET_FOR_US_TO_VERIFY); |
@@ -134,7 +136,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx) | |||
134 | 136 | ||
135 | num=sk_X509_num(ctx->chain); | 137 | num=sk_X509_num(ctx->chain); |
136 | x=sk_X509_value(ctx->chain,num-1); | 138 | x=sk_X509_value(ctx->chain,num-1); |
137 | depth=ctx->depth; | 139 | depth=param->depth; |
138 | 140 | ||
139 | 141 | ||
140 | for (;;) | 142 | for (;;) |
@@ -162,7 +164,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx) | |||
162 | goto end; | 164 | goto end; |
163 | } | 165 | } |
164 | CRYPTO_add(&xtmp->references,1,CRYPTO_LOCK_X509); | 166 | CRYPTO_add(&xtmp->references,1,CRYPTO_LOCK_X509); |
165 | sk_X509_delete_ptr(sktmp,xtmp); | 167 | (void)sk_X509_delete_ptr(sktmp,xtmp); |
166 | ctx->last_untrusted++; | 168 | ctx->last_untrusted++; |
167 | x=xtmp; | 169 | x=xtmp; |
168 | num++; | 170 | num++; |
@@ -201,6 +203,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx) | |||
201 | ctx->current_cert=x; | 203 | ctx->current_cert=x; |
202 | ctx->error_depth=i-1; | 204 | ctx->error_depth=i-1; |
203 | if (ok == 1) X509_free(xtmp); | 205 | if (ok == 1) X509_free(xtmp); |
206 | bad_chain = 1; | ||
204 | ok=cb(0,ctx); | 207 | ok=cb(0,ctx); |
205 | if (!ok) goto end; | 208 | if (!ok) goto end; |
206 | } | 209 | } |
@@ -211,7 +214,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx) | |||
211 | */ | 214 | */ |
212 | X509_free(x); | 215 | X509_free(x); |
213 | x = xtmp; | 216 | x = xtmp; |
214 | sk_X509_set(ctx->chain, i - 1, x); | 217 | (void)sk_X509_set(ctx->chain, i - 1, x); |
215 | ctx->last_untrusted=0; | 218 | ctx->last_untrusted=0; |
216 | } | 219 | } |
217 | } | 220 | } |
@@ -276,6 +279,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx) | |||
276 | } | 279 | } |
277 | 280 | ||
278 | ctx->error_depth=num-1; | 281 | ctx->error_depth=num-1; |
282 | bad_chain = 1; | ||
279 | ok=cb(0,ctx); | 283 | ok=cb(0,ctx); |
280 | if (!ok) goto end; | 284 | if (!ok) goto end; |
281 | } | 285 | } |
@@ -287,7 +291,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx) | |||
287 | 291 | ||
288 | /* The chain extensions are OK: check trust */ | 292 | /* The chain extensions are OK: check trust */ |
289 | 293 | ||
290 | if (ctx->trust > 0) ok = check_trust(ctx); | 294 | if (param->trust > 0) ok = check_trust(ctx); |
291 | 295 | ||
292 | if (!ok) goto end; | 296 | if (!ok) goto end; |
293 | 297 | ||
@@ -301,11 +305,25 @@ int X509_verify_cert(X509_STORE_CTX *ctx) | |||
301 | ok = ctx->check_revocation(ctx); | 305 | ok = ctx->check_revocation(ctx); |
302 | if(!ok) goto end; | 306 | if(!ok) goto end; |
303 | 307 | ||
304 | /* At this point, we have a chain and just need to verify it */ | 308 | /* At this point, we have a chain and need to verify it */ |
305 | if (ctx->verify != NULL) | 309 | if (ctx->verify != NULL) |
306 | ok=ctx->verify(ctx); | 310 | ok=ctx->verify(ctx); |
307 | else | 311 | else |
308 | ok=internal_verify(ctx); | 312 | ok=internal_verify(ctx); |
313 | if(!ok) goto end; | ||
314 | |||
315 | #ifndef OPENSSL_NO_RFC3779 | ||
316 | /* RFC 3779 path validation, now that CRL check has been done */ | ||
317 | ok = v3_asid_validate_path(ctx); | ||
318 | if (!ok) goto end; | ||
319 | ok = v3_addr_validate_path(ctx); | ||
320 | if (!ok) goto end; | ||
321 | #endif | ||
322 | |||
323 | /* If we get this far evaluate policies */ | ||
324 | if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK)) | ||
325 | ok = ctx->check_policy(ctx); | ||
326 | if(!ok) goto end; | ||
309 | if (0) | 327 | if (0) |
310 | { | 328 | { |
311 | end: | 329 | end: |
@@ -342,7 +360,7 @@ static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer) | |||
342 | if (ret == X509_V_OK) | 360 | if (ret == X509_V_OK) |
343 | return 1; | 361 | return 1; |
344 | /* If we haven't asked for issuer errors don't set ctx */ | 362 | /* If we haven't asked for issuer errors don't set ctx */ |
345 | if (!(ctx->flags & X509_V_FLAG_CB_ISSUER_CHECK)) | 363 | if (!(ctx->param->flags & X509_V_FLAG_CB_ISSUER_CHECK)) |
346 | return 0; | 364 | return 0; |
347 | 365 | ||
348 | ctx->error = ret; | 366 | ctx->error = ret; |
@@ -365,7 +383,7 @@ static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) | |||
365 | else | 383 | else |
366 | return 0; | 384 | return 0; |
367 | } | 385 | } |
368 | 386 | ||
369 | 387 | ||
370 | /* Check a certificate chains extensions for consistency | 388 | /* Check a certificate chains extensions for consistency |
371 | * with the supplied purpose | 389 | * with the supplied purpose |
@@ -378,9 +396,10 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) | |||
378 | #else | 396 | #else |
379 | int i, ok=0, must_be_ca; | 397 | int i, ok=0, must_be_ca; |
380 | X509 *x; | 398 | X509 *x; |
381 | int (*cb)(); | 399 | int (*cb)(int xok,X509_STORE_CTX *xctx); |
382 | int proxy_path_length = 0; | 400 | int proxy_path_length = 0; |
383 | int allow_proxy_certs = !!(ctx->flags & X509_V_FLAG_ALLOW_PROXY_CERTS); | 401 | int allow_proxy_certs = |
402 | !!(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS); | ||
384 | cb=ctx->verify_cb; | 403 | cb=ctx->verify_cb; |
385 | 404 | ||
386 | /* must_be_ca can have 1 of 3 values: | 405 | /* must_be_ca can have 1 of 3 values: |
@@ -403,7 +422,7 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) | |||
403 | { | 422 | { |
404 | int ret; | 423 | int ret; |
405 | x = sk_X509_value(ctx->chain, i); | 424 | x = sk_X509_value(ctx->chain, i); |
406 | if (!(ctx->flags & X509_V_FLAG_IGNORE_CRITICAL) | 425 | if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) |
407 | && (x->ex_flags & EXFLAG_CRITICAL)) | 426 | && (x->ex_flags & EXFLAG_CRITICAL)) |
408 | { | 427 | { |
409 | ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION; | 428 | ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION; |
@@ -424,7 +443,7 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) | |||
424 | switch(must_be_ca) | 443 | switch(must_be_ca) |
425 | { | 444 | { |
426 | case -1: | 445 | case -1: |
427 | if ((ctx->flags & X509_V_FLAG_X509_STRICT) | 446 | if ((ctx->param->flags & X509_V_FLAG_X509_STRICT) |
428 | && (ret != 1) && (ret != 0)) | 447 | && (ret != 1) && (ret != 0)) |
429 | { | 448 | { |
430 | ret = 0; | 449 | ret = 0; |
@@ -444,7 +463,7 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) | |||
444 | break; | 463 | break; |
445 | default: | 464 | default: |
446 | if ((ret == 0) | 465 | if ((ret == 0) |
447 | || ((ctx->flags & X509_V_FLAG_X509_STRICT) | 466 | || ((ctx->param->flags & X509_V_FLAG_X509_STRICT) |
448 | && (ret != 1))) | 467 | && (ret != 1))) |
449 | { | 468 | { |
450 | ret = 0; | 469 | ret = 0; |
@@ -461,12 +480,12 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) | |||
461 | ok=cb(0,ctx); | 480 | ok=cb(0,ctx); |
462 | if (!ok) goto end; | 481 | if (!ok) goto end; |
463 | } | 482 | } |
464 | if (ctx->purpose > 0) | 483 | if (ctx->param->purpose > 0) |
465 | { | 484 | { |
466 | ret = X509_check_purpose(x, ctx->purpose, | 485 | ret = X509_check_purpose(x, ctx->param->purpose, |
467 | must_be_ca > 0); | 486 | must_be_ca > 0); |
468 | if ((ret == 0) | 487 | if ((ret == 0) |
469 | || ((ctx->flags & X509_V_FLAG_X509_STRICT) | 488 | || ((ctx->param->flags & X509_V_FLAG_X509_STRICT) |
470 | && (ret != 1))) | 489 | && (ret != 1))) |
471 | { | 490 | { |
472 | ctx->error = X509_V_ERR_INVALID_PURPOSE; | 491 | ctx->error = X509_V_ERR_INVALID_PURPOSE; |
@@ -492,21 +511,15 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) | |||
492 | CA certificate. */ | 511 | CA certificate. */ |
493 | if (x->ex_flags & EXFLAG_PROXY) | 512 | if (x->ex_flags & EXFLAG_PROXY) |
494 | { | 513 | { |
495 | PROXY_CERT_INFO_EXTENSION *pci = | 514 | if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen) |
496 | X509_get_ext_d2i(x, NID_proxyCertInfo, | ||
497 | NULL, NULL); | ||
498 | if (pci->pcPathLengthConstraint && | ||
499 | ASN1_INTEGER_get(pci->pcPathLengthConstraint) | ||
500 | < i) | ||
501 | { | 515 | { |
502 | PROXY_CERT_INFO_EXTENSION_free(pci); | 516 | ctx->error = |
503 | ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED; | 517 | X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED; |
504 | ctx->error_depth = i; | 518 | ctx->error_depth = i; |
505 | ctx->current_cert = x; | 519 | ctx->current_cert = x; |
506 | ok=cb(0,ctx); | 520 | ok=cb(0,ctx); |
507 | if (!ok) goto end; | 521 | if (!ok) goto end; |
508 | } | 522 | } |
509 | PROXY_CERT_INFO_EXTENSION_free(pci); | ||
510 | proxy_path_length++; | 523 | proxy_path_length++; |
511 | must_be_ca = 0; | 524 | must_be_ca = 0; |
512 | } | 525 | } |
@@ -526,12 +539,12 @@ static int check_trust(X509_STORE_CTX *ctx) | |||
526 | #else | 539 | #else |
527 | int i, ok; | 540 | int i, ok; |
528 | X509 *x; | 541 | X509 *x; |
529 | int (*cb)(); | 542 | int (*cb)(int xok,X509_STORE_CTX *xctx); |
530 | cb=ctx->verify_cb; | 543 | cb=ctx->verify_cb; |
531 | /* For now just check the last certificate in the chain */ | 544 | /* For now just check the last certificate in the chain */ |
532 | i = sk_X509_num(ctx->chain) - 1; | 545 | i = sk_X509_num(ctx->chain) - 1; |
533 | x = sk_X509_value(ctx->chain, i); | 546 | x = sk_X509_value(ctx->chain, i); |
534 | ok = X509_check_trust(x, ctx->trust, 0); | 547 | ok = X509_check_trust(x, ctx->param->trust, 0); |
535 | if (ok == X509_TRUST_TRUSTED) | 548 | if (ok == X509_TRUST_TRUSTED) |
536 | return 1; | 549 | return 1; |
537 | ctx->error_depth = i; | 550 | ctx->error_depth = i; |
@@ -548,9 +561,9 @@ static int check_trust(X509_STORE_CTX *ctx) | |||
548 | static int check_revocation(X509_STORE_CTX *ctx) | 561 | static int check_revocation(X509_STORE_CTX *ctx) |
549 | { | 562 | { |
550 | int i, last, ok; | 563 | int i, last, ok; |
551 | if (!(ctx->flags & X509_V_FLAG_CRL_CHECK)) | 564 | if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK)) |
552 | return 1; | 565 | return 1; |
553 | if (ctx->flags & X509_V_FLAG_CRL_CHECK_ALL) | 566 | if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL) |
554 | last = sk_X509_num(ctx->chain) - 1; | 567 | last = sk_X509_num(ctx->chain) - 1; |
555 | else | 568 | else |
556 | last = 0; | 569 | last = 0; |
@@ -593,17 +606,124 @@ static int check_cert(X509_STORE_CTX *ctx) | |||
593 | 606 | ||
594 | } | 607 | } |
595 | 608 | ||
609 | /* Check CRL times against values in X509_STORE_CTX */ | ||
610 | |||
611 | static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) | ||
612 | { | ||
613 | time_t *ptime; | ||
614 | int i; | ||
615 | ctx->current_crl = crl; | ||
616 | if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) | ||
617 | ptime = &ctx->param->check_time; | ||
618 | else | ||
619 | ptime = NULL; | ||
620 | |||
621 | i=X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime); | ||
622 | if (i == 0) | ||
623 | { | ||
624 | ctx->error=X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD; | ||
625 | if (!notify || !ctx->verify_cb(0, ctx)) | ||
626 | return 0; | ||
627 | } | ||
628 | |||
629 | if (i > 0) | ||
630 | { | ||
631 | ctx->error=X509_V_ERR_CRL_NOT_YET_VALID; | ||
632 | if (!notify || !ctx->verify_cb(0, ctx)) | ||
633 | return 0; | ||
634 | } | ||
635 | |||
636 | if(X509_CRL_get_nextUpdate(crl)) | ||
637 | { | ||
638 | i=X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime); | ||
639 | |||
640 | if (i == 0) | ||
641 | { | ||
642 | ctx->error=X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD; | ||
643 | if (!notify || !ctx->verify_cb(0, ctx)) | ||
644 | return 0; | ||
645 | } | ||
646 | |||
647 | if (i < 0) | ||
648 | { | ||
649 | ctx->error=X509_V_ERR_CRL_HAS_EXPIRED; | ||
650 | if (!notify || !ctx->verify_cb(0, ctx)) | ||
651 | return 0; | ||
652 | } | ||
653 | } | ||
654 | |||
655 | ctx->current_crl = NULL; | ||
656 | |||
657 | return 1; | ||
658 | } | ||
659 | |||
660 | /* Lookup CRLs from the supplied list. Look for matching isser name | ||
661 | * and validity. If we can't find a valid CRL return the last one | ||
662 | * with matching name. This gives more meaningful error codes. Otherwise | ||
663 | * we'd get a CRL not found error if a CRL existed with matching name but | ||
664 | * was invalid. | ||
665 | */ | ||
666 | |||
667 | static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, | ||
668 | X509_NAME *nm, STACK_OF(X509_CRL) *crls) | ||
669 | { | ||
670 | int i; | ||
671 | X509_CRL *crl, *best_crl = NULL; | ||
672 | for (i = 0; i < sk_X509_CRL_num(crls); i++) | ||
673 | { | ||
674 | crl = sk_X509_CRL_value(crls, i); | ||
675 | if (X509_NAME_cmp(nm, X509_CRL_get_issuer(crl))) | ||
676 | continue; | ||
677 | if (check_crl_time(ctx, crl, 0)) | ||
678 | { | ||
679 | *pcrl = crl; | ||
680 | CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509); | ||
681 | return 1; | ||
682 | } | ||
683 | best_crl = crl; | ||
684 | } | ||
685 | if (best_crl) | ||
686 | { | ||
687 | *pcrl = best_crl; | ||
688 | CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509); | ||
689 | } | ||
690 | |||
691 | return 0; | ||
692 | } | ||
693 | |||
596 | /* Retrieve CRL corresponding to certificate: currently just a | 694 | /* Retrieve CRL corresponding to certificate: currently just a |
597 | * subject lookup: maybe use AKID later... | 695 | * subject lookup: maybe use AKID later... |
598 | * Also might look up any included CRLs too (e.g PKCS#7 signedData). | ||
599 | */ | 696 | */ |
600 | static int get_crl(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x) | 697 | static int get_crl(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 *x) |
601 | { | 698 | { |
602 | int ok; | 699 | int ok; |
700 | X509_CRL *crl = NULL; | ||
603 | X509_OBJECT xobj; | 701 | X509_OBJECT xobj; |
604 | ok = X509_STORE_get_by_subject(ctx, X509_LU_CRL, X509_get_issuer_name(x), &xobj); | 702 | X509_NAME *nm; |
605 | if (!ok) return 0; | 703 | nm = X509_get_issuer_name(x); |
606 | *crl = xobj.data.crl; | 704 | ok = get_crl_sk(ctx, &crl, nm, ctx->crls); |
705 | if (ok) | ||
706 | { | ||
707 | *pcrl = crl; | ||
708 | return 1; | ||
709 | } | ||
710 | |||
711 | ok = X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj); | ||
712 | |||
713 | if (!ok) | ||
714 | { | ||
715 | /* If we got a near match from get_crl_sk use that */ | ||
716 | if (crl) | ||
717 | { | ||
718 | *pcrl = crl; | ||
719 | return 1; | ||
720 | } | ||
721 | return 0; | ||
722 | } | ||
723 | |||
724 | *pcrl = xobj.data.crl; | ||
725 | if (crl) | ||
726 | X509_CRL_free(crl); | ||
607 | return 1; | 727 | return 1; |
608 | } | 728 | } |
609 | 729 | ||
@@ -612,8 +732,7 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) | |||
612 | { | 732 | { |
613 | X509 *issuer = NULL; | 733 | X509 *issuer = NULL; |
614 | EVP_PKEY *ikey = NULL; | 734 | EVP_PKEY *ikey = NULL; |
615 | int ok = 0, chnum, cnum, i; | 735 | int ok = 0, chnum, cnum; |
616 | time_t *ptime; | ||
617 | cnum = ctx->error_depth; | 736 | cnum = ctx->error_depth; |
618 | chnum = sk_X509_num(ctx->chain) - 1; | 737 | chnum = sk_X509_num(ctx->chain) - 1; |
619 | /* Find CRL issuer: if not last certificate then issuer | 738 | /* Find CRL issuer: if not last certificate then issuer |
@@ -665,45 +784,9 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) | |||
665 | } | 784 | } |
666 | } | 785 | } |
667 | 786 | ||
668 | /* OK, CRL signature valid check times */ | 787 | ok = check_crl_time(ctx, crl, 1); |
669 | if (ctx->flags & X509_V_FLAG_USE_CHECK_TIME) | 788 | if (!ok) |
670 | ptime = &ctx->check_time; | 789 | goto err; |
671 | else | ||
672 | ptime = NULL; | ||
673 | |||
674 | i=X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime); | ||
675 | if (i == 0) | ||
676 | { | ||
677 | ctx->error=X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD; | ||
678 | ok = ctx->verify_cb(0, ctx); | ||
679 | if (!ok) goto err; | ||
680 | } | ||
681 | |||
682 | if (i > 0) | ||
683 | { | ||
684 | ctx->error=X509_V_ERR_CRL_NOT_YET_VALID; | ||
685 | ok = ctx->verify_cb(0, ctx); | ||
686 | if (!ok) goto err; | ||
687 | } | ||
688 | |||
689 | if(X509_CRL_get_nextUpdate(crl)) | ||
690 | { | ||
691 | i=X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime); | ||
692 | |||
693 | if (i == 0) | ||
694 | { | ||
695 | ctx->error=X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD; | ||
696 | ok = ctx->verify_cb(0, ctx); | ||
697 | if (!ok) goto err; | ||
698 | } | ||
699 | |||
700 | if (i < 0) | ||
701 | { | ||
702 | ctx->error=X509_V_ERR_CRL_HAS_EXPIRED; | ||
703 | ok = ctx->verify_cb(0, ctx); | ||
704 | if (!ok) goto err; | ||
705 | } | ||
706 | } | ||
707 | 790 | ||
708 | ok = 1; | 791 | ok = 1; |
709 | 792 | ||
@@ -741,7 +824,7 @@ static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) | |||
741 | if (!ok) return 0; | 824 | if (!ok) return 0; |
742 | } | 825 | } |
743 | 826 | ||
744 | if (ctx->flags & X509_V_FLAG_IGNORE_CRITICAL) | 827 | if (ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) |
745 | return 1; | 828 | return 1; |
746 | 829 | ||
747 | /* See if we have any critical CRL extensions: since we | 830 | /* See if we have any critical CRL extensions: since we |
@@ -768,13 +851,106 @@ static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) | |||
768 | return 1; | 851 | return 1; |
769 | } | 852 | } |
770 | 853 | ||
854 | static int check_policy(X509_STORE_CTX *ctx) | ||
855 | { | ||
856 | int ret; | ||
857 | ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain, | ||
858 | ctx->param->policies, ctx->param->flags); | ||
859 | if (ret == 0) | ||
860 | { | ||
861 | X509err(X509_F_CHECK_POLICY,ERR_R_MALLOC_FAILURE); | ||
862 | return 0; | ||
863 | } | ||
864 | /* Invalid or inconsistent extensions */ | ||
865 | if (ret == -1) | ||
866 | { | ||
867 | /* Locate certificates with bad extensions and notify | ||
868 | * callback. | ||
869 | */ | ||
870 | X509 *x; | ||
871 | int i; | ||
872 | for (i = 1; i < sk_X509_num(ctx->chain); i++) | ||
873 | { | ||
874 | x = sk_X509_value(ctx->chain, i); | ||
875 | if (!(x->ex_flags & EXFLAG_INVALID_POLICY)) | ||
876 | continue; | ||
877 | ctx->current_cert = x; | ||
878 | ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION; | ||
879 | ret = ctx->verify_cb(0, ctx); | ||
880 | } | ||
881 | return 1; | ||
882 | } | ||
883 | if (ret == -2) | ||
884 | { | ||
885 | ctx->current_cert = NULL; | ||
886 | ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY; | ||
887 | return ctx->verify_cb(0, ctx); | ||
888 | } | ||
889 | |||
890 | if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) | ||
891 | { | ||
892 | ctx->current_cert = NULL; | ||
893 | ctx->error = X509_V_OK; | ||
894 | if (!ctx->verify_cb(2, ctx)) | ||
895 | return 0; | ||
896 | } | ||
897 | |||
898 | return 1; | ||
899 | } | ||
900 | |||
901 | static int check_cert_time(X509_STORE_CTX *ctx, X509 *x) | ||
902 | { | ||
903 | time_t *ptime; | ||
904 | int i; | ||
905 | |||
906 | if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) | ||
907 | ptime = &ctx->param->check_time; | ||
908 | else | ||
909 | ptime = NULL; | ||
910 | |||
911 | i=X509_cmp_time(X509_get_notBefore(x), ptime); | ||
912 | if (i == 0) | ||
913 | { | ||
914 | ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; | ||
915 | ctx->current_cert=x; | ||
916 | if (!ctx->verify_cb(0, ctx)) | ||
917 | return 0; | ||
918 | } | ||
919 | |||
920 | if (i > 0) | ||
921 | { | ||
922 | ctx->error=X509_V_ERR_CERT_NOT_YET_VALID; | ||
923 | ctx->current_cert=x; | ||
924 | if (!ctx->verify_cb(0, ctx)) | ||
925 | return 0; | ||
926 | } | ||
927 | |||
928 | i=X509_cmp_time(X509_get_notAfter(x), ptime); | ||
929 | if (i == 0) | ||
930 | { | ||
931 | ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD; | ||
932 | ctx->current_cert=x; | ||
933 | if (!ctx->verify_cb(0, ctx)) | ||
934 | return 0; | ||
935 | } | ||
936 | |||
937 | if (i < 0) | ||
938 | { | ||
939 | ctx->error=X509_V_ERR_CERT_HAS_EXPIRED; | ||
940 | ctx->current_cert=x; | ||
941 | if (!ctx->verify_cb(0, ctx)) | ||
942 | return 0; | ||
943 | } | ||
944 | |||
945 | return 1; | ||
946 | } | ||
947 | |||
771 | static int internal_verify(X509_STORE_CTX *ctx) | 948 | static int internal_verify(X509_STORE_CTX *ctx) |
772 | { | 949 | { |
773 | int i,ok=0,n; | 950 | int ok=0,n; |
774 | X509 *xs,*xi; | 951 | X509 *xs,*xi; |
775 | EVP_PKEY *pkey=NULL; | 952 | EVP_PKEY *pkey=NULL; |
776 | time_t *ptime; | 953 | int (*cb)(int xok,X509_STORE_CTX *xctx); |
777 | int (*cb)(); | ||
778 | 954 | ||
779 | cb=ctx->verify_cb; | 955 | cb=ctx->verify_cb; |
780 | 956 | ||
@@ -782,10 +958,7 @@ static int internal_verify(X509_STORE_CTX *ctx) | |||
782 | ctx->error_depth=n-1; | 958 | ctx->error_depth=n-1; |
783 | n--; | 959 | n--; |
784 | xi=sk_X509_value(ctx->chain,n); | 960 | xi=sk_X509_value(ctx->chain,n); |
785 | if (ctx->flags & X509_V_FLAG_USE_CHECK_TIME) | 961 | |
786 | ptime = &ctx->check_time; | ||
787 | else | ||
788 | ptime = NULL; | ||
789 | if (ctx->check_issued(ctx, xi, xi)) | 962 | if (ctx->check_issued(ctx, xi, xi)) |
790 | xs=xi; | 963 | xs=xi; |
791 | else | 964 | else |
@@ -838,41 +1011,13 @@ static int internal_verify(X509_STORE_CTX *ctx) | |||
838 | } | 1011 | } |
839 | EVP_PKEY_free(pkey); | 1012 | EVP_PKEY_free(pkey); |
840 | pkey=NULL; | 1013 | pkey=NULL; |
841 | |||
842 | i=X509_cmp_time(X509_get_notBefore(xs), ptime); | ||
843 | if (i == 0) | ||
844 | { | ||
845 | ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; | ||
846 | ctx->current_cert=xs; | ||
847 | ok=(*cb)(0,ctx); | ||
848 | if (!ok) goto end; | ||
849 | } | ||
850 | if (i > 0) | ||
851 | { | ||
852 | ctx->error=X509_V_ERR_CERT_NOT_YET_VALID; | ||
853 | ctx->current_cert=xs; | ||
854 | ok=(*cb)(0,ctx); | ||
855 | if (!ok) goto end; | ||
856 | } | ||
857 | xs->valid=1; | ||
858 | } | 1014 | } |
859 | 1015 | ||
860 | i=X509_cmp_time(X509_get_notAfter(xs), ptime); | 1016 | xs->valid = 1; |
861 | if (i == 0) | ||
862 | { | ||
863 | ctx->error=X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD; | ||
864 | ctx->current_cert=xs; | ||
865 | ok=(*cb)(0,ctx); | ||
866 | if (!ok) goto end; | ||
867 | } | ||
868 | 1017 | ||
869 | if (i < 0) | 1018 | ok = check_cert_time(ctx, xs); |
870 | { | 1019 | if (!ok) |
871 | ctx->error=X509_V_ERR_CERT_HAS_EXPIRED; | 1020 | goto end; |
872 | ctx->current_cert=xs; | ||
873 | ok=(*cb)(0,ctx); | ||
874 | if (!ok) goto end; | ||
875 | } | ||
876 | 1021 | ||
877 | /* The last error (if any) is still in the error value */ | 1022 | /* The last error (if any) is still in the error value */ |
878 | ctx->current_issuer=xi; | 1023 | ctx->current_issuer=xi; |
@@ -1105,6 +1250,11 @@ void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) | |||
1105 | ctx->untrusted=sk; | 1250 | ctx->untrusted=sk; |
1106 | } | 1251 | } |
1107 | 1252 | ||
1253 | void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk) | ||
1254 | { | ||
1255 | ctx->crls=sk; | ||
1256 | } | ||
1257 | |||
1108 | int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose) | 1258 | int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose) |
1109 | { | 1259 | { |
1110 | return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0); | 1260 | return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0); |
@@ -1168,8 +1318,8 @@ int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, | |||
1168 | } | 1318 | } |
1169 | } | 1319 | } |
1170 | 1320 | ||
1171 | if (purpose && !ctx->purpose) ctx->purpose = purpose; | 1321 | if (purpose && !ctx->param->purpose) ctx->param->purpose = purpose; |
1172 | if (trust && !ctx->trust) ctx->trust = trust; | 1322 | if (trust && !ctx->param->trust) ctx->param->trust = trust; |
1173 | return 1; | 1323 | return 1; |
1174 | } | 1324 | } |
1175 | 1325 | ||
@@ -1195,20 +1345,30 @@ void X509_STORE_CTX_free(X509_STORE_CTX *ctx) | |||
1195 | int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, | 1345 | int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, |
1196 | STACK_OF(X509) *chain) | 1346 | STACK_OF(X509) *chain) |
1197 | { | 1347 | { |
1348 | int ret = 1; | ||
1198 | ctx->ctx=store; | 1349 | ctx->ctx=store; |
1199 | ctx->current_method=0; | 1350 | ctx->current_method=0; |
1200 | ctx->cert=x509; | 1351 | ctx->cert=x509; |
1201 | ctx->untrusted=chain; | 1352 | ctx->untrusted=chain; |
1353 | ctx->crls = NULL; | ||
1202 | ctx->last_untrusted=0; | 1354 | ctx->last_untrusted=0; |
1203 | ctx->check_time=0; | ||
1204 | ctx->other_ctx=NULL; | 1355 | ctx->other_ctx=NULL; |
1205 | ctx->valid=0; | 1356 | ctx->valid=0; |
1206 | ctx->chain=NULL; | 1357 | ctx->chain=NULL; |
1207 | ctx->depth=9; | ||
1208 | ctx->error=0; | 1358 | ctx->error=0; |
1359 | ctx->explicit_policy=0; | ||
1209 | ctx->error_depth=0; | 1360 | ctx->error_depth=0; |
1210 | ctx->current_cert=NULL; | 1361 | ctx->current_cert=NULL; |
1211 | ctx->current_issuer=NULL; | 1362 | ctx->current_issuer=NULL; |
1363 | ctx->tree = NULL; | ||
1364 | |||
1365 | ctx->param = X509_VERIFY_PARAM_new(); | ||
1366 | |||
1367 | if (!ctx->param) | ||
1368 | { | ||
1369 | X509err(X509_F_X509_STORE_CTX_INIT,ERR_R_MALLOC_FAILURE); | ||
1370 | return 0; | ||
1371 | } | ||
1212 | 1372 | ||
1213 | /* Inherit callbacks and flags from X509_STORE if not set | 1373 | /* Inherit callbacks and flags from X509_STORE if not set |
1214 | * use defaults. | 1374 | * use defaults. |
@@ -1216,18 +1376,26 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, | |||
1216 | 1376 | ||
1217 | 1377 | ||
1218 | if (store) | 1378 | if (store) |
1379 | ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param); | ||
1380 | else | ||
1381 | ctx->param->flags |= X509_VP_FLAG_DEFAULT|X509_VP_FLAG_ONCE; | ||
1382 | |||
1383 | if (store) | ||
1219 | { | 1384 | { |
1220 | ctx->purpose=store->purpose; | 1385 | ctx->verify_cb = store->verify_cb; |
1221 | ctx->trust=store->trust; | ||
1222 | ctx->flags = store->flags; | ||
1223 | ctx->cleanup = store->cleanup; | 1386 | ctx->cleanup = store->cleanup; |
1224 | } | 1387 | } |
1225 | else | 1388 | else |
1226 | { | ||
1227 | ctx->purpose = 0; | ||
1228 | ctx->trust = 0; | ||
1229 | ctx->flags = 0; | ||
1230 | ctx->cleanup = 0; | 1389 | ctx->cleanup = 0; |
1390 | |||
1391 | if (ret) | ||
1392 | ret = X509_VERIFY_PARAM_inherit(ctx->param, | ||
1393 | X509_VERIFY_PARAM_lookup("default")); | ||
1394 | |||
1395 | if (ret == 0) | ||
1396 | { | ||
1397 | X509err(X509_F_X509_STORE_CTX_INIT,ERR_R_MALLOC_FAILURE); | ||
1398 | return 0; | ||
1231 | } | 1399 | } |
1232 | 1400 | ||
1233 | if (store && store->check_issued) | 1401 | if (store && store->check_issued) |
@@ -1270,6 +1438,8 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, | |||
1270 | else | 1438 | else |
1271 | ctx->cert_crl = cert_crl; | 1439 | ctx->cert_crl = cert_crl; |
1272 | 1440 | ||
1441 | ctx->check_policy = check_policy; | ||
1442 | |||
1273 | 1443 | ||
1274 | /* This memset() can't make any sense anyway, so it's removed. As | 1444 | /* This memset() can't make any sense anyway, so it's removed. As |
1275 | * X509_STORE_CTX_cleanup does a proper "free" on the ex_data, we put a | 1445 | * X509_STORE_CTX_cleanup does a proper "free" on the ex_data, we put a |
@@ -1298,6 +1468,16 @@ void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) | |||
1298 | void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx) | 1468 | void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx) |
1299 | { | 1469 | { |
1300 | if (ctx->cleanup) ctx->cleanup(ctx); | 1470 | if (ctx->cleanup) ctx->cleanup(ctx); |
1471 | if (ctx->param != NULL) | ||
1472 | { | ||
1473 | X509_VERIFY_PARAM_free(ctx->param); | ||
1474 | ctx->param=NULL; | ||
1475 | } | ||
1476 | if (ctx->tree != NULL) | ||
1477 | { | ||
1478 | X509_policy_tree_free(ctx->tree); | ||
1479 | ctx->tree=NULL; | ||
1480 | } | ||
1301 | if (ctx->chain != NULL) | 1481 | if (ctx->chain != NULL) |
1302 | { | 1482 | { |
1303 | sk_X509_pop_free(ctx->chain,X509_free); | 1483 | sk_X509_pop_free(ctx->chain,X509_free); |
@@ -1307,15 +1487,19 @@ void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx) | |||
1307 | memset(&ctx->ex_data,0,sizeof(CRYPTO_EX_DATA)); | 1487 | memset(&ctx->ex_data,0,sizeof(CRYPTO_EX_DATA)); |
1308 | } | 1488 | } |
1309 | 1489 | ||
1310 | void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, long flags) | 1490 | void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth) |
1311 | { | 1491 | { |
1312 | ctx->flags |= flags; | 1492 | X509_VERIFY_PARAM_set_depth(ctx->param, depth); |
1313 | } | 1493 | } |
1314 | 1494 | ||
1315 | void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, long flags, time_t t) | 1495 | void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags) |
1316 | { | 1496 | { |
1317 | ctx->check_time = t; | 1497 | X509_VERIFY_PARAM_set_flags(ctx->param, flags); |
1318 | ctx->flags |= X509_V_FLAG_USE_CHECK_TIME; | 1498 | } |
1499 | |||
1500 | void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, time_t t) | ||
1501 | { | ||
1502 | X509_VERIFY_PARAM_set_time(ctx->param, t); | ||
1319 | } | 1503 | } |
1320 | 1504 | ||
1321 | void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, | 1505 | void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, |
@@ -1324,6 +1508,37 @@ void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, | |||
1324 | ctx->verify_cb=verify_cb; | 1508 | ctx->verify_cb=verify_cb; |
1325 | } | 1509 | } |
1326 | 1510 | ||
1511 | X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx) | ||
1512 | { | ||
1513 | return ctx->tree; | ||
1514 | } | ||
1515 | |||
1516 | int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx) | ||
1517 | { | ||
1518 | return ctx->explicit_policy; | ||
1519 | } | ||
1520 | |||
1521 | int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name) | ||
1522 | { | ||
1523 | const X509_VERIFY_PARAM *param; | ||
1524 | param = X509_VERIFY_PARAM_lookup(name); | ||
1525 | if (!param) | ||
1526 | return 0; | ||
1527 | return X509_VERIFY_PARAM_inherit(ctx->param, param); | ||
1528 | } | ||
1529 | |||
1530 | X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx) | ||
1531 | { | ||
1532 | return ctx->param; | ||
1533 | } | ||
1534 | |||
1535 | void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param) | ||
1536 | { | ||
1537 | if (ctx->param) | ||
1538 | X509_VERIFY_PARAM_free(ctx->param); | ||
1539 | ctx->param = param; | ||
1540 | } | ||
1541 | |||
1327 | IMPLEMENT_STACK_OF(X509) | 1542 | IMPLEMENT_STACK_OF(X509) |
1328 | IMPLEMENT_ASN1_SET_OF(X509) | 1543 | IMPLEMENT_ASN1_SET_OF(X509) |
1329 | 1544 | ||