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 | ||
