diff options
author | beck <> | 2017-01-20 00:37:40 +0000 |
---|---|---|
committer | beck <> | 2017-01-20 00:37:40 +0000 |
commit | 321db821baef82b563a6e0e71b6f0f63acf63a1c (patch) | |
tree | f70fb9bc9a62ff972753aa24218db2699ff4444d /src | |
parent | b36ec401a5f835078060753f1f3018ce948dbafe (diff) | |
download | openbsd-321db821baef82b563a6e0e71b6f0f63acf63a1c.tar.gz openbsd-321db821baef82b563a6e0e71b6f0f63acf63a1c.tar.bz2 openbsd-321db821baef82b563a6e0e71b6f0f63acf63a1c.zip |
Rework internal_verify, mostly from OpenSSL. so we can progress
towards cleaning up the V_OK stuff.
ok kinichiro@
Diffstat (limited to 'src')
-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 |