diff options
author | tb <> | 2022-04-21 04:48:12 +0000 |
---|---|---|
committer | tb <> | 2022-04-21 04:48:12 +0000 |
commit | 10d8ec22a81b906974b9ddc26f92c35523c5284c (patch) | |
tree | 4480c2ae34abee044d787297e3befc8eb30fa3a2 /src | |
parent | 45b8140d971deab0e2970c393ed60019bd1b94ba (diff) | |
download | openbsd-10d8ec22a81b906974b9ddc26f92c35523c5284c.tar.gz openbsd-10d8ec22a81b906974b9ddc26f92c35523c5284c.tar.bz2 openbsd-10d8ec22a81b906974b9ddc26f92c35523c5284c.zip |
Avoid expensive RFC 3779 checks during cert verification
X509v3_{addr,asid}_is_canonical() check that the ipAddrBlocks and
autonomousSysIds extension conform to RFC 3779. These checks are not
cheap. Certs containing non-conformant extensions should not be
considered valid, so mark them with EXFLAG_INVALID while caching the
extension information in x509v3_cache_extensions(). This way the
expensive check while walking the chains during X509_verify_cert() is
replaced with a cheap check of the extension flags. This avoids a lot
of superfluous work when validating numerous certs with similar chains
against the same roots as is done in rpki-client.
Issue noticed and fix suggested by claudio
ok claudio inoguchi jsing
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libcrypto/x509/x509_addr.c | 20 | ||||
-rw-r--r-- | src/lib/libcrypto/x509/x509_asid.c | 12 | ||||
-rw-r--r-- | src/lib/libcrypto/x509/x509_purp.c | 6 |
3 files changed, 22 insertions, 16 deletions
diff --git a/src/lib/libcrypto/x509/x509_addr.c b/src/lib/libcrypto/x509/x509_addr.c index 035353826b..d33d4f2f8e 100644 --- a/src/lib/libcrypto/x509/x509_addr.c +++ b/src/lib/libcrypto/x509/x509_addr.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: x509_addr.c,v 1.78 2022/03/16 11:44:36 tb Exp $ */ | 1 | /* $OpenBSD: x509_addr.c,v 1.79 2022/04/21 04:48:12 tb Exp $ */ |
2 | /* | 2 | /* |
3 | * Contributed to the OpenSSL Project by the American Registry for | 3 | * Contributed to the OpenSSL Project by the American Registry for |
4 | * Internet Numbers ("ARIN"). | 4 | * Internet Numbers ("ARIN"). |
@@ -1780,11 +1780,11 @@ addr_validate_path_internal(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, | |||
1780 | if (ext == NULL) { | 1780 | if (ext == NULL) { |
1781 | depth = 0; | 1781 | depth = 0; |
1782 | cert = sk_X509_value(chain, depth); | 1782 | cert = sk_X509_value(chain, depth); |
1783 | if ((X509_get_extension_flags(cert) & EXFLAG_INVALID) != 0) | ||
1784 | goto done; | ||
1783 | if ((ext = cert->rfc3779_addr) == NULL) | 1785 | if ((ext = cert->rfc3779_addr) == NULL) |
1784 | goto done; | 1786 | goto done; |
1785 | } | 1787 | } else if (!X509v3_addr_is_canonical(ext)) { |
1786 | |||
1787 | if (!X509v3_addr_is_canonical(ext)) { | ||
1788 | if ((ret = verify_error(ctx, cert, | 1788 | if ((ret = verify_error(ctx, cert, |
1789 | X509_V_ERR_INVALID_EXTENSION, depth)) == 0) | 1789 | X509_V_ERR_INVALID_EXTENSION, depth)) == 0) |
1790 | goto done; | 1790 | goto done; |
@@ -1806,6 +1806,12 @@ addr_validate_path_internal(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, | |||
1806 | for (depth++; depth < sk_X509_num(chain); depth++) { | 1806 | for (depth++; depth < sk_X509_num(chain); depth++) { |
1807 | cert = sk_X509_value(chain, depth); | 1807 | cert = sk_X509_value(chain, depth); |
1808 | 1808 | ||
1809 | if ((X509_get_extension_flags(cert) & EXFLAG_INVALID) != 0) { | ||
1810 | if ((ret = verify_error(ctx, cert, | ||
1811 | X509_V_ERR_INVALID_EXTENSION, depth)) == 0) | ||
1812 | goto done; | ||
1813 | } | ||
1814 | |||
1809 | if ((parent = cert->rfc3779_addr) == NULL) { | 1815 | if ((parent = cert->rfc3779_addr) == NULL) { |
1810 | for (i = 0; i < sk_IPAddressFamily_num(child); i++) { | 1816 | for (i = 0; i < sk_IPAddressFamily_num(child); i++) { |
1811 | child_af = sk_IPAddressFamily_value(child, i); | 1817 | child_af = sk_IPAddressFamily_value(child, i); |
@@ -1822,12 +1828,6 @@ addr_validate_path_internal(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, | |||
1822 | continue; | 1828 | continue; |
1823 | } | 1829 | } |
1824 | 1830 | ||
1825 | if (!X509v3_addr_is_canonical(parent)) { | ||
1826 | if ((ret = verify_error(ctx, cert, | ||
1827 | X509_V_ERR_INVALID_EXTENSION, depth)) == 0) | ||
1828 | goto done; | ||
1829 | } | ||
1830 | |||
1831 | /* | 1831 | /* |
1832 | * Check that the child's resources are covered by the parent. | 1832 | * Check that the child's resources are covered by the parent. |
1833 | * Each covered resource is replaced with the parent's resource | 1833 | * Each covered resource is replaced with the parent's resource |
diff --git a/src/lib/libcrypto/x509/x509_asid.c b/src/lib/libcrypto/x509/x509_asid.c index c82f2f32cc..5f43b3030d 100644 --- a/src/lib/libcrypto/x509/x509_asid.c +++ b/src/lib/libcrypto/x509/x509_asid.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: x509_asid.c,v 1.30 2021/12/25 15:46:05 tb Exp $ */ | 1 | /* $OpenBSD: x509_asid.c,v 1.31 2022/04/21 04:48:12 tb Exp $ */ |
2 | /* | 2 | /* |
3 | * Contributed to the OpenSSL Project by the American Registry for | 3 | * Contributed to the OpenSSL Project by the American Registry for |
4 | * Internet Numbers ("ARIN"). | 4 | * Internet Numbers ("ARIN"). |
@@ -1006,14 +1006,16 @@ asid_validate_path_internal(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, | |||
1006 | if (ext != NULL) { | 1006 | if (ext != NULL) { |
1007 | i = -1; | 1007 | i = -1; |
1008 | x = NULL; | 1008 | x = NULL; |
1009 | if (!X509v3_asid_is_canonical(ext)) | ||
1010 | validation_err(X509_V_ERR_INVALID_EXTENSION); | ||
1009 | } else { | 1011 | } else { |
1010 | i = 0; | 1012 | i = 0; |
1011 | x = sk_X509_value(chain, i); | 1013 | x = sk_X509_value(chain, i); |
1014 | if ((X509_get_extension_flags(x) & EXFLAG_INVALID) != 0) | ||
1015 | goto done; | ||
1012 | if ((ext = x->rfc3779_asid) == NULL) | 1016 | if ((ext = x->rfc3779_asid) == NULL) |
1013 | goto done; | 1017 | goto done; |
1014 | } | 1018 | } |
1015 | if (!X509v3_asid_is_canonical(ext)) | ||
1016 | validation_err(X509_V_ERR_INVALID_EXTENSION); | ||
1017 | if (ext->asnum != NULL) { | 1019 | if (ext->asnum != NULL) { |
1018 | switch (ext->asnum->type) { | 1020 | switch (ext->asnum->type) { |
1019 | case ASIdentifierChoice_inherit: | 1021 | case ASIdentifierChoice_inherit: |
@@ -1042,13 +1044,13 @@ asid_validate_path_internal(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, | |||
1042 | for (i++; i < sk_X509_num(chain); i++) { | 1044 | for (i++; i < sk_X509_num(chain); i++) { |
1043 | x = sk_X509_value(chain, i); | 1045 | x = sk_X509_value(chain, i); |
1044 | 1046 | ||
1047 | if ((X509_get_extension_flags(x) & EXFLAG_INVALID) != 0) | ||
1048 | validation_err(X509_V_ERR_INVALID_EXTENSION); | ||
1045 | if (x->rfc3779_asid == NULL) { | 1049 | if (x->rfc3779_asid == NULL) { |
1046 | if (child_as != NULL || child_rdi != NULL) | 1050 | if (child_as != NULL || child_rdi != NULL) |
1047 | validation_err(X509_V_ERR_UNNESTED_RESOURCE); | 1051 | validation_err(X509_V_ERR_UNNESTED_RESOURCE); |
1048 | continue; | 1052 | continue; |
1049 | } | 1053 | } |
1050 | if (!X509v3_asid_is_canonical(x->rfc3779_asid)) | ||
1051 | validation_err(X509_V_ERR_INVALID_EXTENSION); | ||
1052 | if (x->rfc3779_asid->asnum == NULL && child_as != NULL) { | 1054 | if (x->rfc3779_asid->asnum == NULL && child_as != NULL) { |
1053 | validation_err(X509_V_ERR_UNNESTED_RESOURCE); | 1055 | validation_err(X509_V_ERR_UNNESTED_RESOURCE); |
1054 | child_as = NULL; | 1056 | child_as = NULL; |
diff --git a/src/lib/libcrypto/x509/x509_purp.c b/src/lib/libcrypto/x509/x509_purp.c index 4d833f73ba..ffd986b4a1 100644 --- a/src/lib/libcrypto/x509/x509_purp.c +++ b/src/lib/libcrypto/x509/x509_purp.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: x509_purp.c,v 1.14 2022/04/21 04:24:51 tb Exp $ */ | 1 | /* $OpenBSD: x509_purp.c,v 1.15 2022/04/21 04:48:12 tb Exp $ */ |
2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
3 | * project 2001. | 3 | * project 2001. |
4 | */ | 4 | */ |
@@ -600,9 +600,13 @@ x509v3_cache_extensions(X509 *x) | |||
600 | x->rfc3779_addr = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, &i, NULL); | 600 | x->rfc3779_addr = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, &i, NULL); |
601 | if (x->rfc3779_addr == NULL && i != -1) | 601 | if (x->rfc3779_addr == NULL && i != -1) |
602 | x->ex_flags |= EXFLAG_INVALID; | 602 | x->ex_flags |= EXFLAG_INVALID; |
603 | if (!X509v3_addr_is_canonical(x->rfc3779_addr)) | ||
604 | x->ex_flags |= EXFLAG_INVALID; | ||
603 | x->rfc3779_asid = X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum, &i, NULL); | 605 | x->rfc3779_asid = X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum, &i, NULL); |
604 | if (x->rfc3779_asid == NULL && i != -1) | 606 | if (x->rfc3779_asid == NULL && i != -1) |
605 | x->ex_flags |= EXFLAG_INVALID; | 607 | x->ex_flags |= EXFLAG_INVALID; |
608 | if (!X509v3_asid_is_canonical(x->rfc3779_asid)) | ||
609 | x->ex_flags |= EXFLAG_INVALID; | ||
606 | #endif | 610 | #endif |
607 | 611 | ||
608 | for (i = 0; i < X509_get_ext_count(x); i++) { | 612 | for (i = 0; i < X509_get_ext_count(x); i++) { |