From 0872d2d8a64fd701776b272f49222428d8def07f Mon Sep 17 00:00:00 2001 From: Andreas Fitzek Date: Tue, 3 Nov 2015 14:38:34 +0100 Subject: initial commit --- .../moa/spss/tsl/connector/TSLConnector.java | 972 +++++++++++++++++++++ .../spss/tsl/connector/TSLConnectorInterface.java | 95 ++ 2 files changed, 1067 insertions(+) create mode 100644 moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/connector/TSLConnector.java create mode 100644 moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/connector/TSLConnectorInterface.java (limited to 'moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/connector') diff --git a/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/connector/TSLConnector.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/connector/TSLConnector.java new file mode 100644 index 0000000..82df37b --- /dev/null +++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/connector/TSLConnector.java @@ -0,0 +1,972 @@ +package at.gv.egovernment.moa.spss.tsl.connector; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.nio.channels.ByteChannel; +import java.nio.channels.FileChannel; +import java.security.Security; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.apache.log4j.Logger; + +import at.gv.egovernment.moa.spss.tsl.config.Configurator; +import at.gv.egovernment.moa.spss.tsl.utils.TSLEUImportFromFileContext; +import at.gv.egovernment.moa.spss.tsl.utils.TSLEvaluationContext; +import at.gv.egovernment.moa.spss.tsl.utils.TSLImportFromFileContext; +import iaik.asn1.ObjectID; +import iaik.util._15; +import iaik.util.logging._l; +import iaik.utils.RFC2253NameParser; +import iaik.xml.crypto.EccProviderAdapter; +import iaik.xml.crypto.XSecProvider; +import iaik.xml.crypto.tsl.DbTables; +import iaik.xml.crypto.tsl.DbTables.MODE; +import iaik.xml.crypto.tsl.DbTables.Service; +import iaik.xml.crypto.tsl.TSLCertEvaluator; +import iaik.xml.crypto.tsl.TSLCertsExporter; +import iaik.xml.crypto.tsl.TSLEngine; +import iaik.xml.crypto.tsl.TSLEngine.LocationAndCertHash; +import iaik.xml.crypto.tsl.TSLEngine.TSLEngineEU; +import iaik.xml.crypto.tsl.TSLImportContext; +import iaik.xml.crypto.tsl.TSLResult; +import iaik.xml.crypto.tsl.TSLResultEndEntity; +import iaik.xml.crypto.tsl.TSLResultImpl; +import iaik.xml.crypto.tsl.TslSqlConnectionWrapper; +import iaik.xml.crypto.tsl.constants.Countries; +import iaik.xml.crypto.tsl.ex.TSLEngineDiedException; +import iaik.xml.crypto.tsl.ex.TSLEngineFatalException; +import iaik.xml.crypto.tsl.ex.TSLEngineFatalRuntimeException; +import iaik.xml.crypto.tsl.ex.TSLExceptionB; +import iaik.xml.crypto.tsl.ex.TSLRuntimeException; +import iaik.xml.crypto.tsl.ex.TSLSearchException; +import iaik.xml.crypto.tsl.ex.TSLTransactionFailedRuntimeException; +import iaik.xml.crypto.tsl.fetch.TLS; +import iaik.xml.crypto.tsl.sie.gen.QualifierType; + +public class TSLConnector implements TSLConnectorInterface { + + static final String _QCSSCDURI = "http://uri.etsi.org/TrstSvc/eSigDir-1999-93-EC-TrustedList/SvcInfoExt/QCWithSSCD"; + static final String _STYPETEMPLATE_CAQC = "CA/QC"; + static final String _STYPETEMPLATE_TSAQTST = "TSA/QTST"; + + private static final String DEFAULT_HASHCACHE_DIR = "./hashcache/"; + + static final List STYPETEMPLATES = Collections.unmodifiableList(new ArrayList(){ + private static final long serialVersionUID = 1L; + { + add(_STYPETEMPLATE_CAQC); + add(_STYPETEMPLATE_TSAQTST); + } + }); + + + static Logger log = Logger.getLogger(TSLConnector.class); + + public void initialize(String euTSLURL, String TSLWorkingDirectoryPath, String jdbcURL, String jdbcDriverClass) + throws TSLEngineDiedException { + + Configurator.initial(euTSLURL, TSLWorkingDirectoryPath, jdbcURL, jdbcDriverClass); + + } + + public ArrayList updateAndGetQualifiedCACertificates(Date dateTime, + String[] serviceLevelStatus) throws TSLEngineDiedException, TSLSearchException { + + if (Configurator.is_isInitialised() == false) + new TSLEngineFatalException("The TSL Engine is not initialized!"); + + return updateAndGetQualifiedCACertificates(dateTime, null, serviceLevelStatus); + } + + public void updateTSLs(Date dateTime, + String[] serviceLevelStatus) throws TSLEngineDiedException, TSLSearchException { + + if (Configurator.is_isInitialised() == false) + new TSLEngineFatalException("The TSL Engine is not initialized!"); + + updateTSLs(dateTime, null, serviceLevelStatus); + } + + public ArrayList updateAndGetQualifiedCACertificates(Date dateTime, + String[] countries, String[] serviceLevelStatus) throws TSLEngineDiedException, TSLSearchException { + + if (Configurator.is_isInitialised() == false) + new TSLEngineFatalException("The TSL Engine is not initialized!"); + + String tsldownloaddir = Configurator.get_TSLWorkingDirectoryPath() + "TslDownload"; + +// String hashcachedir = System.getProperty("iaik.xml.crypto.tsl.BinaryHashCache.DIR"); +// System.out.println("hashcachedir: " + hashcachedir); +// if (hashcachedir==null) +// hashcachedir = DEFAULT_HASHCACHE_DIR; + +// File hashcachefile = new File(hashcachedir); +// File[] filelist = hashcachefile.listFiles(); +// if (filelist != null) { +// for (File f : filelist) +// f.delete(); +// } + + File tsldownloadfile = new File(tsldownloaddir); + if (!tsldownloadfile.exists()) { + tsldownloadfile.mkdir(); + } + File[] tslfilelist = tsldownloadfile.listFiles(); + if (tslfilelist != null) { + for (File f : tslfilelist) + f.delete(); + } + + //create sqlLite database + File dbFile = new File(Configurator.get_TempdbFile()); + try { + dbFile.delete(); + dbFile.createNewFile(); + } catch (IOException e) { + throw new TSLEngineDiedException("Could not create temporary data base file", e); + } + + //the TSL library uses the iaik.util.logging environment. + //iaik.util.logging.Log.setLogLevel(iaik.util.logging.LogLevels.WARN); + iaik.util.logging.Log.setLogLevel(iaik.util.logging.LogLevels.OFF); + + log.info("Starting EU TSL import."); + + // Certificates in Germany, Estonia, Greece, Cyprus, + // Lithuainia, Hungary, Poland, Finland, Norway use SURNAME + log.debug("### SURNAME registered as " + ObjectID.surName + " ###"); + RFC2253NameParser.register("SURNAME", ObjectID.surName); + + XSecProvider.addAsProvider(false); + + TSLEngine tslEngine; + TslSqlConnectionWrapper connection = null; + + try { + // register the Https JSSE Wrapper + TLS.register(); + log.trace("### Https JSSE Wrapper registered ###"); + + + log.debug("### Connect to Database.###"); + connection = DbTables.connectToDatabaBase(dbFile, MODE.AUTO_COMMIT_ON); + + log.trace("### Connected ###"); + + // empty the database and recreate the tables + tslEngine = new TSLEngine(dbFile, Configurator.get_TSLWorkingDirectoryPath(), + connection, true, true); + + } catch (TSLEngineFatalException e1) { + throw new TSLEngineDiedException(e1); + + } + + // H.2.2.1 Same-scheme searching + // H.2.2.2 Known scheme searching + // H.2.2.3 "Blind" (unknown) scheme searching + Number tId = null; + Countries euTerritory = Countries.EU; + TSLImportContext topLevelTslContext = new TSLEUImportFromFileContext( + euTerritory, Configurator.get_euTSLURL(), Configurator.get_TSLWorkingDirectoryPath(), + Configurator.is_sqlMultithreaded(), + Configurator.is_throwExceptions(), Configurator.is_logExceptions(), + Configurator.is_throwWarnings(), Configurator.is_logWarnings(), + Configurator.is_nullRedundancies()); + + TSLEngineEU tslengineEU; + try { + tslengineEU = tslEngine.new TSLEngineEU(); + + } catch (TSLEngineFatalException e1) { + throw new TSLEngineDiedException(e1); + } + + // establish EU TSL trust anchor + ListIterator expectedEuTslSignerCerts = + tslEngine.loadCertificatesFromResource( + Configurator.get_euTrustAnchorsPath(), topLevelTslContext); + + log.debug("Process EU TSL"); + // process the EU TSL to receive the pointers to the other TSLs + // and the trust anchors for the TSL signers + Set> pointersToMsTSLs = null; + + try { + + tId = tslengineEU.processEUTSL(topLevelTslContext, expectedEuTslSignerCerts); + log.info("Process EU TSL finished"); + + log.debug(Thread.currentThread() + " waiting for other threads ..."); + + topLevelTslContext.waitForAllOtherThreads(); + log.debug(Thread.currentThread() + + " reactivated after other threads finished ..."); + + + // get the TSLs pointed from the EU TSL + LinkedHashMap tslMap = tslengineEU + .getOtherTslMap(tId, topLevelTslContext); + + pointersToMsTSLs = tslMap.entrySet(); + + //set Errors and Warrnings + + } catch (TSLEngineFatalRuntimeException e) { + throw new TSLEngineDiedException(topLevelTslContext.dumpFatals()); + + } catch (TSLTransactionFailedRuntimeException e) { + throw new TSLEngineDiedException(topLevelTslContext.dumpTransactionFaliures()); + } + + //Backup implementation if the EU TSL includes a false signer certificate + // establish additional trust anchors for member states +// Countries[] countriesWithPotentiallyWrongCertsOnEuTsl = { +// Countries.CZ, +// Countries.LU, +// Countries.ES, +// Countries.AT, +// }; + Countries[] countriesWithPotentiallyWrongCertsOnEuTsl = {}; + + Map> + trustAnchorsWrongOnEuTsl = loadCertificatesFromResource( + Configurator.get_msTrustAnchorsPath(), tslEngine, topLevelTslContext, + countriesWithPotentiallyWrongCertsOnEuTsl); + + log.info("Starting EU member TSL import."); + + for (Entry entry : pointersToMsTSLs) { + + TSLImportContext msTslContext; + + Countries expectedTerritory = entry.getValue().getSchemeTerritory(); + try { + +// if (expectedTerritory.equals("RO")) +// System.out.println("Stop"); + + Number otpId = entry.getKey(); + LocationAndCertHash lac = entry.getValue(); + + URL uriReference = null; + try { + uriReference = new URL(lac.getUrl()); + + } catch (MalformedURLException e) { + log.warn("Could not process: " + uriReference, e); + continue; + } + + String baseURI = uriReference == null ? "" : "" + uriReference; + + msTslContext = new TSLImportFromFileContext( + expectedTerritory, uriReference, otpId, Configurator.get_TSLWorkingDirectoryPath(), + Configurator.is_sqlMultithreaded(), + Configurator.is_throwExceptions(), Configurator.is_logExceptions(), + Configurator.is_throwWarnings(), Configurator.is_logWarnings(), + Configurator.is_nullRedundancies(), baseURI, trustAnchorsWrongOnEuTsl, + topLevelTslContext); + + ListIterator expectedTslSignerCerts = null; + expectedTslSignerCerts = tslEngine.getCertificates(lac, msTslContext); + + if (expectedTslSignerCerts == null) { + + // no signer certificate on the EU TSL + // ignore this msTSL and log a warning + log.warn("NO signer certificate found on EU TSL! " + + lac.getSchemeTerritory() + "TSL ignored."); + + } + else { + tslEngine.processMSTSL(topLevelTslContext, msTslContext, expectedTslSignerCerts); + } + + } catch (TSLExceptionB e) { + log.warn("Failed to process TSL. " + entry.getValue().getSchemeTerritory() + + " TSL ignored."); + log.debug("Failed to process TSL. " + entry, e); + continue; + } catch (TSLRuntimeException e) { + log.warn("Failed to process TSL. " + entry.getValue().getSchemeTerritory() + + " TSL ignored."); + log.debug("Failed to process TSL. " + entry, e); + continue; + } + } + + log.debug(Thread.currentThread() + " waiting for other threads ..."); + topLevelTslContext.waitForAllOtherThreads(); + + log.debug(_15.dumpAllThreads()); + log.debug(Thread.currentThread() + " reactivated after other threads finished ..."); + + connection = null; + try { + connection = DbTables.connectToDatabaBase(dbFile, MODE.AUTO_COMMIT_ON); + tslEngine.recreateTablesInvalidatedByImport(connection); + + + //TODO: implement database copy operation! + File working_database = new File(Configurator.get_dbFile()); + working_database.delete(); + copy(dbFile, working_database); + + + } catch (TSLEngineFatalException e) { + throw new TSLEngineDiedException(e); + + } finally { + try { + connection.closeConnection(); + + } catch (TSLEngineFatalException e) { + throw new TSLEngineDiedException(e); + + } + } + + return getQualifiedCACertificates(dateTime, countries, serviceLevelStatus); + } + + public void updateTSLs(Date dateTime, + String[] countries, String[] serviceLevelStatus) throws TSLEngineDiedException, TSLSearchException { + + if (Configurator.is_isInitialised() == false) + new TSLEngineFatalException("The TSL Engine is not initialized!"); + + String tsldownloaddir = Configurator.get_TSLWorkingDirectoryPath() + "TslDownload"; + +// String hashcachedir = System.getProperty("iaik.xml.crypto.tsl.BinaryHashCache.DIR"); +// System.out.println("hashcachedir: " + hashcachedir); +// if (hashcachedir==null) +// hashcachedir = DEFAULT_HASHCACHE_DIR; + +// File hashcachefile = new File(hashcachedir); +// File[] filelist = hashcachefile.listFiles(); +// if (filelist != null) { +// for (File f : filelist) +// f.delete(); +// } + + File tsldownloadfile = new File(tsldownloaddir); + if (!tsldownloadfile.exists()) { + tsldownloadfile.mkdir(); + } + File[] tslfilelist = tsldownloadfile.listFiles(); + if (tslfilelist != null) { + for (File f : tslfilelist) + f.delete(); + } + + //create sqlLite database + File dbFile = new File(Configurator.get_TempdbFile()); + try { + dbFile.delete(); + dbFile.createNewFile(); + } catch (IOException e) { + throw new TSLEngineDiedException("Could not create temporary data base file", e); + } + + //the TSL library uses the iaik.util.logging environment. + //iaik.util.logging.Log.setLogLevel(iaik.util.logging.LogLevels.WARN); + iaik.util.logging.Log.setLogLevel(iaik.util.logging.LogLevels.OFF); + + log.info("Starting EU TSL import."); + + // Certificates in Germany, Estonia, Greece, Cyprus, + // Lithuainia, Hungary, Poland, Finland, Norway use SURNAME + log.debug("### SURNAME registered as " + ObjectID.surName + " ###"); + RFC2253NameParser.register("SURNAME", ObjectID.surName); + + XSecProvider.addAsProvider(false); + + TSLEngine tslEngine; + TslSqlConnectionWrapper connection = null; + + try { + // register the Https JSSE Wrapper + TLS.register(); + log.trace("### Https JSSE Wrapper registered ###"); + + + log.debug("### Connect to Database.###"); + connection = DbTables.connectToDatabaBase(dbFile, MODE.AUTO_COMMIT_ON); + + log.trace("### Connected ###"); + + // empty the database and recreate the tables + tslEngine = new TSLEngine(dbFile, Configurator.get_TSLWorkingDirectoryPath(), + connection, true, true); + + } catch (TSLEngineFatalException e1) { + throw new TSLEngineDiedException(e1); + + } + + // H.2.2.1 Same-scheme searching + // H.2.2.2 Known scheme searching + // H.2.2.3 "Blind" (unknown) scheme searching + Number tId = null; + Countries euTerritory = Countries.EU; + TSLImportContext topLevelTslContext = new TSLEUImportFromFileContext( + euTerritory, Configurator.get_euTSLURL(), Configurator.get_TSLWorkingDirectoryPath(), + Configurator.is_sqlMultithreaded(), + Configurator.is_throwExceptions(), Configurator.is_logExceptions(), + Configurator.is_throwWarnings(), Configurator.is_logWarnings(), + Configurator.is_nullRedundancies()); + + TSLEngineEU tslengineEU; + try { + tslengineEU = tslEngine.new TSLEngineEU(); + + } catch (TSLEngineFatalException e1) { + throw new TSLEngineDiedException(e1); + } + + // establish EU TSL trust anchor + ListIterator expectedEuTslSignerCerts = + tslEngine.loadCertificatesFromResource( + Configurator.get_euTrustAnchorsPath(), topLevelTslContext); + + log.debug("Process EU TSL"); + // process the EU TSL to receive the pointers to the other TSLs + // and the trust anchors for the TSL signers + Set> pointersToMsTSLs = null; + + try { + + tId = tslengineEU.processEUTSL(topLevelTslContext, expectedEuTslSignerCerts); + log.info("Process EU TSL finished"); + + log.debug(Thread.currentThread() + " waiting for other threads ..."); + + topLevelTslContext.waitForAllOtherThreads(); + log.debug(Thread.currentThread() + + " reactivated after other threads finished ..."); + + + // get the TSLs pointed from the EU TSL + LinkedHashMap tslMap = tslengineEU + .getOtherTslMap(tId, topLevelTslContext); + + pointersToMsTSLs = tslMap.entrySet(); + + //set Errors and Warrnings + + } catch (TSLEngineFatalRuntimeException e) { + throw new TSLEngineDiedException(topLevelTslContext.dumpFatals()); + + } catch (TSLTransactionFailedRuntimeException e) { + throw new TSLEngineDiedException(topLevelTslContext.dumpTransactionFaliures()); + } + + //Backup implementation if the EU TSL includes a false signer certificate + // establish additional trust anchors for member states +// Countries[] countriesWithPotentiallyWrongCertsOnEuTsl = { +// Countries.CZ, +// Countries.LU, +// Countries.ES, +// Countries.AT, +// }; + Countries[] countriesWithPotentiallyWrongCertsOnEuTsl = {}; + + Map> + trustAnchorsWrongOnEuTsl = loadCertificatesFromResource( + Configurator.get_msTrustAnchorsPath(), tslEngine, topLevelTslContext, + countriesWithPotentiallyWrongCertsOnEuTsl); + + log.info("Starting EU member TSL import."); + + for (Entry entry : pointersToMsTSLs) { + + TSLImportContext msTslContext; + + Countries expectedTerritory = entry.getValue().getSchemeTerritory(); + try { + +// if (expectedTerritory.equals("RO")) +// System.out.println("Stop"); + + Number otpId = entry.getKey(); + LocationAndCertHash lac = entry.getValue(); + + URL uriReference = null; + try { + uriReference = new URL(lac.getUrl()); + + } catch (MalformedURLException e) { + log.warn("Could not process: " + uriReference, e); + continue; + } + + String baseURI = uriReference == null ? "" : "" + uriReference; + + msTslContext = new TSLImportFromFileContext( + expectedTerritory, uriReference, otpId, Configurator.get_TSLWorkingDirectoryPath(), + Configurator.is_sqlMultithreaded(), + Configurator.is_throwExceptions(), Configurator.is_logExceptions(), + Configurator.is_throwWarnings(), Configurator.is_logWarnings(), + Configurator.is_nullRedundancies(), baseURI, trustAnchorsWrongOnEuTsl, + topLevelTslContext); + + ListIterator expectedTslSignerCerts = null; + expectedTslSignerCerts = tslEngine.getCertificates(lac, msTslContext); + + if (expectedTslSignerCerts == null) { + + // no signer certificate on the EU TSL + // ignore this msTSL and log a warning + log.warn("NO signer certificate found on EU TSL! " + + lac.getSchemeTerritory() + "TSL ignored."); + + } + else { + tslEngine.processMSTSL(topLevelTslContext, msTslContext, expectedTslSignerCerts); + } + + } catch (TSLExceptionB e) { + log.warn("Failed to process TSL. " + entry.getValue().getSchemeTerritory() + + " TSL ignored."); + log.debug("Failed to process TSL. " + entry, e); + continue; + } catch (TSLRuntimeException e) { + log.warn("Failed to process TSL. " + entry.getValue().getSchemeTerritory() + + " TSL ignored."); + log.debug("Failed to process TSL. " + entry, e); + continue; + } + } + + log.debug(Thread.currentThread() + " waiting for other threads ..."); + topLevelTslContext.waitForAllOtherThreads(); + + log.debug(_15.dumpAllThreads()); + log.debug(Thread.currentThread() + " reactivated after other threads finished ..."); + + connection = null; + try { + connection = DbTables.connectToDatabaBase(dbFile, MODE.AUTO_COMMIT_ON); + tslEngine.recreateTablesInvalidatedByImport(connection); + + + //TODO: implement database copy operation! + File working_database = new File(Configurator.get_dbFile()); + working_database.delete(); + copy(dbFile, working_database); + + + } catch (TSLEngineFatalException e) { + throw new TSLEngineDiedException(e); + + } finally { + try { + connection.closeConnection(); + + } catch (TSLEngineFatalException e) { + throw new TSLEngineDiedException(e); + + } + } + + //return getQualifiedCACertificates(dateTime, countries, serviceLevelStatus); + } + + public ArrayList getQualifiedCACertificates(Date dateTime, + String[] serviceLevelStatus) throws TSLEngineDiedException, + TSLSearchException { + + if (Configurator.is_isInitialised() == false) + new TSLEngineFatalException("The TSL Engine is not initialized!"); + + return getQualifiedCACertificates(dateTime, null, serviceLevelStatus); + } + + public ArrayList getQualifiedCACertificates(Date dateTime, + String[] countries, String[] serviceLevelStatus) + throws TSLEngineDiedException, TSLSearchException { + + if (Configurator.is_isInitialised() == false) + new TSLEngineFatalException("The TSL Engine is not initialized!"); + + //TODO: database + File dbFile = new File(Configurator.get_TempdbFile()); + //File dbFile = new File(Configurator.get_dbFile()); + if(!dbFile.exists()) + throw new TSLEngineDiedException("Could not open data base file"); + + log.debug("### Connect to Database ###"); + TslSqlConnectionWrapper readConnection = null; + + try { + readConnection = DbTables.connectToDatabaBase(dbFile, MODE.READ_ONLY); + + TSLEngine tslEngine = new TSLEngine(dbFile, Configurator.get_TSLWorkingDirectoryPath(), + readConnection, false, false); + + log.debug("### Connected ###"); + //TODO: maybe add "TSA/QTST for qualified timestamps + try { + TSLCertsExporter certsExporter; + certsExporter = tslEngine.createCertsExporter( + readConnection, + countries, + new String[]{_STYPETEMPLATE_CAQC}, + serviceLevelStatus + ); + + return certsExporter.exportAsArray(dateTime, null); + + } catch (TSLEngineFatalException e) { + e.printStackTrace(); + _l.err("could not export Certs", e); + throw new TSLEngineDiedException(e); + } + + } catch (TSLEngineFatalException e1) { + throw new TSLEngineDiedException(e1); + + } finally { + try { + readConnection.closeConnection(); + + } catch (TSLEngineFatalException e) { + throw new TSLEngineDiedException(e); + } + } + } + + public boolean checkQC(java.security.cert.X509Certificate[] chain) + throws TSLSearchException, TSLEngineDiedException { + + if (Configurator.is_isInitialised() == false) + new TSLEngineFatalException("The TSL Engine is not initialized!"); + + return checkQC(chain, 1); + } + + public boolean checkSSCD(java.security.cert.X509Certificate[] chain) + throws TSLSearchException, TSLEngineDiedException { + + if (Configurator.is_isInitialised() == false) + new TSLEngineFatalException("The TSL Engine is not initialized!"); + + return checkSSCD(chain, 1); + } + + public boolean checkQC(java.security.cert.X509Certificate[] chain, int cnt) + throws TSLSearchException, TSLEngineDiedException { + + if (Configurator.is_isInitialised() == false) + new TSLEngineFatalException("The TSL Engine is not initialized!"); + + LinkedHashMap tslResultC = checkchain(chain, cnt); + + //get first result + java.util.Map.Entry resultmap = tslResultC.entrySet().iterator().next(); + TSLResult tslresult = tslResultC.entrySet().iterator().next().getValue(); + + + + if (tslresult == null) { + log.info("Certificate: " + resultmap.getKey().getSubjectDN() + + " not on the TSL"); + throw new TSLSearchException("Certificate: " + resultmap.getKey().getSubjectDN() + + " not on the TSL"); + } + + if (tslresult instanceof TSLResultEndEntity) { + TSLResultEndEntity ree = (TSLResultEndEntity) tslresult; + + + String sType = (String) ree.get(Service.C.sType); + + log.info("Cert: " + resultmap.getKey().getSubjectDN() + " sType=" + sType); + + //TODO: maybe add "TSA/QTST for qualified timestamps + if (sType.equals(_STYPETEMPLATE_CAQC)) + return true; + else + return false; + } + + else if (tslresult instanceof TSLResultImpl) { + + //TODO: Certificate is not of Type EndEntity (equal to QCSSCD check) + // Is FALSE the correct answer? + return false; + } + + throw new TSLEngineDiedException("TSL Result has an unknown Class type"); + } + + public boolean checkSSCD(java.security.cert.X509Certificate[] chain, int cnt) + throws TSLSearchException, TSLEngineDiedException { + + if (Configurator.is_isInitialised() == false) + new TSLEngineFatalException("The TSL Engine is not initialized!"); + + LinkedHashMap tslResultC = checkchain(chain, cnt); + + //get first result + java.util.Map.Entry resultmap = tslResultC.entrySet().iterator().next(); + TSLResult tslresult = tslResultC.entrySet().iterator().next().getValue(); + + if (tslresult == null) { + log.info("Certificate: " + resultmap.getKey().getSubjectDN() + " not on the TSL"); + throw new TSLSearchException("Certificate: " + resultmap.getKey().getSubjectDN() + + " not on the TSL"); + } + + if (tslresult instanceof TSLResultEndEntity) { + TSLResultEndEntity ree = (TSLResultEndEntity) tslresult; + + List qualifier = ree.getQualifierList(); + + Iterator qualifierlist = qualifier.iterator(); + + String uri = ""; + + while (qualifierlist.hasNext()) { + uri = qualifierlist.next().getUri(); + + log.debug("Cert: " + resultmap.getKey().getSubjectDN() + " SSCD=" + uri); + + if (uri.contains(_QCSSCDURI)) { + return true; + } + else { + return false; + } + } + return false; + } + + else if (tslresult instanceof TSLResultImpl) { + + //TODO: Certificate is not of Type EndEntity (equal to QC check) + // Is FALSE the correct answer? + return false; + } + + throw new TSLEngineDiedException("TSL Result has an unknown Class type"); + } + + + + private LinkedHashMap checkchain(java.security.cert.X509Certificate[] chain, int cnt) + throws TSLSearchException, TSLEngineDiedException { + + File dbFile = new File(Configurator.get_dbFile()); + if(!dbFile.exists()) + throw new TSLEngineDiedException("Could not open data base file"); + + try { + + log.debug("### Connect to Database ###"); + TslSqlConnectionWrapper readConnection; + readConnection = DbTables.connectToDatabaBase(dbFile, MODE.READ_ONLY); + log.debug("### Connected ###"); + + TSLEngine tslEngine = new TSLEngine(dbFile, Configurator.get_TSLWorkingDirectoryPath(), + readConnection, false, false); + + XSecProvider.addAsProvider(false); + log.debug("### XSECT registered ###"); + // register the additional IAIK ECC provider + Security.addProvider(EccProviderAdapter.getEccProvider()); + log.debug("### ECC registered ###"); + + + TSLEvaluationContext context = new TSLEvaluationContext( + Configurator.get_TSLWorkingDirectoryPath(), + Configurator.is_sqlMultithreaded(), + Configurator.is_throwExceptions(), + Configurator.is_logExceptions(), + Configurator.is_throwWarnings(), + Configurator.is_logWarnings()); + + TSLCertEvaluator tslCertEvaluator = tslEngine.createEvaluator(context, + readConnection); + + Date signingTime = new Date(); + + // has to be later or equal + Date now = new Date(); + + LinkedHashMap tslResultC = tslCertEvaluator + .evaluate(TSLCertEvaluator.CHAIN_MODEL, chain, signingTime, now, context); + + return tslResultC; + + } catch (TSLEngineFatalException e1) { + throw new TSLEngineDiedException(e1); + } + + + } + + private static Map> loadCertificatesFromResource( + final String msTrustAnchorsPath, TSLEngine tslEngine, + TSLImportContext topLevelTslContext, Countries[] countriesWithNoCertsOnEuTsl) + throws TSLEngineDiedException { + Map> trustAnchorsMissingOnEuTsl; + trustAnchorsMissingOnEuTsl = + new HashMap>( + countriesWithNoCertsOnEuTsl.length); + + for (int i = 0; i < countriesWithNoCertsOnEuTsl.length; i++) { + Countries country = countriesWithNoCertsOnEuTsl[i]; + + final String mspath = msTrustAnchorsPath + country + "/"; + + ListIterator msCerts = + tslEngine.loadCertificatesFromResource(mspath, topLevelTslContext); + + trustAnchorsMissingOnEuTsl.put(country, msCerts); + } + return trustAnchorsMissingOnEuTsl; + } + + + private void copy(File source, File destination) throws TSLEngineDiedException { + try { + FileInputStream fileInputStream = new FileInputStream(source); + FileOutputStream fileOutputStream = new FileOutputStream(destination); + FileChannel inputChannel = fileInputStream.getChannel(); + FileChannel outputChannel = fileOutputStream.getChannel(); + + transfer(inputChannel, outputChannel, source.length(), false); + + fileInputStream.close(); + fileOutputStream.close(); + + destination.setLastModified(source.lastModified()); + } catch (Exception e) { + + throw new TSLEngineDiedException("Error during TSL database copy operation!."); + } + } + + private void transfer(FileChannel fileChannel, ByteChannel byteChannel, long lengthInBytes, boolean verbose) + throws IOException { + + long overallBytesTransfered = 0L; + long time = -System.currentTimeMillis(); + + while (overallBytesTransfered < lengthInBytes) { + long bytesTransfered = 0L; + bytesTransfered = fileChannel.transferTo(overallBytesTransfered, Math.min(1024 * 1024, lengthInBytes - overallBytesTransfered), byteChannel); + overallBytesTransfered += bytesTransfered; + if (verbose) { + System.out.println("overall bytes transfered: " + overallBytesTransfered + " progress " + (Math.round(overallBytesTransfered / ((double) lengthInBytes) * 100.0)) + "%"); + } + } + time += System.currentTimeMillis(); + + if (verbose) { + System.out.println("Transfered: " + overallBytesTransfered + " bytes in: " + (time / 1000) + " s -> " + (overallBytesTransfered / 1024.0) / (time / 1000.0) + " kbytes/s"); + } + } + + +// /** +// * @param tslResultC +// * @param context +// */ +// private static void printResultDetails( +// LinkedHashMap tslResultC, TSLContext context) { +// +// for (java.util.Map.Entry e : tslResultC +// .entrySet()) { +// +// TSLResult r = e.getValue(); +// +// if (r == null) { +// log.info("Certificate: " + e.getKey().getSubjectDN() +// + " not on the TSL"); +// continue; +// } +// +// if (r instanceof TSLResultEndEntity) { +// TSLResultEndEntity ree = (TSLResultEndEntity) r; +// +// String status = (String) ree.get(Service.C.status); +// +// Date startDate = context.getDate(ree.get(Service.C.startDate)); +// Long endDateL = (Long) ree.get(ServiceView.C.endDate); +// Date endDate = endDateL == null ? null : new Date(endDateL); +// +// String sType = (String) ree.get(Service.C.sType); +// +// List tslQual = ree.getQualifierList(); +// +// StringBuilder qualList = new StringBuilder(""); +// if (!tslQual.isEmpty()) { +// qualList.append("\n~~~~~~~~~~~~ TSL-Qualifiers ~~~~~~~~~~~~\n"); +// for (QualifierType qual : tslQual) { +// qualList.append(qual.getUri() + "\n"); +// } +// qualList.append("~~~~~~~~~~~~~~~~~ End ~~~~~~~~~~~~~~~~\n"); +// } +// +// log.info("############### EndEntity ###############\n" +// + _.printCertificate(e.getKey()) + qualList + "\nServiceProvider: " +// + ree.getSerivceProvider().getSubjectDN() + "\n" + Service.C.sType +// + ": " + sType + "\n" + Service.C.status + ": " + status + "\n" +// + Service.C.startDate + ": " + startDate + "\n" +// + ServiceView.C.endDate + ": " + endDate); +// log.info("############ ServiceProvider ############\n" +// + _.printCertificate(ree.getSerivceProvider())); +// log.info("################# END #################"); +// +// continue; +// } +// +// if (r instanceof TSLResultImpl) { +// TSLResultImpl ri = (TSLResultImpl) r; +// log.info("----------------- BEGIN -----------------\n" +// + "Certificate: " + e.getKey().getSubjectDN() + "\n" + ri.toString()); +// +// int i = 1; +// for (Iterator iter = ri.getRows().iterator(); iter.hasNext();) { +// Row row = (Row) iter.next(); +// // TSPServiceInformationType sInfo = +// // ((JAXBElement) +// // row.s_.get(Service.C.sInfo)).getValue(); +// String status = (String) row.s_.get(Service.C.status); +// +// Date startDate = context.getDate(row.s_.get(Service.C.startDate)); +// +// Date endDate = context.getDate(row.s_.get(ServiceView.C.endDate)); +// +// String sType = (String) row.s_.get(Service.C.sType); +// +// log.info("----------------- (" + (i++) + ") -----------------\n" +// + Service.C.sType + ": " + sType + " " + Service.C.status + ": " +// + status + "\n" + Service.C.startDate + ": " + startDate + "\n" +// + ServiceView.C.endDate + ": " + endDate + "\n" + row.s_); +// +// row.s_.get(Service.C.sExt); +// } +// log.info("----------------- END -----------------"); +// } +// } +// } +} diff --git a/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/connector/TSLConnectorInterface.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/connector/TSLConnectorInterface.java new file mode 100644 index 0000000..4992f75 --- /dev/null +++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/connector/TSLConnectorInterface.java @@ -0,0 +1,95 @@ +package at.gv.egovernment.moa.spss.tsl.connector; + +import iaik.xml.crypto.tsl.ex.TSLEngineDiedException; +import iaik.xml.crypto.tsl.ex.TSLSearchException; + +import java.io.File; +import java.util.ArrayList; +import java.util.Date; + +import java.security.cert.X509Certificate; + +public interface TSLConnectorInterface { + + /** + * Initial the MOA TSL Connector.
+ * The hashcache directory must be set via "System-Property "iaik.xml.crypto.tsl.BinaryHashCache.DIR"!!! + * + * @author TLenz + * @param euTSLURL - URL to TrustList + * @param TSLWorkingDirectoryPath - Path to a folder which should be used by the TSL engine. (/A/B/.../) + * @param jdbcURL - ... + * @param jdbcDriverClass - ... + */ + void initialize(String euTSLURL, String TSLWorkingDirectoryPath, String jdbcURL, String jdbcDriverClass) throws TSLEngineDiedException; + + + /** + * Perform an update of all certificates which are on EU TSL and all MS TSLs and create an locale TSL database. + * The old locale TSL database is removed and a new database is created. + * + * @author TLenz + * @param dateTime - ... + * @param serviceLevelStatus - String Array of ServiceLevelStatus. For example new String[]{"accredited","undersupervision"} + * @return List of certificates with the selected properties + */ + ArrayList updateAndGetQualifiedCACertificates(Date dateTime, String[] serviceLevelStatus) + throws TSLEngineDiedException, TSLSearchException ; + + /** + * Perform an update of all certificates which are on EU TSL and all MS TSLs and create an locale TSL database. + * The old locale TSL database is removed and a new database is created. + * + * @author TLenz + * @param dateTime - ... + * @param countries - String Array of country codes. For example new Sting[]{"AT","IT","BE"} + * @param serviceLevelStatus - String Array of ServiceLevelStatus. For example new String[]{"accredited","undersupervision"} + * @return List of certificates with the selected properties + */ + ArrayList updateAndGetQualifiedCACertificates(Date dateTime, String[] countries, String[] serviceLevelStatus) + throws TSLEngineDiedException, TSLSearchException ; + + /** + * Check the http://uri.etis.org/TrstSvc/Svctype/CA/QC characteristic of a certificate by using the TSL information. + * This method uses information from the local TSL database. + * + * @author TLenz + * @param certificate - An X509 certificate. + * @return Return true, if the certificate comprises the http://uri.etis.org/TrstSvc/Svctype/CA/QC characteristic. + */ + boolean checkQC(X509Certificate[] certificate) throws TSLSearchException, TSLEngineDiedException; + + /** + * Check the http://uri.etis.org/TrstSvc/eSigDir-1999-93-ECTrustedList/SvcInfoExt/QCWithSSCD characteristic of a certificate by using the TSL information. + * This method uses information from the local TSL database. + * + * @author TLenz + * @param certificate - An X509 certificate. + * @return Return true, if the certificate comprises the http://uri.etis.org/TrstSvc/eSigDir-1999-93-ECTrustedList/SvcInfoExt/QCWithSSCD characteristic. + */ + boolean checkSSCD(X509Certificate[] certificate) throws TSLSearchException, TSLEngineDiedException; + + /** + * Get a list of certificates form the local TSL database with the selected properties. + * + * @author TLenz + * @param dateTime - ... + * @param serviceLevelStatus - String Array of ServiceLevelStatus. For example new String[]{"accredited","undersupervision"} + * @return List of certificates with the selected properties + */ + ArrayList getQualifiedCACertificates(Date dateTime, String[] serviceLevelStatus) + throws TSLEngineDiedException, TSLSearchException; + + /** + * Get a list of certificates form the local TSL database with the selected properties. + * + * @author TLenz + * @param dateTime - ... + * @param countries - String Array of countrie codes. For example new Sting[]{"AT","IT","BE"} + * @param serviceLevelStatus - String Array of ServiceLevelStatus. For example new String[]{"accredited","undersupervision"} + * @return List of certificates with the selected properties + */ + ArrayList getQualifiedCACertificates(Date dateTime, String[] countries, String[] serviceLevelStatus) + throws TSLEngineDiedException, TSLSearchException; + +} -- cgit v1.2.3