org.digidoc4j.ddoc.tsl.DigiDocTrustServiceFactory Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ddoc4j Show documentation
Show all versions of ddoc4j Show documentation
DDoc4J is Java Library for validating DDOC documents. It's not recommended to use it directly but rather through DigiDoc4J's API.
The newest version!
package org.digidoc4j.ddoc.tsl;
import org.digidoc4j.ddoc.DigiDocException;
import org.digidoc4j.ddoc.factory.TrustServiceFactory;
import org.digidoc4j.ddoc.utils.ConfigManager;
import org.digidoc4j.ddoc.utils.ConvertUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
import java.security.Principal;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Vector;
/**
* SAX implementation of TrustServiceFactory
* Provides methods for reading a DigiDoc file
* @author Veiko Sinivee
* @version 1.0
*/
public class DigiDocTrustServiceFactory
implements TrustServiceFactory
{
/** log4j logger */
private static Logger m_logger = LoggerFactory.getLogger(DigiDocTrustServiceFactory.class);
/** TSL list */
private List m_tsls;
/**
* initializes the implementation class
*/
public void init()
throws DigiDocException
{
try {
ConfigManager cfg = ConfigManager.instance();
// read in local config file
if(m_logger.isDebugEnabled())
m_logger.debug("Reading local config file");
TrustServiceStatusList tsl = new TrustServiceStatusList();
SchemeInformation si = new SchemeInformation();
si.setVersionIdentifier(1);
si.setSequenceNumber(1);
si.setType(SchemeInformation.TYPE_LOCAL);
tsl.setSchemeInformation(si);
m_tsls = new ArrayList();
m_tsls.add(tsl);
// read CA-s
int nCas = cfg.getIntProperty("DIGIDOC_CAS", 0);
if(m_logger.isDebugEnabled())
m_logger.debug("CA-s: " + nCas);
for(int c = 1; c <= nCas; c++) {
TrustServiceProvider tsp = addTspProvider(
cfg.getStringProperty("DIGIDOC_CA_" + c + "_NAME", null),
cfg.getStringProperty("DIGIDOC_CA_" + c + "_TRADENAME", null));
int nCerts = cfg.getIntProperty("DIGIDOC_CA_" + c + "_CERTS", 0);
for(int n = 1; n <= nCerts; n++) {
String certLoc = cfg.getStringProperty("DIGIDOC_CA_" + c + "_CERT" + n, null);
if(m_logger.isDebugEnabled())
m_logger.debug("CA" + c + " ca-cert" + n + " - " + certLoc);
try {
X509Certificate cert = readCertificate(certLoc);
if(cert != null && tsp != null)
addCATspService(tsp, cert);
} catch(Exception ex2) {
m_logger.warn("Failed to read CA cert: " + certLoc);
}
}
int nOcsps = cfg.getIntProperty("DIGIDOC_CA_" + c + "_OCSPS", 0);
if(m_logger.isDebugEnabled())
m_logger.debug("OCSP-s: " + nOcsps);
for(int n = 1; n <= nOcsps; n++) {
String certLoc = cfg.getStringProperty("DIGIDOC_CA_" + c + "_OCSP" + n + "_CERT", null);
if(m_logger.isDebugEnabled())
m_logger.debug("CA" + c + " ocsp-cert" + n + " - " + certLoc);
TSPService tsps = null;
try {
X509Certificate cert = readCertificate(certLoc);
if(cert != null && tsp != null) {
tsps = addOcspTspService(tsp, cert,
cfg.getStringProperty("DIGIDOC_CA_" + c + "_OCSP" + n + "_CN", null),
cfg.getStringProperty("DIGIDOC_CA_" + c + "_OCSP" + n + "_URL", null),
cfg.getStringProperty("DIGIDOC_CA_" + c + "_OCSP" + n + "_CN", null),
cfg.getStringProperty("DIGIDOC_CA_" + c + "_OCSP" + n + "_CA_CN", null));
}
} catch(Exception ex2) {
m_logger.warn("Failed to read OCSP responder cert: " + certLoc);
}
int j = 1;
do {
certLoc = cfg.getStringProperty("DIGIDOC_CA_" + c + "_OCSP" + n + "_CERT_" + j, null);
if(m_logger.isDebugEnabled())
m_logger.debug("CA" + c + " ocsp-cert" + n + "/" + j + " - " + certLoc);
if(certLoc != null && tsps != null) {
try {
X509Certificate cert = readCertificate(certLoc);
if(cert != null) {
tsps.addCertificate(cert);
}
} catch(Exception ex) {
m_logger.warn("Failed to read OCSP responder cert: " + certLoc);
}
}
j++;
} while(certLoc != null);
// TODO: authority-key-identifier
}
if(m_logger.isDebugEnabled())
m_logger.debug("Local config: " + tsl);
}
// Read TSL-s
// read in all other TSL-s in tsl dir
String sTslDir = cfg.getStringProperty("DIGIDOC_TSL_DIR", null);
if(sTslDir != null && sTslDir.length() > 0) {
File fTslDir = new File(sTslDir);
File[] lTsls = fTslDir.listFiles();
for(int i = 0; (lTsls != null) && (i < lTsls.length); i++) {
File f = lTsls[i];
if(f.isFile() && f.canRead()) {
if(m_logger.isDebugEnabled())
m_logger.debug("Reading TSL: " + f.getAbsolutePath());
TslParser parser = new TslParser();
FileInputStream fis = new FileInputStream(f);
TrustServiceStatusList tsl2 = parser.readTSL(fis);
fis.close();
if(tsl2 != null) {
if(m_logger.isDebugEnabled())
m_logger.debug("Got TSL: " + tsl2);
m_tsls.add(tsl2);
}
}
}
}
} catch(DigiDocException ex) {
m_logger.error("Error init TrustServiceFactory dd: " + ex);
ex.printStackTrace();
throw ex;
} catch(Exception ex) {
m_logger.error("Error init TrustServiceFactory: " + ex);
ex.printStackTrace();
}
}
/**
* Find tsl by type name
* @param type tsl type
* @return TrustServiceStatusList object if found or null
*/
private TrustServiceStatusList findTslByType(String type)
{
for(int i = 0; (m_tsls != null) && (i < m_tsls.size()); i++) {
TrustServiceStatusList tsl = (TrustServiceStatusList)m_tsls.get(i);
if(tsl.getSchemeInformation() != null &&
tsl.getSchemeInformation().getType() != null &&
tsl.getSchemeInformation().getType().equals(type))
return tsl;
}
return null;
}
/**
* Adds info of a new Trust service provider
* @param name short name [optional]
* @param tradeName long name [optional]
* @return TrustServiceProvider object
*/
public TrustServiceProvider addTspProvider(String name, String tradeName)
{
TrustServiceStatusList tsl = findTslByType(SchemeInformation.TYPE_LOCAL);
if(tsl != null) {
TrustServiceProvider tsp = new TrustServiceProvider();
tsl.addTrustServiceProvider(tsp);
TSPInformation tsi = new TSPInformation();
tsi.addName(new MultiLangString(null, name));
tsi.addTradeName(new MultiLangString(null, tradeName));
tsp.setTSPInformation(tsi);
return tsp;
}
return null;
}
/**
* Add new CA service
* @param tspProvider TSP provider
* @param cert ca cert
* @return TSPService object
*/
public TSPService addCATspService(TrustServiceProvider tspProvider, X509Certificate cert)
{
TSPService tsps = new TSPService();
tsps.setType(TSPService.TSP_TYPE_CA_QC);
tsps.addCertificate(cert);
tsps.addSubjectName(new MultiLangString(null, cert.getSubjectDN().getName()));
tsps.addName(new MultiLangString(null, ConvertUtils.getCommonName(cert.getSubjectDN().getName())));
tsps.setCn(ConvertUtils.getCommonName(cert.getSubjectDN().getName()));
tspProvider.addTSPService(tsps);
return tsps;
}
/**
* Add new OCSP service
* @param tspProvider TSP provider
* @param cert ca cert
* @param name service name
* @param oscpUrl OCSP responder url
* @param cn OCSP responder id
* @param caCn responder ca CN
* @return TSPService object
*/
public TSPService addOcspTspService(TrustServiceProvider tspProvider, X509Certificate cert, String name, String ocspUrl, String cn, String caCn)
{
TSPService tsps = new TSPService();
tsps.setType(TSPService.TSP_TYPE_EXT_OCSP_QC);
tsps.addCertificate(cert);
tsps.addSubjectName(new MultiLangString(null, cert.getSubjectDN().getName()));
tsps.addName(new MultiLangString(null, name));
tsps.addServiceAccessPoint(ocspUrl);
tsps.setCn(cn);
tsps.setCaCn(caCn);
tspProvider.addTSPService(tsps);
return tsps;
}
/**
* Reads the cert from a file, URL or from another
* location somewhere in the CLASSPATH such as
* in the librarys jar file.
* @param certLocation certificates file name,
* or URL. You can use url in form jar:// to read
* a certificate from the car file or some other location in the
* CLASSPATH
* @return certificate object
*/
private static X509Certificate readCertificate(String certLocation)
throws DigiDocException
{
X509Certificate cert = null;
try {
InputStream isCert = null;
URL url = null;
if(certLocation != null) {
if(certLocation.startsWith("http")) {
url = new URL(certLocation);
isCert = url.openStream();
} else if(certLocation.startsWith("jar://")) {
ClassLoader cl = ConfigManager.instance().getClass().getClassLoader();
isCert = cl.getResourceAsStream(certLocation.substring(6));
} else {
isCert = new FileInputStream(certLocation);
}
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
cert = (X509Certificate)certificateFactory.generateCertificate(isCert);
isCert.close();
if(m_logger.isDebugEnabled())
m_logger.debug("Read cert: " + certLocation + " - " + ((cert != null) ? "OK" : "NULL"));
}
} catch(Exception ex) {
DigiDocException.handleException(ex, DigiDocException.ERR_READ_FILE);
}
return cert;
}
private X509Certificate findCaForCertInTsl(TrustServiceStatusList tsl, X509Certificate cert, Date dtSigning)
{
Principal caP = cert.getIssuerDN();
String subDn = cert.getSubjectDN().getName();
for(int j = 0; j < tsl.getNumProviders(); j++) {
TrustServiceProvider tsp = tsl.getTrustServiceProvider(j);
for(int l = 0; l < tsp.getNumServices(); l++) {
TSPService tsps = tsp.getTSPService(l);
if(tsps.isCA()) {
for(int m = 0; m < tsps.getNumCertificates(); m++) {
X509Certificate c2 = tsps.getCertificate(m);
if(c2 != null) {
Principal c2p = c2.getSubjectDN();
String ca2Dn = c2.getSubjectDN().getName();
if(c2p.equals(caP) &&
((dtSigning == null) ||
(dtSigning != null && dtSigning.after(c2.getNotBefore()) && dtSigning.before(c2.getNotAfter())))) {
if(m_logger.isDebugEnabled())
m_logger.debug("Found matching CA dn: " + ca2Dn);
try {
cert.verify(c2.getPublicKey());
if(m_logger.isDebugEnabled())
m_logger.debug("CA: " + ca2Dn + " IS issuer of: " + subDn + " serial: " + c2.getSerialNumber().toString());
return c2;
} catch(Exception ex) {
if(m_logger.isDebugEnabled())
m_logger.debug("CA: " + ca2Dn + " IS NOT issuer of: " + subDn);
}
}
} // if c2
} // for
} // if isCA
}
}
return null;
}
private X509Certificate findOcspInTsl(TrustServiceStatusList tsl, String cn)
{
if(m_logger.isDebugEnabled())
m_logger.debug("Search OCSP by cn: " + cn);
for(int j = 0; j < tsl.getNumProviders(); j++) {
TrustServiceProvider tsp = tsl.getTrustServiceProvider(j);
if(m_logger.isDebugEnabled())
m_logger.debug("TSP: " + tsp.getTSPInformation().getName(0));
for(int l = 0; l < tsp.getNumServices(); l++) {
TSPService tsps = tsp.getTSPService(l);
if(m_logger.isDebugEnabled())
m_logger.debug("Service: " + tsps.getCn() + " ocsp: " + tsps.isOCSP() + " CA: " + tsps.isCA());
if(tsps.isOCSP() && tsps.getCn() != null && tsps.getCn().equalsIgnoreCase(cn)) {
if(m_logger.isDebugEnabled())
m_logger.debug("Found OCSP: " + cn);
return tsps.getCertificate(0);
}
}
}
if(m_logger.isDebugEnabled())
m_logger.debug("Did not find ocsp for: " + cn);
return null;
}
private X509Certificate[] findOcspsInTsl(TrustServiceStatusList tsl, String cn, String serialNr)
{
X509Certificate[] lcert = null;
Vector vec = new Vector();
if(m_logger.isDebugEnabled())
m_logger.debug("Search OCSP by cn: " + cn + " serial: " + serialNr);
for(int j = 0; j < tsl.getNumProviders(); j++) {
TrustServiceProvider tsp = tsl.getTrustServiceProvider(j);
if(m_logger.isDebugEnabled())
m_logger.debug("TSP: " + tsp.getTSPInformation().getName(0));
for(int l = 0; l < tsp.getNumServices(); l++) {
TSPService tsps = tsp.getTSPService(l);
if(m_logger.isDebugEnabled())
m_logger.debug("Service: " + tsps.getCn() + " ocsp: " + tsps.isOCSP() + " CA: " + tsps.isCA());
if(tsps.isOCSP() && tsps.getCn() != null && tsps.getCn().equalsIgnoreCase(cn)) {
if(m_logger.isDebugEnabled())
m_logger.debug("Found OCSP: " + cn);
for(int m = 0; m < tsps.getNumCertificates(); m++) {
X509Certificate cert = tsps.getCertificate(m);
if(serialNr == null || (serialNr != null && serialNr.equals(cert.getSerialNumber().toString()))) {
if(m_logger.isDebugEnabled() && cert != null)
m_logger.debug("Found cert: " + cert.getSubjectDN().toString() + " serial: " + cert.getSerialNumber().toString());
vec.add(cert);
}
}
}
}
}
if(m_logger.isDebugEnabled())
m_logger.debug("Found: " + vec.size() + " certs for: " + cn);
lcert = new X509Certificate[vec.size()];
for(int j = 0; j < vec.size(); j++)
lcert[j] = (X509Certificate)vec.elementAt(j);
return lcert;
}
/**
* Finds direct CA cert for given user cert
* @param cert user cert
* @param bUseLocal use also ca certs registered in local config file
* @return CA cert or null if not found
* @deprecated use findCaForCert(X509Certificate cert, boolean bUseLocal, Date dtSigning)
*/
public X509Certificate findCaForCert(X509Certificate cert, boolean bUseLocal)
{
return findCaForCert(cert, bUseLocal, null);
}
/**
* Finds direct CA cert for given user cert
* @param cert user cert
* @param bUseLocal use also ca certs registered in local config file
* @param dtSigning signing timestamp. Used to pick correct ca if many of them apply
* @return CA cert or null if not found
*/
public X509Certificate findCaForCert(X509Certificate cert, boolean bUseLocal, Date dtSigning)
{
Principal caP = cert.getIssuerDN();
String caDn = cert.getIssuerDN().getName();
if(m_logger.isDebugEnabled())
m_logger.debug("Search CA: " + caDn);
// find in TSL files at first
for(int i = 0; (m_tsls != null) && (i < m_tsls.size()); i++) {
TrustServiceStatusList tsl = (TrustServiceStatusList)m_tsls.get(i);
if((tsl.isLocal() && bUseLocal) || !tsl.isLocal()) {
X509Certificate ca = findCaForCertInTsl(tsl, cert, dtSigning);
if(ca != null)
return ca;
}
}
return null;
}
/**
* Finds direct OCSP cert for given ocsp responder id
* @param cn OCSP responder-id
* @param bUseLocal use also ca certs registered in local config file
* @param serialNr serial number or NULL
* @return OCSP cert or null if not found
*/
public X509Certificate[] findOcspsByCNAndNr(String cn, boolean bUseLocal, String serialNr)
{
X509Certificate[] lcert = null;
if(m_logger.isDebugEnabled())
m_logger.debug("Search OCSP: " + cn + " use-local: " + bUseLocal + " serial: " + serialNr);
// find in TSL files at first
for(int i = 0; (m_tsls != null) && (lcert == null) && (i < m_tsls.size()); i++) {
TrustServiceStatusList tsl = (TrustServiceStatusList)m_tsls.get(i);
if(m_logger.isDebugEnabled())
m_logger.debug("TSL: " + tsl.getSchemeInformation().getSchemeName(0) + " local: " + tsl.isLocal());
if((tsl.isLocal() && bUseLocal) || !tsl.isLocal()) {
// TODO: find certs
lcert = findOcspsInTsl(tsl, cn, serialNr);
X509Certificate cert = findOcspInTsl(tsl, cn);
}
}
return lcert;
}
}