package org.apereo.cas.adaptors.x509.authentication.handler.support; import org.apereo.cas.adaptors.x509.authentication.ExpiredCRLException; import org.apereo.cas.adaptors.x509.authentication.revocation.policy.ThresholdExpiredCRLRevocationPolicy; import org.apereo.cas.util.DateTimeUtils; import org.apereo.cas.adaptors.x509.util.MockX509CRL; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import javax.security.auth.x500.X500Principal; import java.security.GeneralSecurityException; import java.security.cert.X509CRL; import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Collection; /** * Unit test for {@link ThresholdExpiredCRLRevocationPolicy} class. * * @author Marvin S. Addison * @since 3.4.7 * */ @RunWith(Parameterized.class) public class ThresholdExpiredCRLRevocationPolicyTests { /** Policy instance under test. */ private final ThresholdExpiredCRLRevocationPolicy policy; /** CRL to test. */ private final X509CRL crl; /** Expected result of check; null for success */ private final GeneralSecurityException expected; /** * Creates a new test instance with given parameters. * * @param policy Policy to test. * @param crl CRL instance to apply policy to. * @param expected Expected result of policy application; null to indicate expected success. */ public ThresholdExpiredCRLRevocationPolicyTests( final ThresholdExpiredCRLRevocationPolicy policy, final X509CRL crl, final GeneralSecurityException expected) { this.policy = policy; this.expected = expected; this.crl = crl; } /** * Gets the unit test parameters. * * @return Test parameter data. * @throws Exception if there is an exception getting the test parameters. */ @Parameters public static Collection<Object[]> getTestParameters() throws Exception { final Collection<Object[]> params = new ArrayList<>(); final ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC); final ZonedDateTime twoHoursAgo = now.minusHours(2); final ZonedDateTime oneHourAgo = now.minusHours(1); final ZonedDateTime halfHourAgo = now.minusMinutes(30); final X500Principal issuer = new X500Principal("CN=CAS"); // Test case #1 // Expect expired for zero leniency on CRL expiring 1ms ago final ThresholdExpiredCRLRevocationPolicy zeroThreshold = new ThresholdExpiredCRLRevocationPolicy(0); params.add(new Object[] { zeroThreshold, new MockX509CRL(issuer, DateTimeUtils.dateOf(oneHourAgo), DateTimeUtils.dateOf(now.minusSeconds(1))), new ExpiredCRLException("CN=CAS", ZonedDateTime.now(ZoneOffset.UTC)), }); // Test case #2 // Expect expired for 1h leniency on CRL expired 1 hour 1ms ago final ThresholdExpiredCRLRevocationPolicy oneHourThreshold = new ThresholdExpiredCRLRevocationPolicy(3600); params.add(new Object[] { oneHourThreshold, new MockX509CRL(issuer, DateTimeUtils.dateOf(twoHoursAgo), DateTimeUtils.dateOf(oneHourAgo.minusSeconds(1))), new ExpiredCRLException("CN=CAS", ZonedDateTime.now(ZoneOffset.UTC)), }); // Test case #3 // Expect valid for 1h leniency on CRL expired 30m ago params.add(new Object[] { oneHourThreshold, new MockX509CRL(issuer, DateTimeUtils.dateOf(twoHoursAgo), DateTimeUtils.dateOf(halfHourAgo)), null, }); return params; } /** * Test method for {@link ThresholdExpiredCRLRevocationPolicy#apply(java.security.cert.X509CRL)}. */ @Test public void verifyApply() { try { this.policy.apply(this.crl); if (this.expected != null) { Assert.fail("Expected exception of type " + this.expected.getClass()); } } catch (final GeneralSecurityException e) { if (this.expected == null) { e.printStackTrace(); Assert.fail("Revocation check failed unexpectedly with exception: " + e); } else { final Class<?> expectedClass = this.expected.getClass(); final Class<?> actualClass = e.getClass(); Assert.assertTrue( String.format("Expected exception of type %s but got %s", expectedClass, actualClass), expectedClass.isAssignableFrom(actualClass)); } } } }