diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libcrypto/x509/x509_vfy.c | 204 |
1 files changed, 102 insertions, 102 deletions
diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c index a2247bcc5b..c09a2c362f 100644 --- a/src/lib/libcrypto/x509/x509_vfy.c +++ b/src/lib/libcrypto/x509/x509_vfy.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: x509_vfy.c,v 1.56 2017/01/07 13:49:07 jsing Exp $ */ | 1 | /* $OpenBSD: x509_vfy.c,v 1.57 2017/01/20 00:37:40 beck Exp $ */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -243,7 +243,7 @@ X509_verify_cert(X509_STORE_CTX *ctx) | |||
| 243 | ctx->error = X509_V_ERR_INVALID_CALL; | 243 | ctx->error = X509_V_ERR_INVALID_CALL; |
| 244 | return -1; | 244 | return -1; |
| 245 | } | 245 | } |
| 246 | if (ctx->error != X509_V_ERR_UNSPECIFIED) { | 246 | if (ctx->error != X509_V_ERR_INVALID_CALL) { |
| 247 | /* | 247 | /* |
| 248 | * This X509_STORE_CTX has not been properly initialized. | 248 | * This X509_STORE_CTX has not been properly initialized. |
| 249 | */ | 249 | */ |
| @@ -562,7 +562,7 @@ find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x) | |||
| 562 | issuer = sk_X509_value(sk, i); | 562 | issuer = sk_X509_value(sk, i); |
| 563 | if (ctx->check_issued(ctx, x, issuer)) { | 563 | if (ctx->check_issued(ctx, x, issuer)) { |
| 564 | rv = issuer; | 564 | rv = issuer; |
| 565 | if (x509_check_cert_time(ctx, rv, 1)) | 565 | if (x509_check_cert_time(ctx, rv, -1)) |
| 566 | break; | 566 | break; |
| 567 | } | 567 | } |
| 568 | } | 568 | } |
| @@ -1698,141 +1698,141 @@ check_policy(X509_STORE_CTX *ctx) | |||
| 1698 | return 1; | 1698 | return 1; |
| 1699 | } | 1699 | } |
| 1700 | 1700 | ||
| 1701 | /* | ||
| 1702 | * Inform the verify callback of an error. | ||
| 1703 | * | ||
| 1704 | * If x is not NULL it is the error cert, otherwise use the chain cert | ||
| 1705 | * at depth. | ||
| 1706 | * | ||
| 1707 | * If err is not X509_V_OK, that's the error value, otherwise leave | ||
| 1708 | * unchanged (presumably set by the caller). | ||
| 1709 | * | ||
| 1710 | * Returns 0 to abort verification with an error, non-zero to continue. | ||
| 1711 | */ | ||
| 1712 | static int | ||
| 1713 | verify_cb_cert(X509_STORE_CTX *ctx, X509 *x, int depth, int err) | ||
| 1714 | { | ||
| 1715 | ctx->error_depth = depth; | ||
| 1716 | ctx->current_cert = (x != NULL) ? x : sk_X509_value(ctx->chain, depth); | ||
| 1717 | if (err != X509_V_OK) | ||
| 1718 | ctx->error = err; | ||
| 1719 | return ctx->verify_cb(0, ctx); | ||
| 1720 | } | ||
| 1721 | |||
| 1722 | /* | ||
| 1723 | * Check certificate validity times. | ||
| 1724 | * | ||
| 1725 | * If depth >= 0, invoke verification callbacks on error, otherwise just return | ||
| 1726 | * the validation status. | ||
| 1727 | * | ||
| 1728 | * Return 1 on success, 0 otherwise. | ||
| 1729 | */ | ||
| 1701 | int | 1730 | int |
| 1702 | x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int quiet) | 1731 | x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth) |
| 1703 | { | 1732 | { |
| 1704 | time_t *ptime = NULL; | 1733 | time_t *ptime; |
| 1705 | int i; | 1734 | int i; |
| 1706 | 1735 | ||
| 1707 | if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME) | ||
| 1708 | return (1); | ||
| 1709 | |||
| 1710 | if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) | 1736 | if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) |
| 1711 | ptime = &ctx->param->check_time; | 1737 | ptime = &ctx->param->check_time; |
| 1738 | else if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME) | ||
| 1739 | return 1; | ||
| 1740 | else | ||
| 1741 | ptime = NULL; | ||
| 1712 | 1742 | ||
| 1713 | i = X509_cmp_time(X509_get_notBefore(x), ptime); | 1743 | i = X509_cmp_time(X509_get_notBefore(x), ptime); |
| 1714 | if (i == 0) { | 1744 | if (i >= 0 && depth < 0) |
| 1715 | if (quiet) | 1745 | return 0; |
| 1716 | return 0; | 1746 | if (i == 0 && !verify_cb_cert(ctx, x, depth, |
| 1717 | ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; | 1747 | X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD)) |
| 1718 | ctx->current_cert = x; | 1748 | return 0; |
| 1719 | if (!ctx->verify_cb(0, ctx)) | 1749 | if (i > 0 && !verify_cb_cert(ctx, x, depth, |
| 1720 | return 0; | 1750 | X509_V_ERR_CERT_NOT_YET_VALID)) |
| 1721 | } | 1751 | return 0; |
| 1722 | |||
| 1723 | if (i > 0) { | ||
| 1724 | if (quiet) | ||
| 1725 | return 0; | ||
| 1726 | ctx->error = X509_V_ERR_CERT_NOT_YET_VALID; | ||
| 1727 | ctx->current_cert = x; | ||
| 1728 | if (!ctx->verify_cb(0, ctx)) | ||
| 1729 | return 0; | ||
| 1730 | } | ||
| 1731 | 1752 | ||
| 1732 | i = X509_cmp_time(X509_get_notAfter(x), ptime); | 1753 | i = X509_cmp_time(X509_get_notAfter(x), ptime); |
| 1733 | if (i == 0) { | 1754 | if (i <= 0 && depth < 0) |
| 1734 | if (quiet) | 1755 | return 0; |
| 1735 | return 0; | 1756 | if (i == 0 && !verify_cb_cert(ctx, x, depth, |
| 1736 | ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD; | 1757 | X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD)) |
| 1737 | ctx->current_cert = x; | 1758 | return 0; |
| 1738 | if (!ctx->verify_cb(0, ctx)) | 1759 | if (i < 0 && !verify_cb_cert(ctx, x, depth, |
| 1739 | return 0; | 1760 | X509_V_ERR_CERT_HAS_EXPIRED)) |
| 1740 | } | 1761 | return 0; |
| 1741 | |||
| 1742 | if (i < 0) { | ||
| 1743 | if (quiet) | ||
| 1744 | return 0; | ||
| 1745 | ctx->error = X509_V_ERR_CERT_HAS_EXPIRED; | ||
| 1746 | ctx->current_cert = x; | ||
| 1747 | if (!ctx->verify_cb(0, ctx)) | ||
| 1748 | return 0; | ||
| 1749 | } | ||
| 1750 | |||
| 1751 | return 1; | 1762 | return 1; |
| 1752 | } | 1763 | } |
| 1753 | 1764 | ||
| 1754 | static int | 1765 | static int |
| 1755 | internal_verify(X509_STORE_CTX *ctx) | 1766 | internal_verify(X509_STORE_CTX *ctx) |
| 1756 | { | 1767 | { |
| 1757 | int ok = 0, n; | 1768 | int n = sk_X509_num(ctx->chain) - 1; |
| 1758 | X509 *xs, *xi; | 1769 | X509 *xi = sk_X509_value(ctx->chain, n); |
| 1759 | EVP_PKEY *pkey = NULL; | 1770 | X509 *xs; |
| 1760 | int (*cb)(int xok, X509_STORE_CTX *xctx); | ||
| 1761 | |||
| 1762 | cb = ctx->verify_cb; | ||
| 1763 | |||
| 1764 | n = sk_X509_num(ctx->chain); | ||
| 1765 | ctx->error_depth = n - 1; | ||
| 1766 | n--; | ||
| 1767 | xi = sk_X509_value(ctx->chain, n); | ||
| 1768 | 1771 | ||
| 1769 | if (ctx->check_issued(ctx, xi, xi)) | 1772 | if (ctx->check_issued(ctx, xi, xi)) |
| 1770 | xs = xi; | 1773 | xs = xi; |
| 1771 | else { | 1774 | else { |
| 1772 | if (n <= 0) { | 1775 | if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) { |
| 1773 | ctx->error = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE; | 1776 | xs = xi; |
| 1774 | ctx->current_cert = xi; | 1777 | goto check_cert; |
| 1775 | ok = cb(0, ctx); | ||
| 1776 | goto end; | ||
| 1777 | } else { | ||
| 1778 | n--; | ||
| 1779 | ctx->error_depth = n; | ||
| 1780 | xs = sk_X509_value(ctx->chain, n); | ||
| 1781 | } | 1778 | } |
| 1779 | if (n <= 0) | ||
| 1780 | return verify_cb_cert(ctx, xi, 0, | ||
| 1781 | X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE); | ||
| 1782 | n--; | ||
| 1783 | ctx->error_depth = n; | ||
| 1784 | xs = sk_X509_value(ctx->chain, n); | ||
| 1782 | } | 1785 | } |
| 1783 | 1786 | ||
| 1784 | /* ctx->error=0; not needed */ | 1787 | /* |
| 1788 | * Do not clear ctx->error=0, it must be "sticky", only the | ||
| 1789 | * user's callback is allowed to reset errors (at its own | ||
| 1790 | * peril). | ||
| 1791 | */ | ||
| 1785 | while (n >= 0) { | 1792 | while (n >= 0) { |
| 1786 | ctx->error_depth = n; | 1793 | EVP_PKEY *pkey; |
| 1787 | 1794 | ||
| 1788 | /* Skip signature check for self signed certificates unless | 1795 | /* |
| 1789 | * explicitly asked for. It doesn't add any security and | 1796 | * Skip signature check for self signed certificates |
| 1790 | * just wastes time. | 1797 | * unless explicitly asked for. It doesn't add any |
| 1798 | * security and just wastes time. If the issuer's | ||
| 1799 | * public key is unusable, report the issuer | ||
| 1800 | * certificate and its depth (rather than the depth of | ||
| 1801 | * the subject). | ||
| 1791 | */ | 1802 | */ |
| 1792 | if (!xs->valid && (xs != xi || | 1803 | if (xs != xi || (ctx->param->flags & |
| 1793 | (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE))) { | 1804 | X509_V_FLAG_CHECK_SS_SIGNATURE)) { |
| 1794 | if ((pkey = X509_get_pubkey(xi)) == NULL) { | 1805 | if ((pkey = X509_get_pubkey(xi)) == NULL) { |
| 1795 | ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; | 1806 | if (!verify_cb_cert(ctx, xi, xi != xs ? n+1 : n, |
| 1796 | ctx->current_cert = xi; | 1807 | X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY)) |
| 1797 | ok = (*cb)(0, ctx); | 1808 | return 0; |
| 1798 | if (!ok) | ||
| 1799 | goto end; | ||
| 1800 | } else if (X509_verify(xs, pkey) <= 0) { | 1809 | } else if (X509_verify(xs, pkey) <= 0) { |
| 1801 | ctx->error = X509_V_ERR_CERT_SIGNATURE_FAILURE; | 1810 | if (!verify_cb_cert(ctx, xs, n, |
| 1802 | ctx->current_cert = xs; | 1811 | X509_V_ERR_CERT_SIGNATURE_FAILURE)) |
| 1803 | ok = (*cb)(0, ctx); | 1812 | return 0; |
| 1804 | if (!ok) { | ||
| 1805 | EVP_PKEY_free(pkey); | ||
| 1806 | goto end; | ||
| 1807 | } | ||
| 1808 | } | 1813 | } |
| 1809 | EVP_PKEY_free(pkey); | ||
| 1810 | pkey = NULL; | ||
| 1811 | } | 1814 | } |
| 1815 | check_cert: | ||
| 1816 | /* Calls verify callback as needed */ | ||
| 1817 | if (!x509_check_cert_time(ctx, xs, n)) | ||
| 1818 | return 0; | ||
| 1812 | 1819 | ||
| 1813 | xs->valid = 1; | 1820 | /* |
| 1814 | 1821 | * Signal success at this depth. However, the | |
| 1815 | ok = x509_check_cert_time(ctx, xs, 0); | 1822 | * previous error (if any) is retained. |
| 1816 | if (!ok) | 1823 | */ |
| 1817 | goto end; | ||
| 1818 | |||
| 1819 | /* The last error (if any) is still in the error value */ | ||
| 1820 | ctx->current_issuer = xi; | 1824 | ctx->current_issuer = xi; |
| 1821 | ctx->current_cert = xs; | 1825 | ctx->current_cert = xs; |
| 1822 | ok = (*cb)(1, ctx); | 1826 | ctx->error_depth = n; |
| 1823 | if (!ok) | 1827 | if (!ctx->verify_cb(1, ctx)) |
| 1824 | goto end; | 1828 | return 0; |
| 1825 | 1829 | ||
| 1826 | n--; | 1830 | if (--n >= 0) { |
| 1827 | if (n >= 0) { | ||
| 1828 | xi = xs; | 1831 | xi = xs; |
| 1829 | xs = sk_X509_value(ctx->chain, n); | 1832 | xs = sk_X509_value(ctx->chain, n); |
| 1830 | } | 1833 | } |
| 1831 | } | 1834 | } |
| 1832 | ok = 1; | 1835 | return 1; |
| 1833 | |||
| 1834 | end: | ||
| 1835 | return ok; | ||
| 1836 | } | 1836 | } |
| 1837 | 1837 | ||
| 1838 | int | 1838 | int |
| @@ -2177,9 +2177,9 @@ X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, | |||
| 2177 | 2177 | ||
| 2178 | /* | 2178 | /* |
| 2179 | * Start with this set to not valid - it will be set to valid | 2179 | * Start with this set to not valid - it will be set to valid |
| 2180 | * in X509_verify_cert. | 2180 | * in X509_verify_cert, or before the callback is called. |
| 2181 | */ | 2181 | */ |
| 2182 | ctx->error = X509_V_ERR_UNSPECIFIED; | 2182 | ctx->error = X509_V_ERR_INVALID_CALL; |
| 2183 | 2183 | ||
| 2184 | /* | 2184 | /* |
| 2185 | * Set values other than 0. Keep this in the same order as | 2185 | * Set values other than 0. Keep this in the same order as |
