diff options
Diffstat (limited to 'src/lib/libcrypto/x509/x509_vfy.c')
-rw-r--r-- | src/lib/libcrypto/x509/x509_vfy.c | 131 |
1 files changed, 13 insertions, 118 deletions
diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c index e43c861ee7..2e4d0b823a 100644 --- a/src/lib/libcrypto/x509/x509_vfy.c +++ b/src/lib/libcrypto/x509/x509_vfy.c | |||
@@ -73,7 +73,7 @@ | |||
73 | static int null_callback(int ok,X509_STORE_CTX *e); | 73 | static int null_callback(int ok,X509_STORE_CTX *e); |
74 | static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); | 74 | 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_extensions(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); | 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); |
@@ -281,7 +281,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx) | |||
281 | } | 281 | } |
282 | 282 | ||
283 | /* We have the chain complete: now we need to check its purpose */ | 283 | /* We have the chain complete: now we need to check its purpose */ |
284 | ok = check_chain_extensions(ctx); | 284 | if (ctx->purpose > 0) ok = check_chain_purpose(ctx); |
285 | 285 | ||
286 | if (!ok) goto end; | 286 | if (!ok) goto end; |
287 | 287 | ||
@@ -365,39 +365,21 @@ static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) | |||
365 | else | 365 | else |
366 | return 0; | 366 | return 0; |
367 | } | 367 | } |
368 | 368 | ||
369 | 369 | ||
370 | /* Check a certificate chains extensions for consistency | 370 | /* Check a certificate chains extensions for consistency |
371 | * with the supplied purpose | 371 | * with the supplied purpose |
372 | */ | 372 | */ |
373 | 373 | ||
374 | static int check_chain_extensions(X509_STORE_CTX *ctx) | 374 | static int check_chain_purpose(X509_STORE_CTX *ctx) |
375 | { | 375 | { |
376 | #ifdef OPENSSL_NO_CHAIN_VERIFY | 376 | #ifdef OPENSSL_NO_CHAIN_VERIFY |
377 | return 1; | 377 | return 1; |
378 | #else | 378 | #else |
379 | int i, ok=0, must_be_ca; | 379 | int i, ok=0; |
380 | X509 *x; | 380 | X509 *x; |
381 | int (*cb)(); | 381 | int (*cb)(); |
382 | int proxy_path_length = 0; | ||
383 | int allow_proxy_certs = !!(ctx->flags & X509_V_FLAG_ALLOW_PROXY_CERTS); | ||
384 | cb=ctx->verify_cb; | 382 | cb=ctx->verify_cb; |
385 | |||
386 | /* must_be_ca can have 1 of 3 values: | ||
387 | -1: we accept both CA and non-CA certificates, to allow direct | ||
388 | use of self-signed certificates (which are marked as CA). | ||
389 | 0: we only accept non-CA certificates. This is currently not | ||
390 | used, but the possibility is present for future extensions. | ||
391 | 1: we only accept CA certificates. This is currently used for | ||
392 | all certificates in the chain except the leaf certificate. | ||
393 | */ | ||
394 | must_be_ca = -1; | ||
395 | |||
396 | /* A hack to keep people who don't want to modify their software | ||
397 | happy */ | ||
398 | if (getenv("OPENSSL_ALLOW_PROXY_CERTS")) | ||
399 | allow_proxy_certs = 1; | ||
400 | |||
401 | /* Check all untrusted certificates */ | 383 | /* Check all untrusted certificates */ |
402 | for (i = 0; i < ctx->last_untrusted; i++) | 384 | for (i = 0; i < ctx->last_untrusted; i++) |
403 | { | 385 | { |
@@ -412,73 +394,23 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) | |||
412 | ok=cb(0,ctx); | 394 | ok=cb(0,ctx); |
413 | if (!ok) goto end; | 395 | if (!ok) goto end; |
414 | } | 396 | } |
415 | if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) | 397 | ret = X509_check_purpose(x, ctx->purpose, i); |
398 | if ((ret == 0) | ||
399 | || ((ctx->flags & X509_V_FLAG_X509_STRICT) | ||
400 | && (ret != 1))) | ||
416 | { | 401 | { |
417 | ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED; | 402 | if (i) |
418 | ctx->error_depth = i; | ||
419 | ctx->current_cert = x; | ||
420 | ok=cb(0,ctx); | ||
421 | if (!ok) goto end; | ||
422 | } | ||
423 | ret = X509_check_ca(x); | ||
424 | switch(must_be_ca) | ||
425 | { | ||
426 | case -1: | ||
427 | if ((ctx->flags & X509_V_FLAG_X509_STRICT) | ||
428 | && (ret != 1) && (ret != 0)) | ||
429 | { | ||
430 | ret = 0; | ||
431 | ctx->error = X509_V_ERR_INVALID_CA; | 403 | ctx->error = X509_V_ERR_INVALID_CA; |
432 | } | ||
433 | else | ||
434 | ret = 1; | ||
435 | break; | ||
436 | case 0: | ||
437 | if (ret != 0) | ||
438 | { | ||
439 | ret = 0; | ||
440 | ctx->error = X509_V_ERR_INVALID_NON_CA; | ||
441 | } | ||
442 | else | 404 | else |
443 | ret = 1; | 405 | ctx->error = X509_V_ERR_INVALID_PURPOSE; |
444 | break; | ||
445 | default: | ||
446 | if ((ret == 0) | ||
447 | || ((ctx->flags & X509_V_FLAG_X509_STRICT) | ||
448 | && (ret != 1))) | ||
449 | { | ||
450 | ret = 0; | ||
451 | ctx->error = X509_V_ERR_INVALID_CA; | ||
452 | } | ||
453 | else | ||
454 | ret = 1; | ||
455 | break; | ||
456 | } | ||
457 | if (ret == 0) | ||
458 | { | ||
459 | ctx->error_depth = i; | 406 | ctx->error_depth = i; |
460 | ctx->current_cert = x; | 407 | ctx->current_cert = x; |
461 | ok=cb(0,ctx); | 408 | ok=cb(0,ctx); |
462 | if (!ok) goto end; | 409 | if (!ok) goto end; |
463 | } | 410 | } |
464 | if (ctx->purpose > 0) | ||
465 | { | ||
466 | ret = X509_check_purpose(x, ctx->purpose, | ||
467 | must_be_ca > 0); | ||
468 | if ((ret == 0) | ||
469 | || ((ctx->flags & X509_V_FLAG_X509_STRICT) | ||
470 | && (ret != 1))) | ||
471 | { | ||
472 | ctx->error = X509_V_ERR_INVALID_PURPOSE; | ||
473 | ctx->error_depth = i; | ||
474 | ctx->current_cert = x; | ||
475 | ok=cb(0,ctx); | ||
476 | if (!ok) goto end; | ||
477 | } | ||
478 | } | ||
479 | /* Check pathlen */ | 411 | /* Check pathlen */ |
480 | if ((i > 1) && (x->ex_pathlen != -1) | 412 | if ((i > 1) && (x->ex_pathlen != -1) |
481 | && (i > (x->ex_pathlen + proxy_path_length + 1))) | 413 | && (i > (x->ex_pathlen + 1))) |
482 | { | 414 | { |
483 | ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED; | 415 | ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED; |
484 | ctx->error_depth = i; | 416 | ctx->error_depth = i; |
@@ -486,32 +418,6 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) | |||
486 | ok=cb(0,ctx); | 418 | ok=cb(0,ctx); |
487 | if (!ok) goto end; | 419 | if (!ok) goto end; |
488 | } | 420 | } |
489 | /* If this certificate is a proxy certificate, the next | ||
490 | certificate must be another proxy certificate or a EE | ||
491 | certificate. If not, the next certificate must be a | ||
492 | CA certificate. */ | ||
493 | if (x->ex_flags & EXFLAG_PROXY) | ||
494 | { | ||
495 | PROXY_CERT_INFO_EXTENSION *pci = | ||
496 | X509_get_ext_d2i(x, NID_proxyCertInfo, | ||
497 | NULL, NULL); | ||
498 | if (pci->pcPathLengthConstraint && | ||
499 | ASN1_INTEGER_get(pci->pcPathLengthConstraint) | ||
500 | < i) | ||
501 | { | ||
502 | PROXY_CERT_INFO_EXTENSION_free(pci); | ||
503 | ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED; | ||
504 | ctx->error_depth = i; | ||
505 | ctx->current_cert = x; | ||
506 | ok=cb(0,ctx); | ||
507 | if (!ok) goto end; | ||
508 | } | ||
509 | PROXY_CERT_INFO_EXTENSION_free(pci); | ||
510 | proxy_path_length++; | ||
511 | must_be_ca = 0; | ||
512 | } | ||
513 | else | ||
514 | must_be_ca = 1; | ||
515 | } | 421 | } |
516 | ok = 1; | 422 | ok = 1; |
517 | end: | 423 | end: |
@@ -721,15 +627,6 @@ static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) | |||
721 | X509_EXTENSION *ext; | 627 | X509_EXTENSION *ext; |
722 | /* Look for serial number of certificate in CRL */ | 628 | /* Look for serial number of certificate in CRL */ |
723 | rtmp.serialNumber = X509_get_serialNumber(x); | 629 | rtmp.serialNumber = X509_get_serialNumber(x); |
724 | /* Sort revoked into serial number order if not already sorted. | ||
725 | * Do this under a lock to avoid race condition. | ||
726 | */ | ||
727 | if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked)) | ||
728 | { | ||
729 | CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL); | ||
730 | sk_X509_REVOKED_sort(crl->crl->revoked); | ||
731 | CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL); | ||
732 | } | ||
733 | idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp); | 630 | idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp); |
734 | /* If found assume revoked: want something cleverer than | 631 | /* If found assume revoked: want something cleverer than |
735 | * this to handle entry extensions in V2 CRLs. | 632 | * this to handle entry extensions in V2 CRLs. |
@@ -875,7 +772,6 @@ static int internal_verify(X509_STORE_CTX *ctx) | |||
875 | } | 772 | } |
876 | 773 | ||
877 | /* The last error (if any) is still in the error value */ | 774 | /* The last error (if any) is still in the error value */ |
878 | ctx->current_issuer=xi; | ||
879 | ctx->current_cert=xs; | 775 | ctx->current_cert=xs; |
880 | ok=(*cb)(1,ctx); | 776 | ok=(*cb)(1,ctx); |
881 | if (!ok) goto end; | 777 | if (!ok) goto end; |
@@ -955,8 +851,7 @@ int X509_cmp_time(ASN1_TIME *ctm, time_t *cmp_time) | |||
955 | atm.length=sizeof(buff2); | 851 | atm.length=sizeof(buff2); |
956 | atm.data=(unsigned char *)buff2; | 852 | atm.data=(unsigned char *)buff2; |
957 | 853 | ||
958 | if (X509_time_adj(&atm,-offset*60, cmp_time) == NULL) | 854 | X509_time_adj(&atm,-offset*60, cmp_time); |
959 | return 0; | ||
960 | 855 | ||
961 | if (ctm->type == V_ASN1_UTCTIME) | 856 | if (ctm->type == V_ASN1_UTCTIME) |
962 | { | 857 | { |