diff options
Diffstat (limited to '')
| -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 | ||
