diff options
author | tb <> | 2022-01-04 19:56:53 +0000 |
---|---|---|
committer | tb <> | 2022-01-04 19:56:53 +0000 |
commit | b12b3490ed823138c3caf219523ffd0555a07d88 (patch) | |
tree | 37c345670fecacfe422824c944e0fa99a25319f9 /src/lib | |
parent | 2609e55a77d1488ed932d4761f5b4025e6fadf9e (diff) | |
download | openbsd-b12b3490ed823138c3caf219523ffd0555a07d88.tar.gz openbsd-b12b3490ed823138c3caf219523ffd0555a07d88.tar.bz2 openbsd-b12b3490ed823138c3caf219523ffd0555a07d88.zip |
First pass over x509_addr_validate_path()
Replace reaching into the structs with IPAddressFamily accessors
and add a few comments that explain what the code is actually doing.
ok inoguchi jsing
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libcrypto/x509/x509_addr.c | 116 |
1 files changed, 79 insertions, 37 deletions
diff --git a/src/lib/libcrypto/x509/x509_addr.c b/src/lib/libcrypto/x509/x509_addr.c index de4e42acde..227d934806 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.48 2022/01/04 19:49:14 tb Exp $ */ | 1 | /* $OpenBSD: x509_addr.c,v 1.49 2022/01/04 19:56:53 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"). |
@@ -1688,9 +1688,13 @@ static int | |||
1688 | addr_validate_path_internal(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, | 1688 | addr_validate_path_internal(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, |
1689 | IPAddrBlocks *ext) | 1689 | IPAddrBlocks *ext) |
1690 | { | 1690 | { |
1691 | IPAddrBlocks *child = NULL; | 1691 | IPAddrBlocks *child = NULL, *parent = NULL; |
1692 | int i, j, ret = 1; | 1692 | IPAddressFamily *fc, *fp; |
1693 | IPAddressOrRanges *aorc, *aorp; | ||
1693 | X509 *x; | 1694 | X509 *x; |
1695 | int i, j, k; | ||
1696 | unsigned int length; | ||
1697 | int ret = 1; | ||
1694 | 1698 | ||
1695 | /* We need a non-empty chain to test against. */ | 1699 | /* We need a non-empty chain to test against. */ |
1696 | if (sk_X509_num(chain) <= 0) | 1700 | if (sk_X509_num(chain) <= 0) |
@@ -1733,59 +1737,95 @@ addr_validate_path_internal(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, | |||
1733 | */ | 1737 | */ |
1734 | for (i++; i < sk_X509_num(chain); i++) { | 1738 | for (i++; i < sk_X509_num(chain); i++) { |
1735 | x = sk_X509_value(chain, i); | 1739 | x = sk_X509_value(chain, i); |
1736 | if (!X509v3_addr_is_canonical(x->rfc3779_addr)) | 1740 | parent = x->rfc3779_addr; |
1741 | |||
1742 | if (!X509v3_addr_is_canonical(parent)) | ||
1737 | validation_err(X509_V_ERR_INVALID_EXTENSION); | 1743 | validation_err(X509_V_ERR_INVALID_EXTENSION); |
1738 | if (x->rfc3779_addr == NULL) { | 1744 | |
1745 | if (parent == NULL) { | ||
1739 | for (j = 0; j < sk_IPAddressFamily_num(child); j++) { | 1746 | for (j = 0; j < sk_IPAddressFamily_num(child); j++) { |
1740 | IPAddressFamily *fc = sk_IPAddressFamily_value(child, | 1747 | fc = sk_IPAddressFamily_value(child, j); |
1741 | j); | 1748 | |
1742 | if (fc->ipAddressChoice->type != | 1749 | if (IPAddressFamily_inheritance(fc) == NULL) { |
1743 | IPAddressChoice_inherit) { | ||
1744 | validation_err(X509_V_ERR_UNNESTED_RESOURCE); | 1750 | validation_err(X509_V_ERR_UNNESTED_RESOURCE); |
1745 | break; | 1751 | break; |
1746 | } | 1752 | } |
1747 | } | 1753 | } |
1748 | continue; | 1754 | continue; |
1749 | } | 1755 | } |
1750 | (void)sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr, | 1756 | |
1751 | IPAddressFamily_cmp); | 1757 | sk_IPAddressFamily_set_cmp_func(parent, IPAddressFamily_cmp); |
1758 | |||
1759 | /* | ||
1760 | * Check that the child's resources are covered by the parent. | ||
1761 | * Each covered resource is replaced with the parent's resource | ||
1762 | * covering it, so the next iteration will check that the | ||
1763 | * parent's resources are covered by the grandparent. | ||
1764 | */ | ||
1752 | for (j = 0; j < sk_IPAddressFamily_num(child); j++) { | 1765 | for (j = 0; j < sk_IPAddressFamily_num(child); j++) { |
1753 | IPAddressFamily *fc = sk_IPAddressFamily_value(child, j); | 1766 | fc = sk_IPAddressFamily_value(child, j); |
1754 | int k = sk_IPAddressFamily_find(x->rfc3779_addr, fc); | 1767 | |
1755 | IPAddressFamily *fp = | 1768 | k = sk_IPAddressFamily_find(parent, fc); |
1756 | sk_IPAddressFamily_value(x->rfc3779_addr, k); | 1769 | fp = sk_IPAddressFamily_value(parent, k); |
1770 | |||
1757 | if (fp == NULL) { | 1771 | if (fp == NULL) { |
1758 | if (fc->ipAddressChoice->type == | 1772 | /* |
1759 | IPAddressChoice_addressesOrRanges) { | 1773 | * If we have no match in the parent and the |
1760 | validation_err(X509_V_ERR_UNNESTED_RESOURCE); | 1774 | * child inherits, that's fine. |
1761 | break; | 1775 | */ |
1762 | } | 1776 | if (IPAddressFamily_inheritance(fc) != NULL) |
1777 | continue; | ||
1778 | |||
1779 | /* Otherwise the child isn't covered. */ | ||
1780 | validation_err(X509_V_ERR_UNNESTED_RESOURCE); | ||
1781 | break; | ||
1782 | } | ||
1783 | |||
1784 | /* Parent inherits, nothing to do. */ | ||
1785 | if (IPAddressFamily_inheritance(fp) != NULL) | ||
1786 | continue; | ||
1787 | |||
1788 | /* Child inherits. Use parent's address family. */ | ||
1789 | if (IPAddressFamily_inheritance(fc) != NULL) { | ||
1790 | sk_IPAddressFamily_set(child, j, fp); | ||
1763 | continue; | 1791 | continue; |
1764 | } | 1792 | } |
1765 | if (fp->ipAddressChoice->type == | 1793 | |
1766 | IPAddressChoice_addressesOrRanges) { | 1794 | aorc = IPAddressFamily_addressesOrRanges(fc); |
1767 | if (fc->ipAddressChoice->type == | 1795 | aorp = IPAddressFamily_addressesOrRanges(fp); |
1768 | IPAddressChoice_inherit || | 1796 | |
1769 | addr_contains(fp->ipAddressChoice->u.addressesOrRanges, | 1797 | /* |
1770 | fc->ipAddressChoice->u.addressesOrRanges, | 1798 | * Child and parent are canonical and neither inherits. |
1771 | length_from_afi(X509v3_addr_get_afi(fc)))) | 1799 | * If either addressesOrRanges is NULL, something's |
1772 | sk_IPAddressFamily_set(child, j, fp); | 1800 | * very wrong. |
1773 | else | 1801 | */ |
1774 | validation_err(X509_V_ERR_UNNESTED_RESOURCE); | 1802 | if (aorc == NULL || aorp == NULL) |
1803 | goto err; | ||
1804 | |||
1805 | if (!IPAddressFamily_afi_length(fc, &length)) | ||
1806 | goto err; | ||
1807 | |||
1808 | /* Now check containment and replace or error. */ | ||
1809 | if (addr_contains(aorp, aorc, length)) { | ||
1810 | sk_IPAddressFamily_set(child, j, fp); | ||
1811 | continue; | ||
1775 | } | 1812 | } |
1813 | |||
1814 | validation_err(X509_V_ERR_UNNESTED_RESOURCE); | ||
1776 | } | 1815 | } |
1777 | } | 1816 | } |
1778 | 1817 | ||
1779 | /* | 1818 | /* |
1780 | * Trust anchor can't inherit. | 1819 | * Trust anchor can't inherit. |
1781 | */ | 1820 | */ |
1782 | if (x->rfc3779_addr != NULL) { | 1821 | if ((parent = x->rfc3779_addr) != NULL) { |
1783 | for (j = 0; j < sk_IPAddressFamily_num(x->rfc3779_addr); j++) { | 1822 | for (j = 0; j < sk_IPAddressFamily_num(parent); j++) { |
1784 | IPAddressFamily *fp = | 1823 | fp = sk_IPAddressFamily_value(parent, j); |
1785 | sk_IPAddressFamily_value(x->rfc3779_addr, j); | 1824 | |
1786 | if (fp->ipAddressChoice->type == | 1825 | if (IPAddressFamily_inheritance(fp) == NULL) |
1787 | IPAddressChoice_inherit && | 1826 | continue; |
1788 | sk_IPAddressFamily_find(child, fp) >= 0) | 1827 | |
1828 | if (sk_IPAddressFamily_find(child, fp) >= 0) | ||
1789 | validation_err(X509_V_ERR_UNNESTED_RESOURCE); | 1829 | validation_err(X509_V_ERR_UNNESTED_RESOURCE); |
1790 | } | 1830 | } |
1791 | } | 1831 | } |
@@ -1795,6 +1835,8 @@ addr_validate_path_internal(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, | |||
1795 | return ret; | 1835 | return ret; |
1796 | 1836 | ||
1797 | err: | 1837 | err: |
1838 | sk_IPAddressFamily_free(child); | ||
1839 | |||
1798 | if (ctx != NULL) | 1840 | if (ctx != NULL) |
1799 | ctx->error = X509_V_ERR_UNSPECIFIED; | 1841 | ctx->error = X509_V_ERR_UNSPECIFIED; |
1800 | 1842 | ||