Skip to content

Commit

Permalink
Add cache in offline revocation sources
Browse files Browse the repository at this point in the history
  • Loading branch information
pvandenbroucke committed Jul 2, 2021
1 parent 44e0e88 commit 237759b
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ public CRLValidity(CRLBinary crlBinary) {
this.crlBinary = crlBinary;
}

public CRLBinary getCrlBinary() {
return crlBinary;
}

/**
* Returns DER encoded binaries of the CRL
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ public abstract class OfflineCRLSource extends OfflineRevocationSource<CRL> {

private static final Logger LOG = LoggerFactory.getLogger(OfflineCRLSource.class);

private final List<CRLValidity> cachedValidCRLValidities = new ArrayList<>();

/**
* The default constructor
*/
Expand All @@ -58,25 +60,46 @@ public List<RevocationToken<CRL>> getRevocationTokens(final CertificateToken cer
Objects.requireNonNull(issuerToken, "The issuer of the certificate to be verified cannot be null");

List<RevocationToken<CRL>> result = new ArrayList<>();
final Set<EncapsulatedRevocationTokenIdentifier<CRL>> collectedBinaries = getAllRevocationBinaries();
LOG.trace("--> OfflineCRLSource queried for {} contains: {} element(s).", certificateToken.getDSSIdAsString(), collectedBinaries.size());

for (EncapsulatedRevocationTokenIdentifier<CRL> binary : collectedBinaries) {
CRLBinary crlBinary = (CRLBinary) binary;
try {
CRLValidity crlValidity = CRLUtils.buildCRLValidity(crlBinary, issuerToken);
if (crlValidity.isValid()) {
final CRLToken crlToken = new CRLToken(certificateToken, crlValidity);
addRevocation(crlToken, crlBinary);
result.add(crlToken);

List<CRLValidity> validCRLValiditiesForIssuer = getFromCachedCRLValidities(issuerToken);

if (validCRLValiditiesForIssuer.isEmpty()) {

final Set<EncapsulatedRevocationTokenIdentifier<CRL>> collectedBinaries = getAllRevocationBinaries();
LOG.trace("--> OfflineCRLSource queried for {} contains: {} element(s).", certificateToken.getDSSIdAsString(), collectedBinaries.size());

for (EncapsulatedRevocationTokenIdentifier<CRL> binary : collectedBinaries) {
CRLBinary crlBinary = (CRLBinary) binary;
try {
CRLValidity crlValidity = CRLUtils.buildCRLValidity(crlBinary, issuerToken);
if (crlValidity.isValid()) {
cachedValidCRLValidities.add(crlValidity);
validCRLValiditiesForIssuer.add(crlValidity);
}
} catch (Exception e) {
LOG.warn("Unable to retrieve the CRLValidity for CRL with ID '{}' : {}", crlBinary.asXmlId(), e.getMessage());
}
} catch (Exception e) {
LOG.warn("Unable to retrieve the CRLValidity for CRL with ID '{}' : {}", crlBinary.asXmlId(), e.getMessage());
}
}

for (CRLValidity crlValidity : validCRLValiditiesForIssuer) {
final CRLToken crlToken = new CRLToken(certificateToken, crlValidity);
addRevocation(crlToken, crlValidity.getCrlBinary());
result.add(crlToken);
}

LOG.trace("--> OfflineCRLSource found result(s) : {}", result.size());
return result;
}

private List<CRLValidity> getFromCachedCRLValidities(CertificateToken issuerToken) {
List<CRLValidity> result = new ArrayList<>();
for (CRLValidity validity : cachedValidCRLValidities) {
if (issuerToken.equals(validity.getIssuerToken())) {
result.add(validity);
}
}
return result;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,22 @@
*/
package eu.europa.esig.dss.spi.x509.revocation.ocsp;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;

import org.bouncycastle.cert.ocsp.BasicOCSPResp;
import org.bouncycastle.cert.ocsp.SingleResp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import eu.europa.esig.dss.model.identifier.EncapsulatedRevocationTokenIdentifier;
import eu.europa.esig.dss.model.x509.CertificateToken;
import eu.europa.esig.dss.model.x509.revocation.ocsp.OCSP;
import eu.europa.esig.dss.spi.DSSRevocationUtils;
import eu.europa.esig.dss.spi.x509.revocation.OfflineRevocationSource;
import eu.europa.esig.dss.spi.x509.revocation.RevocationToken;
import eu.europa.esig.dss.utils.Utils;
import org.bouncycastle.cert.ocsp.BasicOCSPResp;
import org.bouncycastle.cert.ocsp.SingleResp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
* Abstract class that helps to implement an OCSPSource with an already loaded list of BasicOCSPResp
Expand All @@ -56,18 +56,29 @@ public List<RevocationToken<OCSP>> getRevocationTokens(CertificateToken certific
Objects.requireNonNull(issuer, "The issuer of the certificate to be verified cannot be null");

List<RevocationToken<OCSP>> result = new ArrayList<>();
final Set<EncapsulatedRevocationTokenIdentifier<OCSP>> collectedBinaries = getAllRevocationBinaries();
LOG.trace("--> OfflineOCSPSource queried for {} contains: {} element(s).", certificate.getDSSIdAsString(), collectedBinaries.size());
for (EncapsulatedRevocationTokenIdentifier<OCSP> binary : collectedBinaries) {
OCSPResponseBinary ocspBinary = (OCSPResponseBinary) binary;
BasicOCSPResp basicOCSPResp = ocspBinary.getBasicOCSPResp();
SingleResp latestSingleResponse = DSSRevocationUtils.getLatestSingleResponse(basicOCSPResp, certificate, issuer);
if (latestSingleResponse != null) {
OCSPToken ocspToken = new OCSPToken(basicOCSPResp, latestSingleResponse, certificate, issuer);
addRevocation(ocspToken, ocspBinary);
result.add(ocspToken);

Set<RevocationToken<OCSP>> allRevocationTokens = getAllRevocationTokens();
for (RevocationToken<OCSP> revocationToken : allRevocationTokens) {
if (certificate.getDSSIdAsString().equals(revocationToken.getRelatedCertificateId()) && issuer.equals(revocationToken.getIssuerCertificateToken())) {
result.add(revocationToken);
}
}

if (Utils.isCollectionEmpty(result)) {
final Set<EncapsulatedRevocationTokenIdentifier<OCSP>> collectedBinaries = getAllRevocationBinaries();
LOG.trace("--> OfflineOCSPSource queried for {} contains: {} element(s).", certificate.getDSSIdAsString(), collectedBinaries.size());
for (EncapsulatedRevocationTokenIdentifier<OCSP> binary : collectedBinaries) {
OCSPResponseBinary ocspBinary = (OCSPResponseBinary) binary;
BasicOCSPResp basicOCSPResp = ocspBinary.getBasicOCSPResp();
SingleResp latestSingleResponse = DSSRevocationUtils.getLatestSingleResponse(basicOCSPResp, certificate, issuer);
if (latestSingleResponse != null) {
OCSPToken ocspToken = new OCSPToken(basicOCSPResp, latestSingleResponse, certificate, issuer);
addRevocation(ocspToken, ocspBinary);
result.add(ocspToken);
}
}
}

LOG.trace("--> OfflineOCSPSource found result(s) : {}", result.size());
return result;
}
Expand Down

0 comments on commit 237759b

Please sign in to comment.