summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbeck <>2017-01-20 00:37:40 +0000
committerbeck <>2017-01-20 00:37:40 +0000
commit321db821baef82b563a6e0e71b6f0f63acf63a1c (patch)
treef70fb9bc9a62ff972753aa24218db2699ff4444d /src
parentb36ec401a5f835078060753f1f3018ce948dbafe (diff)
downloadopenbsd-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.c204
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 */
1712static int
1713verify_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 */
1701int 1730int
1702x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int quiet) 1731x509_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
1754static int 1765static int
1755internal_verify(X509_STORE_CTX *ctx) 1766internal_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 }
1815check_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
1834end:
1835 return ok;
1836} 1836}
1837 1837
1838int 1838int
@@ -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