@@ -1675,6 +1675,146 @@ public void testAlgorithmConstraintsWithSHAVariant() throws Exception {
16751675 }
16761676 }
16771677
1678+ /**
1679+ * Test that revocation checking fails with UNDETERMINED_REVOCATION_STATUS
1680+ * when revocation is enabled but no CRLs are available and no
1681+ * PKIXRevocationChecker is registered for OCSP.
1682+ */
1683+ @ Test
1684+ public void testRevocationEnabledNoCRLsFailsWithUndeterminedStatus ()
1685+ throws FileNotFoundException , KeyStoreException , IOException ,
1686+ NoSuchAlgorithmException , CertificateException ,
1687+ InvalidAlgorithmParameterException , NoSuchProviderException ,
1688+ Exception {
1689+
1690+ KeyStore store = null ;
1691+ CertificateFactory certFactory = null ;
1692+ InputStream fis = null ;
1693+ Certificate serverCert = null ;
1694+ List <Certificate > certList = new ArrayList <>();
1695+
1696+ if (!WolfCrypt .CrlEnabled ()) {
1697+ /* Native CRL not enabled, skip test */
1698+ System .out .println ("CertPathValidator revocation status test " +
1699+ "skipped, CRL not compiled in" );
1700+ return ;
1701+ }
1702+
1703+ /* Use example KeyStore that verifies server-cert.der */
1704+ store = createKeyStoreFromFile (jksCaServerRSA2048 , keyStorePass );
1705+ if (store == null || store .size () != 1 ) {
1706+ throw new Exception ("Error creating KeyStore" );
1707+ }
1708+
1709+ certFactory = CertificateFactory .getInstance ("X.509" );
1710+
1711+ /* Import server-cert.der into Certificate object */
1712+ fis = new FileInputStream (serverCertDer );
1713+ serverCert = certFactory .generateCertificate (fis );
1714+ certList .add (serverCert );
1715+ fis .close ();
1716+
1717+ /* Create PKIXParameters with trusted KeyStore */
1718+ PKIXParameters params = new PKIXParameters (store );
1719+
1720+ /* Enable revocation checking but DO NOT add any CRLs or
1721+ * PKIXRevocationChecker. This should cause validation to fail
1722+ * with UNDETERMINED_REVOCATION_STATUS. */
1723+ params .setRevocationEnabled (true );
1724+ params .setCertStores (null );
1725+
1726+ /* Validate cert chain, should fail */
1727+ CertPath path = certFactory .generateCertPath (certList );
1728+ CertPathValidator cpv =
1729+ CertPathValidator .getInstance ("PKIX" , provider );
1730+
1731+ try {
1732+ cpv .validate (path , params );
1733+ fail ("Expected CertPathValidatorException with " +
1734+ "UNDETERMINED_REVOCATION_STATUS when revocation is enabled " +
1735+ "but no CRLs or OCSP checker is available" );
1736+
1737+ } catch (CertPathValidatorException e ) {
1738+ /* Expected - verify reason is UNDETERMINED_REVOCATION_STATUS */
1739+ assertEquals ("Expected BasicReason.UNDETERMINED_REVOCATION_STATUS" ,
1740+ BasicReason .UNDETERMINED_REVOCATION_STATUS , e .getReason ());
1741+ }
1742+ }
1743+
1744+ /**
1745+ * Test that revocation checking fails with UNDETERMINED_REVOCATION_STATUS
1746+ * when revocation is enabled and CertStores exist but contain no CRLs.
1747+ */
1748+ @ Test
1749+ public void testRevocationEnabledEmptyCertStoreFailsWithUndeterminedStatus ()
1750+ throws FileNotFoundException , KeyStoreException , IOException ,
1751+ NoSuchAlgorithmException , CertificateException ,
1752+ InvalidAlgorithmParameterException , NoSuchProviderException ,
1753+ Exception {
1754+
1755+ KeyStore store = null ;
1756+ CertificateFactory certFactory = null ;
1757+ InputStream fis = null ;
1758+ Certificate serverCert = null ;
1759+ List <Certificate > certList = new ArrayList <>();
1760+ CertStore emptyCertStore = null ;
1761+ List <CertStore > certStores = null ;
1762+
1763+ if (!WolfCrypt .CrlEnabled ()) {
1764+ /* Native CRL not enabled, skip test */
1765+ System .out .println ("CertPathValidator revocation status test " +
1766+ "skipped, CRL not compiled in" );
1767+ return ;
1768+ }
1769+
1770+ /* Use example KeyStore that verifies server-cert.der */
1771+ store = createKeyStoreFromFile (jksCaServerRSA2048 , keyStorePass );
1772+ if (store == null || store .size () != 1 ) {
1773+ throw new Exception ("Error creating KeyStore" );
1774+ }
1775+
1776+ certFactory = CertificateFactory .getInstance ("X.509" );
1777+
1778+ /* Import server-cert.der into Certificate object */
1779+ fis = new FileInputStream (serverCertDer );
1780+ serverCert = certFactory .generateCertificate (fis );
1781+ certList .add (serverCert );
1782+ fis .close ();
1783+
1784+ /* Create PKIXParameters with trusted KeyStore */
1785+ PKIXParameters params = new PKIXParameters (store );
1786+
1787+ /* Enable revocation checking with empty CertStore (no CRLs).
1788+ * This should cause validation to fail with
1789+ * UNDETERMINED_REVOCATION_STATUS. */
1790+ params .setRevocationEnabled (true );
1791+
1792+ /* Create empty CertStore */
1793+ Collection <CRL > emptyCrls = new HashSet <>();
1794+ emptyCertStore = CertStore .getInstance ("Collection" ,
1795+ new CollectionCertStoreParameters (emptyCrls ));
1796+ certStores = new ArrayList <>();
1797+ certStores .add (emptyCertStore );
1798+ params .setCertStores (certStores );
1799+
1800+ /* Validate cert chain, should fail */
1801+ CertPath path = certFactory .generateCertPath (certList );
1802+ CertPathValidator cpv =
1803+ CertPathValidator .getInstance ("PKIX" , provider );
1804+
1805+ try {
1806+ cpv .validate (path , params );
1807+ fail ("Expected CertPathValidatorException with " +
1808+ "UNDETERMINED_REVOCATION_STATUS when revocation is enabled " +
1809+ "but CertStore contains no CRLs" );
1810+
1811+ } catch (CertPathValidatorException e ) {
1812+ /* Expected - verify reason is UNDETERMINED_REVOCATION_STATUS */
1813+ assertEquals ("Expected BasicReason.UNDETERMINED_REVOCATION_STATUS" ,
1814+ BasicReason .UNDETERMINED_REVOCATION_STATUS , e .getReason ());
1815+ }
1816+ }
1817+
16781818 /**
16791819 * Test that zero-length cert paths are valid per RFC 5280. This occurs
16801820 * when CertPathBuilder determines the trust anchor itself is the target.
0 commit comments