/*
* DSS - Digital Signature Services
*
* Copyright (C) 2013 European Commission, Directorate-General Internal Market and Services (DG MARKT), B-1049 Bruxelles/Brussel
*
* Developed by: 2013 ARHS Developments S.A. (rue Nicolas Bové 2B, L-1253 Luxembourg) http://www.arhs-developments.com
*
* This file is part of the "DSS - Digital Signature Services" project.
*
* "DSS - Digital Signature Services" is free software: you can redistribute it and/or modify it under the terms of
* the GNU Lesser General Public License as published by the Free Software Foundation, either version 2.1 of the
* License, or (at your option) any later version.
*
* DSS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* "DSS - Digital Signature Services". If not, see <http://www.gnu.org/licenses/>.
*/
package eu.europa.ec.markt.dss.validation102853.crl;
import java.security.cert.X509CRL;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import eu.europa.ec.markt.dss.DSSUtils;
import eu.europa.ec.markt.dss.exception.DSSException;
import eu.europa.ec.markt.dss.exception.DSSNullException;
import eu.europa.ec.markt.dss.validation102853.CertificateToken;
import eu.europa.ec.markt.dss.validation102853.https.CommonDataLoader;
import eu.europa.ec.markt.dss.validation102853.loader.DataLoader;
import eu.europa.ec.markt.dss.validation102853.loader.Protocol;
/**
* Online CRL repository. This CRL repository implementation will download the CRLs from the given CRL URIs.
* Note that for the HTTP kind of URLs you can provide dedicated data loader. If the data loader is not provided the standard load from URI is
* provided. For FTP the standard load from URI is provided. For LDAP kind of URLs an internal implementation using apache-ldap-api is provided.
*
* @version $Revision$ - $Date$
*/
public class OnlineCRLSource extends CommonCRLSource {
private static final Logger LOG = LoggerFactory.getLogger(OnlineCRLSource.class);
/**
* If the multiple protocols are available to retrieve the revocation data, then that indicated by this variable is used first.
*/
private Protocol preferredProtocol;
/**
* The component that allows to retrieve the data using any protocol: HTTP, HTTPS, FTP, LDAP.
*/
protected DataLoader dataLoader;
/**
* The default constructor. A {@code CommonsDataLoader is created}.
*/
public OnlineCRLSource() {
dataLoader = new CommonDataLoader();
LOG.trace("+OnlineCRLSource with the default data loader.");
}
/**
* This constructor allows to set a specific {@code DataLoader}.
*
* @param dataLoader the component that allows to retrieve the data using any protocol: HTTP, HTTPS, FTP, LDAP.
* @throws DSSNullException in the case of {@code null} parameter value
*/
public OnlineCRLSource(final DataLoader dataLoader) throws DSSNullException {
setDataLoader(dataLoader);
LOG.trace("+OnlineCRLSource with the specific data loader.");
}
/**
* This method allows to set the preferred protocol. This parameter is used used when retrieving the CRL to choose the canal.<br/>
* Possible values are: http, ldap, ftp
*
* @param preferredProtocol {@code Protocol} that is used first to retrieve the revocation data
*/
public void setPreferredProtocol(final Protocol preferredProtocol) {
this.preferredProtocol = preferredProtocol;
}
/**
* Set the DataLoader to use for querying the CRL server
*
* @param dataLoader the component that allows to retrieve the data using any protocol: HTTP, HTTPS, FTP, LDAP.
* @throws DSSNullException in the case of {@code null} parameter value
*/
public void setDataLoader(final DataLoader dataLoader) throws DSSNullException {
if (dataLoader == null) {
throw new DSSNullException(DataLoader.class);
}
this.dataLoader = dataLoader;
}
@Override
public CRLToken findCrl(final CertificateToken certificateToken) throws DSSException {
if (certificateToken == null) {
return null;
}
final CertificateToken issuerToken = certificateToken.getIssuerToken();
if (issuerToken == null) {
return null;
}
final List<String> crlUrls = getCrlUrl(certificateToken, preferredProtocol);
if (DSSUtils.isEmpty(crlUrls)) {
return null;
}
final DataLoader.DataAndUrl dataAndUrl = downloadCrl(crlUrls);
if (dataAndUrl == null) {
return null;
}
final X509CRL x509CRL = buildX509Crl(dataAndUrl.data);
if (x509CRL == null) {
return null;
}
final List<String> dpUrlList = new ArrayList<String>();
dpUrlList.add(dataAndUrl.urlString);
final CRLValidity crlValidity = isValidCRL(x509CRL, issuerToken, dpUrlList);
final CRLToken crlToken = new CRLToken(certificateToken, crlValidity);
crlToken.setSourceURL(dataAndUrl.urlString);
return crlToken;
}
protected X509CRL buildX509Crl(byte[] data) {
try {
final X509CRL x509CRL = DSSUtils.loadCRL(data);
return x509CRL;
} catch (Exception e) {
LOG.warn("", e);
return null;
}
}
/**
* Download a CRL from any location with any protocol.
*
* @param downloadUrls the {@code List} of urls to be used to obtain the revocation data through the CRL canal.
* @return {@code X509CRL} or {@code null} if it was not possible to download the CRL
*/
private DataLoader.DataAndUrl downloadCrl(final List<String> downloadUrls) {
try {
final DataLoader.DataAndUrl dataAndUrl = dataLoader.get(downloadUrls);
return dataAndUrl;
} catch (DSSException e) {
LOG.warn("", e);
}
return null;
}
}