diff options
Diffstat (limited to 'src/lib/libcrypto/x509/x509_vfy.c')
-rw-r--r-- | src/lib/libcrypto/x509/x509_vfy.c | 347 |
1 files changed, 307 insertions, 40 deletions
diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c index 0f4110cc64..db12f7bd35 100644 --- a/src/lib/libcrypto/x509/x509_vfy.c +++ b/src/lib/libcrypto/x509/x509_vfy.c | |||
@@ -75,15 +75,11 @@ static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); | |||
75 | static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x); | 75 | static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x); |
76 | static int check_chain_purpose(X509_STORE_CTX *ctx); | 76 | static int check_chain_purpose(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); | ||
79 | static int check_cert(X509_STORE_CTX *ctx); | ||
78 | static int internal_verify(X509_STORE_CTX *ctx); | 80 | static int internal_verify(X509_STORE_CTX *ctx); |
79 | const char *X509_version="X.509" OPENSSL_VERSION_PTEXT; | 81 | const char *X509_version="X.509" OPENSSL_VERSION_PTEXT; |
80 | 82 | ||
81 | static STACK_OF(CRYPTO_EX_DATA_FUNCS) *x509_store_ctx_method=NULL; | ||
82 | static int x509_store_ctx_num=0; | ||
83 | #if 0 | ||
84 | static int x509_store_num=1; | ||
85 | static STACK *x509_store_method=NULL; | ||
86 | #endif | ||
87 | 83 | ||
88 | static int null_callback(int ok, X509_STORE_CTX *e) | 84 | static int null_callback(int ok, X509_STORE_CTX *e) |
89 | { | 85 | { |
@@ -113,7 +109,6 @@ int X509_verify_cert(X509_STORE_CTX *ctx) | |||
113 | } | 109 | } |
114 | 110 | ||
115 | cb=ctx->verify_cb; | 111 | cb=ctx->verify_cb; |
116 | if (cb == NULL) cb=null_callback; | ||
117 | 112 | ||
118 | /* first we make sure the chain we are going to build is | 113 | /* first we make sure the chain we are going to build is |
119 | * present and that the first entry is in place */ | 114 | * present and that the first entry is in place */ |
@@ -299,6 +294,13 @@ int X509_verify_cert(X509_STORE_CTX *ctx) | |||
299 | /* We may as well copy down any DSA parameters that are required */ | 294 | /* We may as well copy down any DSA parameters that are required */ |
300 | X509_get_pubkey_parameters(NULL,ctx->chain); | 295 | X509_get_pubkey_parameters(NULL,ctx->chain); |
301 | 296 | ||
297 | /* Check revocation status: we do this after copying parameters | ||
298 | * because they may be needed for CRL signature verification. | ||
299 | */ | ||
300 | |||
301 | ok = ctx->check_revocation(ctx); | ||
302 | if(!ok) goto end; | ||
303 | |||
302 | /* At this point, we have a chain and just need to verify it */ | 304 | /* At this point, we have a chain and just need to verify it */ |
303 | if (ctx->verify != NULL) | 305 | if (ctx->verify != NULL) |
304 | ok=ctx->verify(ctx); | 306 | ok=ctx->verify(ctx); |
@@ -346,8 +348,7 @@ static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer) | |||
346 | ctx->error = ret; | 348 | ctx->error = ret; |
347 | ctx->current_cert = x; | 349 | ctx->current_cert = x; |
348 | ctx->current_issuer = issuer; | 350 | ctx->current_issuer = issuer; |
349 | if (ctx->verify_cb) | 351 | return ctx->verify_cb(0, ctx); |
350 | return ctx->verify_cb(0, ctx); | ||
351 | return 0; | 352 | return 0; |
352 | } | 353 | } |
353 | 354 | ||
@@ -372,18 +373,26 @@ static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) | |||
372 | 373 | ||
373 | static int check_chain_purpose(X509_STORE_CTX *ctx) | 374 | static int check_chain_purpose(X509_STORE_CTX *ctx) |
374 | { | 375 | { |
375 | #ifdef NO_CHAIN_VERIFY | 376 | #ifdef OPENSSL_NO_CHAIN_VERIFY |
376 | return 1; | 377 | return 1; |
377 | #else | 378 | #else |
378 | int i, ok=0; | 379 | int i, ok=0; |
379 | X509 *x; | 380 | X509 *x; |
380 | int (*cb)(); | 381 | int (*cb)(); |
381 | cb=ctx->verify_cb; | 382 | cb=ctx->verify_cb; |
382 | if (cb == NULL) cb=null_callback; | ||
383 | /* Check all untrusted certificates */ | 383 | /* Check all untrusted certificates */ |
384 | for (i = 0; i < ctx->last_untrusted; i++) | 384 | for (i = 0; i < ctx->last_untrusted; i++) |
385 | { | 385 | { |
386 | x = sk_X509_value(ctx->chain, i); | 386 | x = sk_X509_value(ctx->chain, i); |
387 | if (!(ctx->flags & X509_V_FLAG_IGNORE_CRITICAL) | ||
388 | && (x->ex_flags & EXFLAG_CRITICAL)) | ||
389 | { | ||
390 | ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION; | ||
391 | ctx->error_depth = i; | ||
392 | ctx->current_cert = x; | ||
393 | ok=cb(0,ctx); | ||
394 | if (!ok) goto end; | ||
395 | } | ||
387 | if (!X509_check_purpose(x, ctx->purpose, i)) | 396 | if (!X509_check_purpose(x, ctx->purpose, i)) |
388 | { | 397 | { |
389 | if (i) | 398 | if (i) |
@@ -414,21 +423,20 @@ static int check_chain_purpose(X509_STORE_CTX *ctx) | |||
414 | 423 | ||
415 | static int check_trust(X509_STORE_CTX *ctx) | 424 | static int check_trust(X509_STORE_CTX *ctx) |
416 | { | 425 | { |
417 | #ifdef NO_CHAIN_VERIFY | 426 | #ifdef OPENSSL_NO_CHAIN_VERIFY |
418 | return 1; | 427 | return 1; |
419 | #else | 428 | #else |
420 | int i, ok; | 429 | int i, ok; |
421 | X509 *x; | 430 | X509 *x; |
422 | int (*cb)(); | 431 | int (*cb)(); |
423 | cb=ctx->verify_cb; | 432 | cb=ctx->verify_cb; |
424 | if (cb == NULL) cb=null_callback; | ||
425 | /* For now just check the last certificate in the chain */ | 433 | /* For now just check the last certificate in the chain */ |
426 | i = sk_X509_num(ctx->chain) - 1; | 434 | i = sk_X509_num(ctx->chain) - 1; |
427 | x = sk_X509_value(ctx->chain, i); | 435 | x = sk_X509_value(ctx->chain, i); |
428 | ok = X509_check_trust(x, ctx->trust, 0); | 436 | ok = X509_check_trust(x, ctx->trust, 0); |
429 | if (ok == X509_TRUST_TRUSTED) | 437 | if (ok == X509_TRUST_TRUSTED) |
430 | return 1; | 438 | return 1; |
431 | ctx->error_depth = sk_X509_num(ctx->chain) - 1; | 439 | ctx->error_depth = i; |
432 | ctx->current_cert = x; | 440 | ctx->current_cert = x; |
433 | if (ok == X509_TRUST_REJECTED) | 441 | if (ok == X509_TRUST_REJECTED) |
434 | ctx->error = X509_V_ERR_CERT_REJECTED; | 442 | ctx->error = X509_V_ERR_CERT_REJECTED; |
@@ -439,6 +447,183 @@ static int check_trust(X509_STORE_CTX *ctx) | |||
439 | #endif | 447 | #endif |
440 | } | 448 | } |
441 | 449 | ||
450 | static int check_revocation(X509_STORE_CTX *ctx) | ||
451 | { | ||
452 | int i, last, ok; | ||
453 | if (!(ctx->flags & X509_V_FLAG_CRL_CHECK)) | ||
454 | return 1; | ||
455 | if (ctx->flags & X509_V_FLAG_CRL_CHECK_ALL) | ||
456 | last = 0; | ||
457 | else | ||
458 | last = sk_X509_num(ctx->chain) - 1; | ||
459 | for(i = 0; i <= last; i++) | ||
460 | { | ||
461 | ctx->error_depth = i; | ||
462 | ok = check_cert(ctx); | ||
463 | if (!ok) return ok; | ||
464 | } | ||
465 | return 1; | ||
466 | } | ||
467 | |||
468 | static int check_cert(X509_STORE_CTX *ctx) | ||
469 | { | ||
470 | X509_CRL *crl = NULL; | ||
471 | X509 *x; | ||
472 | int ok, cnum; | ||
473 | cnum = ctx->error_depth; | ||
474 | x = sk_X509_value(ctx->chain, cnum); | ||
475 | ctx->current_cert = x; | ||
476 | /* Try to retrieve relevant CRL */ | ||
477 | ok = ctx->get_crl(ctx, &crl, x); | ||
478 | /* If error looking up CRL, nothing we can do except | ||
479 | * notify callback | ||
480 | */ | ||
481 | if(!ok) | ||
482 | { | ||
483 | ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL; | ||
484 | ok = ctx->verify_cb(0, ctx); | ||
485 | goto err; | ||
486 | } | ||
487 | ctx->current_crl = crl; | ||
488 | ok = ctx->check_crl(ctx, crl); | ||
489 | if (!ok) goto err; | ||
490 | ok = ctx->cert_crl(ctx, crl, x); | ||
491 | err: | ||
492 | ctx->current_crl = NULL; | ||
493 | X509_CRL_free(crl); | ||
494 | return ok; | ||
495 | |||
496 | } | ||
497 | |||
498 | /* Retrieve CRL corresponding to certificate: currently just a | ||
499 | * subject lookup: maybe use AKID later... | ||
500 | * Also might look up any included CRLs too (e.g PKCS#7 signedData). | ||
501 | */ | ||
502 | static int get_crl(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x) | ||
503 | { | ||
504 | int ok; | ||
505 | X509_OBJECT xobj; | ||
506 | ok = X509_STORE_get_by_subject(ctx, X509_LU_CRL, X509_get_issuer_name(x), &xobj); | ||
507 | if (!ok) return 0; | ||
508 | *crl = xobj.data.crl; | ||
509 | return 1; | ||
510 | } | ||
511 | |||
512 | /* Check CRL validity */ | ||
513 | static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) | ||
514 | { | ||
515 | X509 *issuer = NULL; | ||
516 | EVP_PKEY *ikey = NULL; | ||
517 | int ok = 0, chnum, cnum, i; | ||
518 | time_t *ptime; | ||
519 | cnum = ctx->error_depth; | ||
520 | chnum = sk_X509_num(ctx->chain) - 1; | ||
521 | /* Find CRL issuer: if not last certificate then issuer | ||
522 | * is next certificate in chain. | ||
523 | */ | ||
524 | if(cnum < chnum) | ||
525 | issuer = sk_X509_value(ctx->chain, cnum + 1); | ||
526 | else | ||
527 | { | ||
528 | issuer = sk_X509_value(ctx->chain, chnum); | ||
529 | /* If not self signed, can't check signature */ | ||
530 | if(!ctx->check_issued(ctx, issuer, issuer)) | ||
531 | { | ||
532 | ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER; | ||
533 | ok = ctx->verify_cb(0, ctx); | ||
534 | if(!ok) goto err; | ||
535 | } | ||
536 | } | ||
537 | |||
538 | if(issuer) | ||
539 | { | ||
540 | |||
541 | /* Attempt to get issuer certificate public key */ | ||
542 | ikey = X509_get_pubkey(issuer); | ||
543 | |||
544 | if(!ikey) | ||
545 | { | ||
546 | ctx->error=X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; | ||
547 | ok = ctx->verify_cb(0, ctx); | ||
548 | if (!ok) goto err; | ||
549 | } | ||
550 | else | ||
551 | { | ||
552 | /* Verify CRL signature */ | ||
553 | if(X509_CRL_verify(crl, ikey) <= 0) | ||
554 | { | ||
555 | ctx->error=X509_V_ERR_CRL_SIGNATURE_FAILURE; | ||
556 | ok = ctx->verify_cb(0, ctx); | ||
557 | if (!ok) goto err; | ||
558 | } | ||
559 | } | ||
560 | } | ||
561 | |||
562 | /* OK, CRL signature valid check times */ | ||
563 | if (ctx->flags & X509_V_FLAG_USE_CHECK_TIME) | ||
564 | ptime = &ctx->check_time; | ||
565 | else | ||
566 | ptime = NULL; | ||
567 | |||
568 | i=X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime); | ||
569 | if (i == 0) | ||
570 | { | ||
571 | ctx->error=X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD; | ||
572 | ok = ctx->verify_cb(0, ctx); | ||
573 | if (!ok) goto err; | ||
574 | } | ||
575 | |||
576 | if (i > 0) | ||
577 | { | ||
578 | ctx->error=X509_V_ERR_CRL_NOT_YET_VALID; | ||
579 | ok = ctx->verify_cb(0, ctx); | ||
580 | if (!ok) goto err; | ||
581 | } | ||
582 | |||
583 | if(X509_CRL_get_nextUpdate(crl)) | ||
584 | { | ||
585 | i=X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime); | ||
586 | |||
587 | if (i == 0) | ||
588 | { | ||
589 | ctx->error=X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD; | ||
590 | ok = ctx->verify_cb(0, ctx); | ||
591 | if (!ok) goto err; | ||
592 | } | ||
593 | |||
594 | if (i < 0) | ||
595 | { | ||
596 | ctx->error=X509_V_ERR_CRL_HAS_EXPIRED; | ||
597 | ok = ctx->verify_cb(0, ctx); | ||
598 | if (!ok) goto err; | ||
599 | } | ||
600 | } | ||
601 | |||
602 | ok = 1; | ||
603 | |||
604 | err: | ||
605 | EVP_PKEY_free(ikey); | ||
606 | return ok; | ||
607 | } | ||
608 | |||
609 | /* Check certificate against CRL */ | ||
610 | static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) | ||
611 | { | ||
612 | int idx, ok; | ||
613 | X509_REVOKED rtmp; | ||
614 | /* Look for serial number of certificate in CRL */ | ||
615 | rtmp.serialNumber = X509_get_serialNumber(x); | ||
616 | idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp); | ||
617 | /* Not found: OK */ | ||
618 | if(idx == -1) return 1; | ||
619 | /* Otherwise revoked: want something cleverer than | ||
620 | * this to handle entry extensions in V2 CRLs. | ||
621 | */ | ||
622 | ctx->error = X509_V_ERR_CERT_REVOKED; | ||
623 | ok = ctx->verify_cb(0, ctx); | ||
624 | return ok; | ||
625 | } | ||
626 | |||
442 | static int internal_verify(X509_STORE_CTX *ctx) | 627 | static int internal_verify(X509_STORE_CTX *ctx) |
443 | { | 628 | { |
444 | int i,ok=0,n; | 629 | int i,ok=0,n; |
@@ -448,7 +633,6 @@ static int internal_verify(X509_STORE_CTX *ctx) | |||
448 | int (*cb)(); | 633 | int (*cb)(); |
449 | 634 | ||
450 | cb=ctx->verify_cb; | 635 | cb=ctx->verify_cb; |
451 | if (cb == NULL) cb=null_callback; | ||
452 | 636 | ||
453 | n=sk_X509_num(ctx->chain); | 637 | n=sk_X509_num(ctx->chain); |
454 | ctx->error_depth=n-1; | 638 | ctx->error_depth=n-1; |
@@ -491,6 +675,13 @@ static int internal_verify(X509_STORE_CTX *ctx) | |||
491 | if (!ok) goto end; | 675 | if (!ok) goto end; |
492 | } | 676 | } |
493 | if (X509_verify(xs,pkey) <= 0) | 677 | if (X509_verify(xs,pkey) <= 0) |
678 | /* XXX For the final trusted self-signed cert, | ||
679 | * this is a waste of time. That check should | ||
680 | * optional so that e.g. 'openssl x509' can be | ||
681 | * used to detect invalid self-signatures, but | ||
682 | * we don't verify again and again in SSL | ||
683 | * handshakes and the like once the cert has | ||
684 | * been declared trusted. */ | ||
494 | { | 685 | { |
495 | ctx->error=X509_V_ERR_CERT_SIGNATURE_FAILURE; | 686 | ctx->error=X509_V_ERR_CERT_SIGNATURE_FAILURE; |
496 | ctx->current_cert=xs; | 687 | ctx->current_cert=xs; |
@@ -539,8 +730,6 @@ static int internal_verify(X509_STORE_CTX *ctx) | |||
539 | if (!ok) goto end; | 730 | if (!ok) goto end; |
540 | } | 731 | } |
541 | 732 | ||
542 | /* CRL CHECK */ | ||
543 | |||
544 | /* The last error (if any) is still in the error value */ | 733 | /* The last error (if any) is still in the error value */ |
545 | ctx->current_cert=xs; | 734 | ctx->current_cert=xs; |
546 | ok=(*cb)(1,ctx); | 735 | ok=(*cb)(1,ctx); |
@@ -648,14 +837,16 @@ ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj) | |||
648 | ASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *in_tm) | 837 | ASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *in_tm) |
649 | { | 838 | { |
650 | time_t t; | 839 | time_t t; |
840 | int type = -1; | ||
651 | 841 | ||
652 | if (in_tm) t = *in_tm; | 842 | if (in_tm) t = *in_tm; |
653 | else time(&t); | 843 | else time(&t); |
654 | 844 | ||
655 | t+=adj; | 845 | t+=adj; |
656 | if (!s) return ASN1_TIME_set(s, t); | 846 | if (s) type = s->type; |
657 | if (s->type == V_ASN1_UTCTIME) return ASN1_UTCTIME_set(s,t); | 847 | if (type == V_ASN1_UTCTIME) return ASN1_UTCTIME_set(s,t); |
658 | return ASN1_GENERALIZEDTIME_set(s, t); | 848 | if (type == V_ASN1_GENERALIZEDTIME) return ASN1_GENERALIZEDTIME_set(s, t); |
849 | return ASN1_TIME_set(s, t); | ||
659 | } | 850 | } |
660 | 851 | ||
661 | int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain) | 852 | int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain) |
@@ -702,12 +893,12 @@ int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain) | |||
702 | 893 | ||
703 | int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, | 894 | int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, |
704 | CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) | 895 | CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) |
705 | { | 896 | { |
706 | x509_store_ctx_num++; | 897 | /* This function is (usually) called only once, by |
707 | return CRYPTO_get_ex_new_index(x509_store_ctx_num-1, | 898 | * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c). */ |
708 | &x509_store_ctx_method, | 899 | return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, argl, argp, |
709 | argl,argp,new_func,dup_func,free_func); | 900 | new_func, dup_func, free_func); |
710 | } | 901 | } |
711 | 902 | ||
712 | int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data) | 903 | int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data) |
713 | { | 904 | { |
@@ -831,8 +1022,8 @@ int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, | |||
831 | } | 1022 | } |
832 | } | 1023 | } |
833 | 1024 | ||
834 | if (purpose) ctx->purpose = purpose; | 1025 | if (purpose && !ctx->purpose) ctx->purpose = purpose; |
835 | if (trust) ctx->trust = trust; | 1026 | if (trust && !ctx->trust) ctx->trust = trust; |
836 | return 1; | 1027 | return 1; |
837 | } | 1028 | } |
838 | 1029 | ||
@@ -840,7 +1031,12 @@ X509_STORE_CTX *X509_STORE_CTX_new(void) | |||
840 | { | 1031 | { |
841 | X509_STORE_CTX *ctx; | 1032 | X509_STORE_CTX *ctx; |
842 | ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX)); | 1033 | ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX)); |
843 | if (ctx) memset(ctx, 0, sizeof(X509_STORE_CTX)); | 1034 | if (!ctx) |
1035 | { | ||
1036 | X509err(X509_F_X509_STORE_CTX_NEW,ERR_R_MALLOC_FAILURE); | ||
1037 | return NULL; | ||
1038 | } | ||
1039 | memset(ctx, 0, sizeof(X509_STORE_CTX)); | ||
844 | return ctx; | 1040 | return ctx; |
845 | } | 1041 | } |
846 | 1042 | ||
@@ -850,7 +1046,7 @@ void X509_STORE_CTX_free(X509_STORE_CTX *ctx) | |||
850 | OPENSSL_free(ctx); | 1046 | OPENSSL_free(ctx); |
851 | } | 1047 | } |
852 | 1048 | ||
853 | void X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, | 1049 | int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, |
854 | STACK_OF(X509) *chain) | 1050 | STACK_OF(X509) *chain) |
855 | { | 1051 | { |
856 | ctx->ctx=store; | 1052 | ctx->ctx=store; |
@@ -858,10 +1054,7 @@ void X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, | |||
858 | ctx->cert=x509; | 1054 | ctx->cert=x509; |
859 | ctx->untrusted=chain; | 1055 | ctx->untrusted=chain; |
860 | ctx->last_untrusted=0; | 1056 | ctx->last_untrusted=0; |
861 | ctx->purpose=0; | ||
862 | ctx->trust=0; | ||
863 | ctx->check_time=0; | 1057 | ctx->check_time=0; |
864 | ctx->flags=0; | ||
865 | ctx->other_ctx=NULL; | 1058 | ctx->other_ctx=NULL; |
866 | ctx->valid=0; | 1059 | ctx->valid=0; |
867 | ctx->chain=NULL; | 1060 | ctx->chain=NULL; |
@@ -870,12 +1063,80 @@ void X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, | |||
870 | ctx->error_depth=0; | 1063 | ctx->error_depth=0; |
871 | ctx->current_cert=NULL; | 1064 | ctx->current_cert=NULL; |
872 | ctx->current_issuer=NULL; | 1065 | ctx->current_issuer=NULL; |
873 | ctx->check_issued = check_issued; | 1066 | |
874 | ctx->get_issuer = X509_STORE_CTX_get1_issuer; | 1067 | /* Inherit callbacks and flags from X509_STORE if not set |
875 | ctx->verify_cb = store->verify_cb; | 1068 | * use defaults. |
876 | ctx->verify = store->verify; | 1069 | */ |
877 | ctx->cleanup = 0; | 1070 | |
878 | memset(&(ctx->ex_data),0,sizeof(CRYPTO_EX_DATA)); | 1071 | |
1072 | if (store) | ||
1073 | { | ||
1074 | ctx->purpose=store->purpose; | ||
1075 | ctx->trust=store->trust; | ||
1076 | ctx->flags = store->flags; | ||
1077 | ctx->cleanup = store->cleanup; | ||
1078 | } | ||
1079 | else | ||
1080 | { | ||
1081 | ctx->purpose = 0; | ||
1082 | ctx->trust = 0; | ||
1083 | ctx->flags = 0; | ||
1084 | ctx->cleanup = 0; | ||
1085 | } | ||
1086 | |||
1087 | if (store && store->check_issued) | ||
1088 | ctx->check_issued = store->check_issued; | ||
1089 | else | ||
1090 | ctx->check_issued = check_issued; | ||
1091 | |||
1092 | if (store && store->get_issuer) | ||
1093 | ctx->get_issuer = store->get_issuer; | ||
1094 | else | ||
1095 | ctx->get_issuer = X509_STORE_CTX_get1_issuer; | ||
1096 | |||
1097 | if (store && store->verify_cb) | ||
1098 | ctx->verify_cb = store->verify_cb; | ||
1099 | else | ||
1100 | ctx->verify_cb = null_callback; | ||
1101 | |||
1102 | if (store && store->verify) | ||
1103 | ctx->verify = store->verify; | ||
1104 | else | ||
1105 | ctx->verify = internal_verify; | ||
1106 | |||
1107 | if (store && store->check_revocation) | ||
1108 | ctx->check_revocation = store->check_revocation; | ||
1109 | else | ||
1110 | ctx->check_revocation = check_revocation; | ||
1111 | |||
1112 | if (store && store->get_crl) | ||
1113 | ctx->get_crl = store->get_crl; | ||
1114 | else | ||
1115 | ctx->get_crl = get_crl; | ||
1116 | |||
1117 | if (store && store->check_crl) | ||
1118 | ctx->check_crl = store->check_crl; | ||
1119 | else | ||
1120 | ctx->check_crl = check_crl; | ||
1121 | |||
1122 | if (store && store->cert_crl) | ||
1123 | ctx->cert_crl = store->cert_crl; | ||
1124 | else | ||
1125 | ctx->cert_crl = cert_crl; | ||
1126 | |||
1127 | |||
1128 | /* This memset() can't make any sense anyway, so it's removed. As | ||
1129 | * X509_STORE_CTX_cleanup does a proper "free" on the ex_data, we put a | ||
1130 | * corresponding "new" here and remove this bogus initialisation. */ | ||
1131 | /* memset(&(ctx->ex_data),0,sizeof(CRYPTO_EX_DATA)); */ | ||
1132 | if(!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, | ||
1133 | &(ctx->ex_data))) | ||
1134 | { | ||
1135 | OPENSSL_free(ctx); | ||
1136 | X509err(X509_F_X509_STORE_CTX_INIT,ERR_R_MALLOC_FAILURE); | ||
1137 | return 0; | ||
1138 | } | ||
1139 | return 1; | ||
879 | } | 1140 | } |
880 | 1141 | ||
881 | /* Set alternative lookup method: just a STACK of trusted certificates. | 1142 | /* Set alternative lookup method: just a STACK of trusted certificates. |
@@ -896,7 +1157,7 @@ void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx) | |||
896 | sk_X509_pop_free(ctx->chain,X509_free); | 1157 | sk_X509_pop_free(ctx->chain,X509_free); |
897 | ctx->chain=NULL; | 1158 | ctx->chain=NULL; |
898 | } | 1159 | } |
899 | CRYPTO_free_ex_data(x509_store_ctx_method,ctx,&(ctx->ex_data)); | 1160 | CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, &(ctx->ex_data)); |
900 | memset(&ctx->ex_data,0,sizeof(CRYPTO_EX_DATA)); | 1161 | memset(&ctx->ex_data,0,sizeof(CRYPTO_EX_DATA)); |
901 | } | 1162 | } |
902 | 1163 | ||
@@ -911,6 +1172,12 @@ void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, long flags, time_t t) | |||
911 | ctx->flags |= X509_V_FLAG_USE_CHECK_TIME; | 1172 | ctx->flags |= X509_V_FLAG_USE_CHECK_TIME; |
912 | } | 1173 | } |
913 | 1174 | ||
1175 | void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, | ||
1176 | int (*verify_cb)(int, X509_STORE_CTX *)) | ||
1177 | { | ||
1178 | ctx->verify_cb=verify_cb; | ||
1179 | } | ||
1180 | |||
914 | IMPLEMENT_STACK_OF(X509) | 1181 | IMPLEMENT_STACK_OF(X509) |
915 | IMPLEMENT_ASN1_SET_OF(X509) | 1182 | IMPLEMENT_ASN1_SET_OF(X509) |
916 | 1183 | ||