Refactoring CmsValidator (internal CRL resolution) (#2635)

* Refactoring CmsValidator (internal CRL resolution)

Signed-off-by: Lucas Saldanha <lucascrsaldanha@gmail.com>
pull/2641/head
Lucas Saldanha 3 years ago committed by GitHub
parent 1f4f131469
commit d844a37f96
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 42
      pki/src/main/java/org/hyperledger/besu/pki/cms/CmsValidator.java
  2. 39
      pki/src/test/java/org/hyperledger/besu/pki/cms/CmsCreationAndValidationTest.java

@ -20,6 +20,7 @@ import java.security.Security;
import java.security.cert.CertPathBuilder; import java.security.cert.CertPathBuilder;
import java.security.cert.CertPathBuilderException; import java.security.cert.CertPathBuilderException;
import java.security.cert.CertStore; import java.security.cert.CertStore;
import java.security.cert.CollectionCertStoreParameters;
import java.security.cert.PKIXBuilderParameters; import java.security.cert.PKIXBuilderParameters;
import java.security.cert.PKIXRevocationChecker; import java.security.cert.PKIXRevocationChecker;
import java.security.cert.PKIXRevocationChecker.Option; import java.security.cert.PKIXRevocationChecker.Option;
@ -54,11 +55,9 @@ public class CmsValidator {
private static final Logger LOGGER = LogManager.getLogger(); private static final Logger LOGGER = LogManager.getLogger();
private final KeyStoreWrapper truststore; private final KeyStoreWrapper truststore;
private final Optional<CertStore> crlCertStore;
public CmsValidator(final KeyStoreWrapper truststore, final CertStore crlCertStore) { public CmsValidator(final KeyStoreWrapper truststore) {
this.truststore = truststore; this.truststore = truststore;
this.crlCertStore = Optional.ofNullable(crlCertStore);
} }
/** /**
@ -146,17 +145,18 @@ public class CmsValidator {
new PKIXBuilderParameters(truststore.getKeyStore(), targetConstraints); new PKIXBuilderParameters(truststore.getKeyStore(), targetConstraints);
// Adding CertStore with CRLs (if present, otherwise disabling revocation check) // Adding CertStore with CRLs (if present, otherwise disabling revocation check)
crlCertStore.ifPresentOrElse( createCRLCertStore(truststore)
CRLs -> { .ifPresentOrElse(
params.addCertStore(CRLs); CRLs -> {
PKIXRevocationChecker rc = (PKIXRevocationChecker) cpb.getRevocationChecker(); params.addCertStore(CRLs);
rc.setOptions(EnumSet.of(Option.PREFER_CRLS)); PKIXRevocationChecker rc = (PKIXRevocationChecker) cpb.getRevocationChecker();
params.addCertPathChecker(rc); rc.setOptions(EnumSet.of(Option.PREFER_CRLS));
}, params.addCertPathChecker(rc);
() -> { },
LOGGER.warn("No CRL CertStore provided. CRL validation will be disabled."); () -> {
params.setRevocationEnabled(false); LOGGER.warn("No CRL CertStore provided. CRL validation will be disabled.");
}); params.setRevocationEnabled(false);
});
// Read certificates sent on the CMS message and adding it to the path building algorithm // Read certificates sent on the CMS message and adding it to the path building algorithm
final CertStore cmsCertificates = final CertStore cmsCertificates =
@ -178,4 +178,18 @@ public class CmsValidator {
throw new RuntimeException("Error validating certificate chain", e); throw new RuntimeException("Error validating certificate chain", e);
} }
} }
private Optional<CertStore> createCRLCertStore(final KeyStoreWrapper truststore) {
if (truststore.getCRLs() != null) {
try {
return Optional.of(
CertStore.getInstance(
"Collection", new CollectionCertStoreParameters(truststore.getCRLs())));
} catch (final Exception e) {
throw new RuntimeException("Error loading CRLs from Truststore", e);
}
} else {
return Optional.empty();
}
}
} }

@ -20,6 +20,8 @@ import static org.hyperledger.besu.pki.util.TestCertificateUtils.createCRL;
import static org.hyperledger.besu.pki.util.TestCertificateUtils.createKeyPair; import static org.hyperledger.besu.pki.util.TestCertificateUtils.createKeyPair;
import static org.hyperledger.besu.pki.util.TestCertificateUtils.createSelfSignedCertificate; import static org.hyperledger.besu.pki.util.TestCertificateUtils.createSelfSignedCertificate;
import static org.hyperledger.besu.pki.util.TestCertificateUtils.issueCertificate; import static org.hyperledger.besu.pki.util.TestCertificateUtils.issueCertificate;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import org.hyperledger.besu.pki.keystore.KeyStoreWrapper; import org.hyperledger.besu.pki.keystore.KeyStoreWrapper;
import org.hyperledger.besu.pki.keystore.SoftwareKeyStoreWrapper; import org.hyperledger.besu.pki.keystore.SoftwareKeyStoreWrapper;
@ -27,14 +29,13 @@ import org.hyperledger.besu.pki.keystore.SoftwareKeyStoreWrapper;
import java.security.KeyPair; import java.security.KeyPair;
import java.security.KeyStore; import java.security.KeyStore;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.security.cert.CertStore;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.security.cert.CollectionCertStoreParameters;
import java.security.cert.X509CRL; import java.security.cert.X509CRL;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.time.Instant; import java.time.Instant;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import java.util.Set; import java.util.Set;
import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes;
@ -54,10 +55,12 @@ import org.junit.Test;
public class CmsCreationAndValidationTest { public class CmsCreationAndValidationTest {
private static KeyStoreWrapper keystoreWrapper; private static KeyStore keystore;
private static KeyStoreWrapper truststoreWrapper; private static KeyStore truststore;
private static CertStore CRLs; private static List<X509CRL> CRLs;
private KeyStoreWrapper keystoreWrapper;
private KeyStoreWrapper truststoreWrapper;
private CmsValidator cmsValidator; private CmsValidator cmsValidator;
@BeforeClass @BeforeClass
@ -150,19 +153,17 @@ public class CmsCreationAndValidationTest {
/* /*
Create truststore wrapper with 3 trusted certificates: 'ca', 'interca' and 'selfsigned' Create truststore wrapper with 3 trusted certificates: 'ca', 'interca' and 'selfsigned'
*/ */
final KeyStore truststore = KeyStore.getInstance("PKCS12"); truststore = KeyStore.getInstance("PKCS12");
truststore.load(null, null); truststore.load(null, null);
truststore.setCertificateEntry("ca", caCertificate); truststore.setCertificateEntry("ca", caCertificate);
truststore.setCertificateEntry("interca", interCACertificate); truststore.setCertificateEntry("interca", interCACertificate);
truststore.setCertificateEntry("selfsigned", selfsignedCertificate); truststore.setCertificateEntry("selfsigned", selfsignedCertificate);
truststoreWrapper = new SoftwareKeyStoreWrapper(truststore, "");
/* /*
Create keystore with certificates used in tests Create keystore with certificates used in tests
*/ */
final KeyStore keystore = KeyStore.getInstance("PKCS12"); keystore = KeyStore.getInstance("PKCS12");
keystore.load(null, null); keystore.load(null, null);
keystore.setKeyEntry( keystore.setKeyEntry(
@ -195,7 +196,6 @@ public class CmsCreationAndValidationTest {
untrustedIntermediateKeyPair.getPrivate(), untrustedIntermediateKeyPair.getPrivate(),
"".toCharArray(), "".toCharArray(),
new Certificate[] {untrustedIntermediateCertificate, untrustedSelfsignedCertificate}); new Certificate[] {untrustedIntermediateCertificate, untrustedSelfsignedCertificate});
keystoreWrapper = new SoftwareKeyStoreWrapper(keystore, "");
/* /*
Create CRLs for all CA certificates (mostly empty, only ca has one revoked certificate) Create CRLs for all CA certificates (mostly empty, only ca has one revoked certificate)
@ -207,17 +207,17 @@ public class CmsCreationAndValidationTest {
createCRL(partnerACACertificate, partnerACAPair, Collections.emptyList()); createCRL(partnerACACertificate, partnerACAPair, Collections.emptyList());
final X509CRL selfsignedCRL = final X509CRL selfsignedCRL =
createCRL(selfsignedCertificate, selfsignedKeyPair, Collections.emptyList()); createCRL(selfsignedCertificate, selfsignedKeyPair, Collections.emptyList());
CRLs = List.of(caCRL, intercaCRL, partnerACACRL, selfsignedCRL);
CRLs =
CertStore.getInstance(
"Collection",
new CollectionCertStoreParameters(
Set.of(caCRL, intercaCRL, partnerACACRL, selfsignedCRL)));
} }
@Before @Before
public void before() { public void before() {
cmsValidator = new CmsValidator(truststoreWrapper, CRLs); keystoreWrapper = new SoftwareKeyStoreWrapper(keystore, "");
truststoreWrapper = spy(new SoftwareKeyStoreWrapper(truststore, ""));
when(truststoreWrapper.getCRLs()).thenReturn(CRLs);
cmsValidator = new CmsValidator(truststoreWrapper);
} }
@Test @Test
@ -285,10 +285,13 @@ public class CmsCreationAndValidationTest {
final CmsCreator cmsCreator = new CmsCreator(keystoreWrapper, "revoked"); final CmsCreator cmsCreator = new CmsCreator(keystoreWrapper, "revoked");
final Bytes data = Bytes.random(32); final Bytes data = Bytes.random(32);
// Removing CRLs
when(truststoreWrapper.getCRLs()).thenReturn(null);
final Bytes cms = cmsCreator.create(data); final Bytes cms = cmsCreator.create(data);
// Overriding validator with instance without CRL CertStore // Overriding validator with instance without CRL CertStore
cmsValidator = new CmsValidator(truststoreWrapper, null); cmsValidator = new CmsValidator(truststoreWrapper);
// Because we don't have a CRL CertStore, revocation is not checked // Because we don't have a CRL CertStore, revocation is not checked
assertThat(cmsValidator.validate(cms, data)).isTrue(); assertThat(cmsValidator.validate(cms, data)).isTrue();

Loading…
Cancel
Save