summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/x509/x509_verify.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/x509/x509_verify.c')
-rw-r--r--src/lib/libcrypto/x509/x509_verify.c172
1 files changed, 78 insertions, 94 deletions
diff --git a/src/lib/libcrypto/x509/x509_verify.c b/src/lib/libcrypto/x509/x509_verify.c
index 8bcc647149..b9ba2bee3c 100644
--- a/src/lib/libcrypto/x509/x509_verify.c
+++ b/src/lib/libcrypto/x509/x509_verify.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: x509_verify.c,v 1.50 2021/10/26 15:14:18 job Exp $ */ 1/* $OpenBSD: x509_verify.c,v 1.51 2021/11/04 23:52:34 beck Exp $ */
2/* 2/*
3 * Copyright (c) 2020-2021 Bob Beck <beck@openbsd.org> 3 * Copyright (c) 2020-2021 Bob Beck <beck@openbsd.org>
4 * 4 *
@@ -38,7 +38,58 @@ static int x509_verify_cert_error(struct x509_verify_ctx *ctx, X509 *cert,
38 size_t depth, int error, int ok); 38 size_t depth, int error, int ok);
39static void x509_verify_chain_free(struct x509_verify_chain *chain); 39static void x509_verify_chain_free(struct x509_verify_chain *chain);
40 40
41#define X509_VERIFY_CERT_HASH (EVP_sha512()) 41/*
42 * Parse an asn1 to a representable time_t as per RFC 5280 rules.
43 * Returns -1 if that can't be done for any reason.
44 */
45time_t
46x509_verify_asn1_time_to_time_t(const ASN1_TIME *atime, int notAfter)
47{
48 struct tm tm = { 0 };
49 int type;
50
51 type = ASN1_time_parse(atime->data, atime->length, &tm, atime->type);
52 if (type == -1)
53 return -1;
54
55 /* RFC 5280 section 4.1.2.5 */
56 if (tm.tm_year < 150 && type != V_ASN1_UTCTIME)
57 return -1;
58 if (tm.tm_year >= 150 && type != V_ASN1_GENERALIZEDTIME)
59 return -1;
60
61 if (notAfter) {
62 /*
63 * If we are a completely broken operating system with a
64 * 32 bit time_t, and we have been told this is a notAfter
65 * date, limit the date to a 32 bit representable value.
66 */
67 if (!ASN1_time_tm_clamp_notafter(&tm))
68 return -1;
69 }
70
71 /*
72 * Defensively fail if the time string is not representable as
73 * a time_t. A time_t must be sane if you care about times after
74 * Jan 19 2038.
75 */
76 return timegm(&tm);
77}
78
79/*
80 * Cache certificate hash, and values parsed out of an X509.
81 * called from cache_extensions()
82 */
83void
84x509_verify_cert_info_populate(X509 *cert)
85{
86 /*
87 * Parse and save the cert times, or remember that they
88 * are unacceptable/unparsable.
89 */
90 cert->not_before = x509_verify_asn1_time_to_time_t(X509_get_notBefore(cert), 0);
91 cert->not_after = x509_verify_asn1_time_to_time_t(X509_get_notAfter(cert), 1);
92}
42 93
43struct x509_verify_chain * 94struct x509_verify_chain *
44x509_verify_chain_new(void) 95x509_verify_chain_new(void)
@@ -194,6 +245,7 @@ x509_verify_cert_cache_extensions(X509 *cert) {
194 } 245 }
195 if (cert->ex_flags & EXFLAG_INVALID) 246 if (cert->ex_flags & EXFLAG_INVALID)
196 return 0; 247 return 0;
248
197 return (cert->ex_flags & EXFLAG_SET); 249 return (cert->ex_flags & EXFLAG_SET);
198} 250}
199 251
@@ -455,22 +507,15 @@ x509_verify_potential_parent(struct x509_verify_ctx *ctx, X509 *parent,
455} 507}
456 508
457static int 509static int
458x509_verify_parent_signature(X509 *parent, X509 *child, 510x509_verify_parent_signature(X509 *parent, X509 *child, int *error)
459 unsigned char *child_md, int *error)
460{ 511{
461 unsigned char parent_md[EVP_MAX_MD_SIZE] = { 0 };
462 EVP_PKEY *pkey; 512 EVP_PKEY *pkey;
463 int cached; 513 int cached;
464 int ret = 0; 514 int ret = 0;
465 515
466 /* Use cached value if we have it */ 516 /* Use cached value if we have it */
467 if (child_md != NULL) { 517 if ((cached = x509_issuer_cache_find(parent->hash, child->hash)) >= 0)
468 if (!X509_digest(parent, X509_VERIFY_CERT_HASH, parent_md, 518 return cached;
469 NULL))
470 return 0;
471 if ((cached = x509_issuer_cache_find(parent_md, child_md)) >= 0)
472 return cached;
473 }
474 519
475 /* Check signature. Did parent sign child? */ 520 /* Check signature. Did parent sign child? */
476 if ((pkey = X509_get_pubkey(parent)) == NULL) { 521 if ((pkey = X509_get_pubkey(parent)) == NULL) {
@@ -483,8 +528,7 @@ x509_verify_parent_signature(X509 *parent, X509 *child,
483 ret = 1; 528 ret = 1;
484 529
485 /* Add result to cache */ 530 /* Add result to cache */
486 if (child_md != NULL) 531 x509_issuer_cache_add(parent->hash, child->hash, ret);
487 x509_issuer_cache_add(parent_md, child_md, ret);
488 532
489 EVP_PKEY_free(pkey); 533 EVP_PKEY_free(pkey);
490 534
@@ -493,8 +537,8 @@ x509_verify_parent_signature(X509 *parent, X509 *child,
493 537
494static int 538static int
495x509_verify_consider_candidate(struct x509_verify_ctx *ctx, X509 *cert, 539x509_verify_consider_candidate(struct x509_verify_ctx *ctx, X509 *cert,
496 unsigned char *cert_md, int is_root_cert, X509 *candidate, 540 int is_root_cert, X509 *candidate, struct x509_verify_chain *current_chain,
497 struct x509_verify_chain *current_chain, int full_chain) 541 int full_chain)
498{ 542{
499 int depth = sk_X509_num(current_chain->certs); 543 int depth = sk_X509_num(current_chain->certs);
500 struct x509_verify_chain *new_chain; 544 struct x509_verify_chain *new_chain;
@@ -514,8 +558,7 @@ x509_verify_consider_candidate(struct x509_verify_ctx *ctx, X509 *cert,
514 return 0; 558 return 0;
515 } 559 }
516 560
517 if (!x509_verify_parent_signature(candidate, cert, cert_md, 561 if (!x509_verify_parent_signature(candidate, cert, &ctx->error)) {
518 &ctx->error)) {
519 if (!x509_verify_cert_error(ctx, candidate, depth, 562 if (!x509_verify_cert_error(ctx, candidate, depth,
520 ctx->error, 0)) 563 ctx->error, 0))
521 return 0; 564 return 0;
@@ -579,7 +622,6 @@ static void
579x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, 622x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert,
580 struct x509_verify_chain *current_chain, int full_chain) 623 struct x509_verify_chain *current_chain, int full_chain)
581{ 624{
582 unsigned char cert_md[EVP_MAX_MD_SIZE] = { 0 };
583 X509 *candidate; 625 X509 *candidate;
584 int i, depth, count, ret, is_root; 626 int i, depth, count, ret, is_root;
585 627
@@ -600,11 +642,6 @@ x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert,
600 X509_V_ERR_CERT_CHAIN_TOO_LONG, 0)) 642 X509_V_ERR_CERT_CHAIN_TOO_LONG, 0))
601 return; 643 return;
602 644
603 if (!X509_digest(cert, X509_VERIFY_CERT_HASH, cert_md, NULL) &&
604 !x509_verify_cert_error(ctx, cert, depth,
605 X509_V_ERR_UNSPECIFIED, 0))
606 return;
607
608 count = ctx->chains_count; 645 count = ctx->chains_count;
609 646
610 ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; 647 ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
@@ -640,7 +677,7 @@ x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert,
640 is_root = !full_chain || 677 is_root = !full_chain ||
641 x509_verify_cert_self_signed(candidate); 678 x509_verify_cert_self_signed(candidate);
642 x509_verify_consider_candidate(ctx, cert, 679 x509_verify_consider_candidate(ctx, cert,
643 cert_md, is_root, candidate, current_chain, 680 is_root, candidate, current_chain,
644 full_chain); 681 full_chain);
645 } 682 }
646 X509_free(candidate); 683 X509_free(candidate);
@@ -653,7 +690,7 @@ x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert,
653 is_root = !full_chain || 690 is_root = !full_chain ||
654 x509_verify_cert_self_signed(candidate); 691 x509_verify_cert_self_signed(candidate);
655 x509_verify_consider_candidate(ctx, cert, 692 x509_verify_consider_candidate(ctx, cert,
656 cert_md, is_root, candidate, current_chain, 693 is_root, candidate, current_chain,
657 full_chain); 694 full_chain);
658 } 695 }
659 } 696 }
@@ -665,7 +702,7 @@ x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert,
665 candidate = sk_X509_value(ctx->intermediates, i); 702 candidate = sk_X509_value(ctx->intermediates, i);
666 if (x509_verify_potential_parent(ctx, candidate, cert)) { 703 if (x509_verify_potential_parent(ctx, candidate, cert)) {
667 x509_verify_consider_candidate(ctx, cert, 704 x509_verify_consider_candidate(ctx, cert,
668 cert_md, 0, candidate, current_chain, 705 0, candidate, current_chain,
669 full_chain); 706 full_chain);
670 } 707 }
671 } 708 }
@@ -748,47 +785,9 @@ x509_verify_set_check_time(struct x509_verify_ctx *ctx) {
748 return 1; 785 return 1;
749} 786}
750 787
751int
752x509_verify_asn1_time_to_tm(const ASN1_TIME *atime, struct tm *tm, int notafter)
753{
754 int type;
755
756 type = ASN1_time_parse(atime->data, atime->length, tm, atime->type);
757 if (type == -1)
758 return 0;
759
760 /* RFC 5280 section 4.1.2.5 */
761 if (tm->tm_year < 150 && type != V_ASN1_UTCTIME)
762 return 0;
763 if (tm->tm_year >= 150 && type != V_ASN1_GENERALIZEDTIME)
764 return 0;
765
766 if (notafter) {
767 /*
768 * If we are a completely broken operating system with a
769 * 32 bit time_t, and we have been told this is a notafter
770 * date, limit the date to a 32 bit representable value.
771 */
772 if (!ASN1_time_tm_clamp_notafter(tm))
773 return 0;
774 }
775
776 /*
777 * Defensively fail if the time string is not representable as
778 * a time_t. A time_t must be sane if you care about times after
779 * Jan 19 2038.
780 */
781 if (timegm(tm) == -1)
782 return 0;
783
784 return 1;
785}
786
787static int 788static int
788x509_verify_cert_time(int is_notafter, const ASN1_TIME *cert_asn1, 789x509_verify_cert_times(X509 *cert, time_t *cmp_time, int *error)
789 time_t *cmp_time, int *error)
790{ 790{
791 struct tm cert_tm, when_tm;
792 time_t when; 791 time_t when;
793 792
794 if (cmp_time == NULL) 793 if (cmp_time == NULL)
@@ -796,29 +795,21 @@ x509_verify_cert_time(int is_notafter, const ASN1_TIME *cert_asn1,
796 else 795 else
797 when = *cmp_time; 796 when = *cmp_time;
798 797
799 if (!x509_verify_asn1_time_to_tm(cert_asn1, &cert_tm, 798 if (cert->not_before == -1) {
800 is_notafter)) { 799 *error = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
801 *error = is_notafter ?
802 X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD :
803 X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
804 return 0; 800 return 0;
805 } 801 }
806 802 if (when < cert->not_before) {
807 if (gmtime_r(&when, &when_tm) == NULL) { 803 *error = X509_V_ERR_CERT_NOT_YET_VALID;
808 *error = X509_V_ERR_UNSPECIFIED;
809 return 0; 804 return 0;
810 } 805 }
811 806 if (cert->not_after == -1) {
812 if (is_notafter) { 807 *error = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD;
813 if (ASN1_time_tm_cmp(&cert_tm, &when_tm) == -1) { 808 return 0;
814 *error = X509_V_ERR_CERT_HAS_EXPIRED; 809 }
815 return 0; 810 if (when > cert->not_after) {
816 } 811 *error = X509_V_ERR_CERT_HAS_EXPIRED;
817 } else { 812 return 0;
818 if (ASN1_time_tm_cmp(&cert_tm, &when_tm) == 1) {
819 *error = X509_V_ERR_CERT_NOT_YET_VALID;
820 return 0;
821 }
822 } 813 }
823 814
824 return 1; 815 return 1;
@@ -924,15 +915,8 @@ x509_verify_cert_valid(struct x509_verify_ctx *ctx, X509 *cert,
924 } 915 }
925 916
926 if (x509_verify_set_check_time(ctx)) { 917 if (x509_verify_set_check_time(ctx)) {
927 if (!x509_verify_cert_time(0, X509_get_notBefore(cert), 918 if (!x509_verify_cert_times(cert, ctx->check_time,
928 ctx->check_time, &ctx->error)) { 919 &ctx->error)) {
929 if (!x509_verify_cert_error(ctx, cert, depth,
930 ctx->error, 0))
931 return 0;
932 }
933
934 if (!x509_verify_cert_time(1, X509_get_notAfter(cert),
935 ctx->check_time, &ctx->error)) {
936 if (!x509_verify_cert_error(ctx, cert, depth, 920 if (!x509_verify_cert_error(ctx, cert, depth,
937 ctx->error, 0)) 921 ctx->error, 0))
938 return 0; 922 return 0;