aboutsummaryrefslogtreecommitdiff
path: root/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl
diff options
context:
space:
mode:
authorAndreas Fitzek <andreas.fitzek@iaik.tugraz.at>2015-11-03 14:38:34 +0100
committerAndreas Fitzek <andreas.fitzek@iaik.tugraz.at>2015-11-03 14:38:34 +0100
commit0872d2d8a64fd701776b272f49222428d8def07f (patch)
tree0954a523ad2cc7ad615dbbae5282dd56497e4c6e /moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl
parente635718b8d6a12e4e80207c8bdf30b02eed3f2ab (diff)
downloadmoa-sig-0872d2d8a64fd701776b272f49222428d8def07f.tar.gz
moa-sig-0872d2d8a64fd701776b272f49222428d8def07f.tar.bz2
moa-sig-0872d2d8a64fd701776b272f49222428d8def07f.zip
initial commit
Diffstat (limited to 'moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl')
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/config/Configurator.java130
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/connector/TSLConnector.java972
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/connector/TSLConnectorInterface.java95
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/exception/MitigatedTSLSecurityException.java17
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/timer/TSLUpdaterTimerTask.java212
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/utils/CertificateReader.java155
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/utils/Mitigation.java15
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/utils/TSLEUImportFromFileContext.java140
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/utils/TSLEvaluationContext.java134
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/utils/TSLImportFromFileContext.java850
10 files changed, 2720 insertions, 0 deletions
diff --git a/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/config/Configurator.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/config/Configurator.java
new file mode 100644
index 0000000..defaedd
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/config/Configurator.java
@@ -0,0 +1,130 @@
+package at.gv.egovernment.moa.spss.tsl.config;
+
+import iaik.util.logging._l;
+import iaik.xml.crypto.tsl.ex.TSLEngineDiedException;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+public class Configurator {
+
+ private static final String _TMPDBFILENAME = "temp_tsl.sqlite";
+
+ private static boolean _sqlMultithreaded;
+ private static boolean _throwExceptions;
+ private static boolean _logExceptions;
+ private static boolean _throwWarnings;
+ private static boolean _logWarnings;
+ private static boolean _nullRedundancies;
+ private static URL _euTSLURL;
+ private static String _TSLWorkingDirectoryPath;
+ private static String _dbFile;
+ private static String _euTrustAnchorsPath;
+ private static String _msTrustAnchorsPath;
+
+
+ private static boolean _isInitialised = false;
+
+
+ /**
+ *
+ */
+ public static void initial(String euTSLURL, String TSLWorkingDirectoryPath, String jdbcURL, String jdbcDriverClass)
+ throws TSLEngineDiedException {
+
+
+ if (!_isInitialised) {
+ try {
+ _euTSLURL = new URL(euTSLURL);
+ } catch (MalformedURLException e) {
+ _l.err("Bad TSL URL: " + euTSLURL, e);
+ throw new TSLEngineDiedException(e);
+ }
+
+ if (!TSLWorkingDirectoryPath.endsWith("/"))
+ TSLWorkingDirectoryPath += "/";
+
+ Configurator._TSLWorkingDirectoryPath = TSLWorkingDirectoryPath;
+
+ initialDefaultConfig();
+
+ _isInitialised = true;
+ }
+ }
+
+ public static String get_TSLWorkingDirectoryPath() {
+ return _TSLWorkingDirectoryPath;
+ }
+
+ public static String get_dbFile() {
+ return _dbFile;
+ }
+
+ public static void set_dbFileName(String _dbFile) {
+ Configurator._dbFile = _TSLWorkingDirectoryPath + _dbFile;
+ }
+
+ public static String get_euTrustAnchorsPath() {
+ return _euTrustAnchorsPath;
+ }
+
+ public static String get_msTrustAnchorsPath() {
+ return _msTrustAnchorsPath;
+ }
+
+ public static boolean is_sqlMultithreaded() {
+ return _sqlMultithreaded;
+ }
+
+ public static boolean is_throwExceptions() {
+ return _throwExceptions;
+ }
+
+ public static boolean is_logExceptions() {
+ return _logExceptions;
+ }
+
+ public static boolean is_throwWarnings() {
+ return _throwWarnings;
+ }
+
+ public static boolean is_logWarnings() {
+ return _logWarnings;
+ }
+
+ public static boolean is_nullRedundancies() {
+ return _nullRedundancies;
+ }
+
+ public static URL get_euTSLURL() {
+ return _euTSLURL;
+ }
+
+ public static boolean is_isInitialised() {
+ return _isInitialised;
+ }
+
+ public static String get_TempdbFile() {
+ return _TSLWorkingDirectoryPath + _TMPDBFILENAME;
+ }
+
+ public static void set_euTrustAnchorsPath(String _euTrustAnchorsPath) {
+ Configurator._euTrustAnchorsPath = _euTrustAnchorsPath;
+ }
+
+ public static void set_msTrustAnchorsPath(String _msTrustAnchorsPath) {
+ Configurator._msTrustAnchorsPath = _msTrustAnchorsPath;
+ }
+
+ private static void initialDefaultConfig() {
+ _sqlMultithreaded = false;
+ _throwExceptions = true;
+ _logExceptions = true;
+ _throwWarnings = false;
+ _logWarnings = true;
+ _nullRedundancies = false;
+ _dbFile = _TSLWorkingDirectoryPath + "tsl.sqlite";
+ _euTrustAnchorsPath = _TSLWorkingDirectoryPath + "trust/eu/";
+ _msTrustAnchorsPath = "/trust/ms/";
+ }
+}
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<String> STYPETEMPLATES = Collections.unmodifiableList(new ArrayList<String>(){
+ 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<File> 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<File> 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<java.security.cert.X509Certificate> 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<Entry<Number, LocationAndCertHash>> 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<Number, LocationAndCertHash> 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<Countries, java.util.ListIterator<java.security.cert.X509Certificate>>
+ trustAnchorsWrongOnEuTsl = loadCertificatesFromResource(
+ Configurator.get_msTrustAnchorsPath(), tslEngine, topLevelTslContext,
+ countriesWithPotentiallyWrongCertsOnEuTsl);
+
+ log.info("Starting EU member TSL import.");
+
+ for (Entry<Number, LocationAndCertHash> 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<X509Certificate> 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<java.security.cert.X509Certificate> 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<Entry<Number, LocationAndCertHash>> 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<Number, LocationAndCertHash> 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<Countries, java.util.ListIterator<java.security.cert.X509Certificate>>
+ trustAnchorsWrongOnEuTsl = loadCertificatesFromResource(
+ Configurator.get_msTrustAnchorsPath(), tslEngine, topLevelTslContext,
+ countriesWithPotentiallyWrongCertsOnEuTsl);
+
+ log.info("Starting EU member TSL import.");
+
+ for (Entry<Number, LocationAndCertHash> 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<X509Certificate> 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<File> 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<File> 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<X509Certificate, TSLResult> tslResultC = checkchain(chain, cnt);
+
+ //get first result
+ java.util.Map.Entry<java.security.cert.X509Certificate, TSLResult> 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<X509Certificate, TSLResult> tslResultC = checkchain(chain, cnt);
+
+ //get first result
+ java.util.Map.Entry<java.security.cert.X509Certificate, TSLResult> 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<QualifierType> qualifier = ree.getQualifierList();
+
+ Iterator<QualifierType> 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<java.security.cert.X509Certificate, TSLResult> 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<java.security.cert.X509Certificate, TSLResult> tslResultC = tslCertEvaluator
+ .evaluate(TSLCertEvaluator.CHAIN_MODEL, chain, signingTime, now, context);
+
+ return tslResultC;
+
+ } catch (TSLEngineFatalException e1) {
+ throw new TSLEngineDiedException(e1);
+ }
+
+
+ }
+
+ private static Map<Countries, java.util.ListIterator<java.security.cert.X509Certificate>> loadCertificatesFromResource(
+ final String msTrustAnchorsPath, TSLEngine tslEngine,
+ TSLImportContext topLevelTslContext, Countries[] countriesWithNoCertsOnEuTsl)
+ throws TSLEngineDiedException {
+ Map<Countries, java.util.ListIterator<java.security.cert.X509Certificate>> trustAnchorsMissingOnEuTsl;
+ trustAnchorsMissingOnEuTsl =
+ new HashMap<Countries, java.util.ListIterator<java.security.cert.X509Certificate>>(
+ countriesWithNoCertsOnEuTsl.length);
+
+ for (int i = 0; i < countriesWithNoCertsOnEuTsl.length; i++) {
+ Countries country = countriesWithNoCertsOnEuTsl[i];
+
+ final String mspath = msTrustAnchorsPath + country + "/";
+
+ ListIterator<java.security.cert.X509Certificate> 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<java.security.cert.X509Certificate, TSLResult> tslResultC, TSLContext context) {
+//
+// for (java.util.Map.Entry<java.security.cert.X509Certificate, TSLResult> 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<QualifierType> 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<TSPServiceInformationType>)
+// // 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.<br>
+ * <b>The hashcache directory must be set via "System-Property "iaik.xml.crypto.tsl.BinaryHashCache.DIR"!!!</b>
+ *
+ * @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<File> 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<File> 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<File> 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<File> getQualifiedCACertificates(Date dateTime, String[] countries, String[] serviceLevelStatus)
+ throws TSLEngineDiedException, TSLSearchException;
+
+}
diff --git a/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/exception/MitigatedTSLSecurityException.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/exception/MitigatedTSLSecurityException.java
new file mode 100644
index 0000000..d580405
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/exception/MitigatedTSLSecurityException.java
@@ -0,0 +1,17 @@
+package at.gv.egovernment.moa.spss.tsl.exception;
+
+import iaik.xml.crypto.tsl.ex.TSLSecurityException;
+
+import org.xml.sax.Locator;
+
+public final class MitigatedTSLSecurityException extends
+ TSLSecurityException {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ public MitigatedTSLSecurityException(Type t, Locator l) {
+ super(t, l);
+ }
+} \ No newline at end of file
diff --git a/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/timer/TSLUpdaterTimerTask.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/timer/TSLUpdaterTimerTask.java
new file mode 100644
index 0000000..e06abe4
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/timer/TSLUpdaterTimerTask.java
@@ -0,0 +1,212 @@
+package at.gv.egovernment.moa.spss.tsl.timer;
+
+import iaik.pki.store.certstore.CertStoreException;
+import iaik.pki.store.certstore.CertStoreParameters;
+import iaik.pki.store.truststore.TrustStoreException;
+import iaik.pki.store.truststore.TrustStoreProfile;
+import iaik.pki.store.utils.StoreUpdater;
+import iaik.server.ConfigurationData;
+import iaik.x509.X509Certificate;
+import iaik.xml.crypto.tsl.ex.TSLEngineDiedException;
+import iaik.xml.crypto.tsl.ex.TSLSearchException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TimerTask;
+
+import at.gv.egovernment.moa.logging.LogMsg;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.api.common.TSLConfiguration;
+import at.gv.egovernment.moa.spss.server.config.ConfigurationException;
+import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider;
+import at.gv.egovernment.moa.spss.server.config.TrustProfile;
+import at.gv.egovernment.moa.spss.server.iaik.config.IaikConfigurator;
+import at.gv.egovernment.moa.spss.server.iaik.pki.store.truststore.TrustStoreProfileImpl;
+import at.gv.egovernment.moa.spss.server.logging.TransactionId;
+import at.gv.egovernment.moa.spss.tsl.connector.TSLConnector;
+import at.gv.egovernment.moa.spss.util.MessageProvider;
+import at.gv.egovernment.moa.util.StringUtils;
+
+
+public class TSLUpdaterTimerTask extends TimerTask {
+
+ public static TSLConnector tslconnector_;
+
+ public static ConfigurationData configData_ = null;
+
+ @Override
+ public void run() {
+
+ try {
+ Logger.info("Start TSL Update");
+ update();
+ Logger.info("Finished TSL Update");
+ } catch (TSLEngineDiedException e) {
+ MessageProvider msg = MessageProvider.getInstance();
+ Logger.error(new LogMsg(msg.getMessage("tsl.00", null)), e);
+ } catch (TSLSearchException e) {
+ MessageProvider msg = MessageProvider.getInstance();
+ Logger.error(new LogMsg(msg.getMessage("tsl.00", null)), e);
+ } catch (ConfigurationException e) {
+ MessageProvider msg = MessageProvider.getInstance();
+ Logger.error(new LogMsg(msg.getMessage("tsl.00", null)), e);
+ } catch (MOAApplicationException e) {
+ MessageProvider msg = MessageProvider.getInstance();
+ Logger.error(new LogMsg(msg.getMessage("tsl.00", null)), e);
+ } catch (CertStoreException e) {
+ MessageProvider msg = MessageProvider.getInstance();
+ Logger.error(new LogMsg(msg.getMessage("tsl.00", null)), e);
+ } catch (TrustStoreException e) {
+ MessageProvider msg = MessageProvider.getInstance();
+ Logger.error(new LogMsg(msg.getMessage("tsl.00", null)), e);
+ } catch (FileNotFoundException e) {
+ MessageProvider msg = MessageProvider.getInstance();
+ Logger.error(new LogMsg(msg.getMessage("tsl.00", null)), e);
+ } catch (IOException e) {
+ MessageProvider msg = MessageProvider.getInstance();
+ Logger.error(new LogMsg(msg.getMessage("tsl.00", null)), e);
+ } catch (CertificateException e) {
+ MessageProvider msg = MessageProvider.getInstance();
+ Logger.error(new LogMsg(msg.getMessage("tsl.00", null)), e);
+ }
+
+ }
+
+ public static void update() throws TSLEngineDiedException, TSLSearchException, ConfigurationException, MOAApplicationException, CertStoreException, TrustStoreException, CertificateException, IOException {
+ MessageProvider msg = MessageProvider.getInstance();
+
+ //TrustProfile tp = null;
+ TrustStoreProfile tsp = null;
+ StoreUpdater storeUpdater = null;
+ TransactionId tid = null;
+
+ //get TSl configuration
+ ConfigurationProvider config = ConfigurationProvider.getInstance();
+ if (configData_ == null)
+ configData_ = new IaikConfigurator().configure(config);
+
+ TSLConfiguration tslconfig = config.getTSLConfiguration();
+ if (tslconfig != null) {
+
+ tslconnector_.updateTSLs(new Date(), new String[]{"accredited","undersupervision"});
+
+ Logger.info(new LogMsg(msg.getMessage("config.42", null)));
+
+ // get certstore parameters
+ CertStoreParameters[] certStoreParameters = configData_.getPKIConfiguration().getCertStoreConfiguration().getParameters();
+
+ // iterate over all truststores
+ Map mapTrustProfiles = config.getTrustProfiles();
+ Iterator it = mapTrustProfiles.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry pairs = (Map.Entry)it.next();
+ TrustProfile tp = (TrustProfile) pairs.getValue();
+ if (tp.isTSLEnabled()) {
+ tsp = new TrustStoreProfileImpl(config, tp.getId());
+ TrustStoreProfile[] trustStoreProfiles = new TrustStoreProfile[1];
+ trustStoreProfiles[0] = tsp;
+
+ Logger.debug(new LogMsg(msg.getMessage("config.43", new String[]{tp.getId()})));
+
+ tid = new TransactionId("TSLConfigurator-" + tp.getId());
+ ArrayList tsl_certs = null;
+ if (StringUtils.isEmpty(tp.getCountries())) {
+ Logger.debug(new LogMsg(msg.getMessage("config.44", null)));
+
+ // get certificates from TSL from all countries
+ tsl_certs = tslconnector_.getQualifiedCACertificates(new Date(), new String[]{"accredited","undersupervision"});
+ }
+ else {
+ Logger.debug(new LogMsg(msg.getMessage("config.44", null)));
+ // get selected countries as array
+ String countries = tp.getCountries();
+ String[] array = countries.split(",");
+ for (int i = 0; i < array.length; i++)
+ array[i] = array[i].trim();
+
+ // get certificates from TSL from given countries
+ tsl_certs = tslconnector_.getQualifiedCACertificates(new Date(), array, new String[]{"accredited","undersupervision"});
+ }
+
+ // create store updater for each TSL enabled truststore
+ Logger.debug(new LogMsg(msg.getMessage("config.45", null)));
+ storeUpdater = new StoreUpdater(certStoreParameters, trustStoreProfiles, tid);
+
+ // delete files in trustprofile
+
+ File ftp = new File(tp.getUri());
+ File[] files = ftp.listFiles();
+ X509Certificate[] removeCertificates = new X509Certificate[files.length];
+ int i = 0;
+ for (File file : files) {
+ FileInputStream fis = new FileInputStream(file);
+ removeCertificates[i] = new X509Certificate(fis);
+ i++;
+ fis.close();
+ //file.delete();
+ }
+
+ // remove all certificates
+ storeUpdater.removeCertificatesFromTrustStores(removeCertificates, tid);
+ storeUpdater.removeCertificatesFromCertStores(removeCertificates, tid);
+
+
+ // copy files from original trustAnchorsLocURI into tslworking trust profile
+ File src = new File(tp.getUriOrig());
+ files = src.listFiles();
+ X509Certificate[] addCertificates = new X509Certificate[files.length];
+ i = 0;
+ for (File file : files) {
+ FileInputStream fis = new FileInputStream(file);
+ addCertificates[i] = new X509Certificate(fis);
+ //FileUtils.copyFile(file, new File(tp.getUri(), file.getName()));
+ i++;
+ fis.close();
+ }
+
+ // convert ArrayList<File> to X509Certificate[]
+ if (tsl_certs == null) {
+ Logger.warn("No certificates from TSL imported.");
+ //throw new TSLSearchException("No certificates from TSL imported.");
+ }
+ else {
+
+ X509Certificate[] addCertificatesTSL = new X509Certificate[tsl_certs.size()];
+ Iterator itcert = tsl_certs.iterator();
+ i = 0;
+ File f = null;
+ while(itcert.hasNext()) {
+ f = (File)itcert.next();
+ FileInputStream fis = new FileInputStream(f);
+ X509Certificate cert = new X509Certificate(fis);
+ addCertificatesTSL[i] = cert;
+
+ i++;
+ fis.close();
+ }
+
+ Logger.debug(new LogMsg("Add " + addCertificatesTSL.length + " certificates."));
+ storeUpdater.addCertificatesToTrustStores(addCertificatesTSL, tid);
+ storeUpdater.addCertificatesToCertStores(addCertificatesTSL, tid);
+
+ Logger.debug(new LogMsg("Add " + addCertificates.length + " certificates."));
+ storeUpdater.addCertificatesToTrustStores(addCertificates, tid);
+ storeUpdater.addCertificatesToCertStores(addCertificates, tid);
+ }
+ }
+ }
+ }
+
+
+
+ }
+
+}
diff --git a/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/utils/CertificateReader.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/utils/CertificateReader.java
new file mode 100644
index 0000000..763382a
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/utils/CertificateReader.java
@@ -0,0 +1,155 @@
+package at.gv.egovernment.moa.spss.tsl.utils;
+import iaik.pkcs.PKCS7CertList;
+import iaik.pkcs.PKCSParsingException;
+import iaik.security.provider.IAIK;
+import iaik.utils.Util;
+import iaik.x509.X509Certificate;
+import iaik.xml.crypto.EccProviderAdapter;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.security.Security;
+import java.security.cert.CertificateException;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+// Copyright (C) 2011 IAIK
+// http://jce.iaik.at
+//
+// Copyright (C) 2011 Stiftung Secure Information and
+// Communication Technologies SIC
+// http://www.sic.st
+//
+// All rights reserved.
+//
+// This source is provided for inspection purposes and recompilation only,
+// unless specified differently in a contract with IAIK. This source has to
+// be kept in strict confidence and must not be disclosed to any third party
+// under any circumstances. Redistribution in source and binary forms, with
+// or without modification, are <not> permitted in any case!
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+// SUCH DAMAGE.
+//
+//
+
+public class CertificateReader {
+
+ /**
+ * Filter for reading certificate files from a directory.
+ * The filter accepts a file if its name ends with
+ * &quot;.cer&quot;, &quot;.der&quot;, &quot;.crt&quot;
+ * or &quot;.pem&quot;.
+ *
+ * @author Harald Bratko
+ * @author Konrad Lanz
+ */
+ static class CertificateFileFilter implements FileFilter {
+
+ /**
+ * Accepts a file if it is not a directory and its name ends with
+ * &quot;.cer&quot;, &quot;.der&quot;, &quot;.crt&quot; or &quot;.pem&quot;.
+ *
+ * @see java.io.FileFilter#accept(java.io.File)
+ */
+ public boolean accept(File file) {
+ String name = file.getName();
+ if (name.endsWith(".der") ||
+ name.endsWith(".cer") ||
+ name.endsWith(".crt") ||
+ name.endsWith(".pem"))
+ {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+
+
+
+ /**
+ * Reads the certificates from the given directory and
+ * returns the certificates as sorted list (end user certificate first).
+ * @param directory
+ * @return
+ * @throws IOException
+ * @throws FileNotFoundException
+ * @throws CertificateException
+ * @throws Exception
+ */
+ public static X509Certificate[] readCertificatesIntoArray(String directory) throws CertificateException, FileNotFoundException, IOException{
+ File file = new File(directory);
+ File[] certificateFiles = file.listFiles(new CertificateFileFilter());
+ int l = certificateFiles.length;
+ X509Certificate[] certs = new X509Certificate[l];
+ for (int i=0; i<certificateFiles.length; i++) {
+ X509Certificate certificate = new X509Certificate(new FileInputStream(certificateFiles[i]));
+ certs[i] = certificate;
+ }
+ return Util.arrangeCertificateChain(certs, false);
+ }
+
+ /**
+ * Reads the certificates from the given directory and
+ * returns the certificates as sorted list (end user certificate first).
+ * @param directory
+ * @return
+ * @throws IOException
+ * @throws FileNotFoundException
+ * @throws CertificateException
+ * @throws Exception
+ */
+ public static List<X509Certificate> readCertificates(String directory) throws CertificateException, FileNotFoundException, IOException{
+
+ return Arrays.asList(readCertificatesIntoArray(directory));
+ }
+
+ public static void main(String[] args) {
+ try {
+
+ IAIK.addAsJDK14Provider();
+ //IAIK.addAsProvider();
+ //Security.addProvider(new IAIK());
+
+ // install ECC provider
+ Security.addProvider(EccProviderAdapter.getEccProvider());
+
+ String dir = "spec/examples/EU/AT/certs/on-tsl/chain/";
+ List l = readCertificates(dir);
+ Iterator<X509Certificate> it = l.iterator();
+ while (it.hasNext()) {
+ System.out.println(((X509Certificate)it.next()).getSubjectDN().getName());
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+
+ }
+
+ public static X509Certificate[] p7read(File path) throws PKCSParsingException, FileNotFoundException, IOException {
+ PKCS7CertList p7certList = new PKCS7CertList(
+ new BufferedInputStream(
+ new FileInputStream(
+ path
+ )
+ )
+ );
+ return p7certList.getCertificateList();
+ }
+ } \ No newline at end of file
diff --git a/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/utils/Mitigation.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/utils/Mitigation.java
new file mode 100644
index 0000000..a1635b8
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/utils/Mitigation.java
@@ -0,0 +1,15 @@
+package at.gv.egovernment.moa.spss.tsl.utils;
+
+public class Mitigation extends iaik.xml.crypto.tsl.ex.SeverityAspect.Mitigation {
+
+ String report_;
+
+ public Mitigation(String report) {
+ report_ = report;
+ }
+
+ @Override
+ public String getReport() {
+ return report_;
+ }
+} \ No newline at end of file
diff --git a/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/utils/TSLEUImportFromFileContext.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/utils/TSLEUImportFromFileContext.java
new file mode 100644
index 0000000..453ee2b
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/utils/TSLEUImportFromFileContext.java
@@ -0,0 +1,140 @@
+package at.gv.egovernment.moa.spss.tsl.utils;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.sqlite.SQLiteErrorCode;
+
+import iaik.util.logging.Log;
+import iaik.util.logging._l;
+import iaik.util.logging.Log.MultiThreadLoggingGroup;
+import iaik.xml.crypto.tsl.DbTables;
+import iaik.xml.crypto.tsl.TSLImportFromFileContext;
+import iaik.xml.crypto.tsl.TSLOpenURIException;
+import iaik.xml.crypto.tsl.constants.Countries;
+import iaik.xml.crypto.tsl.ex.TSLExceptionB;
+import iaik.xml.crypto.tsl.ex.ThrowableAndLocatorAndMitigation;
+import iaik.xml.crypto.tsl.ex.SeverityAspect.Severity;
+import iaik.xml.crypto.tsl.fetch.TopLevelTslFetchContext;
+
+public class TSLEUImportFromFileContext extends TopLevelTslFetchContext {
+
+ public TSLEUImportFromFileContext(
+ Countries euTerritory,
+ URL euTslURL,
+ String workingdirectory,
+ boolean sqlMultithreaded,
+ boolean throwExceptions,
+ boolean logExceptions,
+ boolean throwWarnings,
+ boolean logWarnings,
+ boolean nullRedundancies) {
+
+ super(
+ euTerritory,
+ euTslURL,
+ workingdirectory,
+ sqlMultithreaded,
+ throwExceptions,
+ logExceptions,
+ throwWarnings,
+ logWarnings,
+ nullRedundancies);
+
+ }
+
+ public List<ThrowableAndLocatorAndMitigation> getErrorsAndWarnings() {
+ List<ThrowableAndLocatorAndMitigation> errorsAndWarnings = new ArrayList<ThrowableAndLocatorAndMitigation>();
+ errorsAndWarnings.addAll(this.fatals_);
+ errorsAndWarnings.addAll(this.faildTransactions_);
+ errorsAndWarnings.addAll(this.warnings_);
+
+ return errorsAndWarnings;
+ }
+
+ @Override
+ public boolean normalizeXML() {
+ return true;
+ }
+
+ @Override
+ public Object throwException(Throwable e, Method enclosingMethod,
+ Object thisObject, Object[] parameters) {
+
+ if (enclosingMethod != null){
+ if (
+ e instanceof TSLOpenURIException &&
+ enclosingMethod.getName().equals("processUrl") &&
+ TSLImportFromFileContext.class.isAssignableFrom(enclosingMethod.getDeclaringClass()) &&
+ parameters[1] instanceof File &&
+ e.getCause() instanceof IOException &&
+ parameters[0] instanceof URL
+ ){
+
+ _l.err("Ignoring download error using old: " + parameters[0],null);
+ wrapException(e);
+ return parameters[1];
+ }
+ }
+
+ //we allow each and every funny stuff from the EU as long as it's not insecure
+ if (e instanceof TSLExceptionB){
+ TSLExceptionB ve = (TSLExceptionB) e;
+ Severity s = ve.getSeverity();
+ if ( s != null && s.ordinal() < Severity.insecure.ordinal()){
+ _l.err("Ignored Exception: ",ve);
+// if(logExceptions_){
+ warnings_.add(
+ new ThrowableAndLocatorAndMitigation(
+ ve, null, ve.getLocator(), ve.getMitigation()
+ )
+ );
+// }
+ return null;
+ }
+ }
+
+
+ return super.throwException(e, enclosingMethod, thisObject, parameters);
+ }
+
+ @Override
+ public Boolean doesViolateRawHash(SQLException e, byte[] rawHash) {
+
+ String msg = e.getMessage();
+ return (
+ msg.startsWith("["+SQLiteErrorCode.SQLITE_CONSTRAINT.name()+"]") &&
+ msg.contains("column " + DbTables.TSLDownload.C.rawHash + " is not unique")
+ );
+ }
+
+ public MultiThreadLoggingGroup getLoggingGroup() {
+ return this;
+ }
+
+ StringBuilder log = new StringBuilder();
+
+ public void flushLog() {
+ if (log != null && log.length() > 0) {
+ Thread currentThread = Thread.currentThread();
+ String ncName = getNcName(currentThread);
+
+ synchronized (log) {
+ print(
+ "<" + ncName + " state=\"" + currentThread.getState() + "\" " + " id=\"" + currentThread.getId() + "\">\n"
+ + log.toString() + "</" + ncName + ">\n");
+ log.setLength(0);
+ }
+ }
+ }
+
+ public void print(Object msg) {
+ Log.print(msg);
+ }
+
+}
diff --git a/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/utils/TSLEvaluationContext.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/utils/TSLEvaluationContext.java
new file mode 100644
index 0000000..a656f11
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/utils/TSLEvaluationContext.java
@@ -0,0 +1,134 @@
+package at.gv.egovernment.moa.spss.tsl.utils;
+
+import iaik.util.logging.Log.MultiThreadLoggingGroup;
+import iaik.util.logging.Log;
+import iaik.util.logging._l;
+import iaik.xml.crypto.tsl.BaseClass;
+import iaik.xml.crypto.tsl.SIEExtensionChecker;
+import iaik.xml.crypto.tsl.constants.Countries;
+import iaik.xml.crypto.tsl.ex.TSLSIEExtensionException;
+import iaik.xml.crypto.tsl.ex.SeverityAspect.Mitigation;
+import iaik.xml.crypto.tsl.sie.gen.CriteriaListType;
+import iaik.xml.crypto.tsl.sie.gen.KeyUsageBitType;
+import iaik.xml.crypto.tsl.sie.gen.KeyUsageType;
+import iaik.xml.crypto.tsl.sie.gen.ObjectFactory;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+public final class TSLEvaluationContext extends iaik.xml.crypto.tsl.TSLEvaluationContext {
+
+ public TSLEvaluationContext(
+ String workingdirectory,
+ boolean sqlMultithreaded,
+ boolean throwExceptions,
+ boolean logExceptions,
+ boolean throwWarnings,
+ boolean logWarnings) {
+ super(workingdirectory,
+ sqlMultithreaded,
+ throwExceptions,
+ logExceptions,
+ throwWarnings,
+ logWarnings);
+ }
+
+ @Override
+ public Object throwException(Throwable e, Method enclosingMethod,
+ Object thisObject, Object[] parameters) {
+
+ if (e instanceof TSLSIEExtensionException
+ && e.getMessage() == TSLSIEExtensionException.NO_KEYUSEAGE_NOR_POLICYSET) {
+
+ CriteriaListType criteriaList = (CriteriaListType) parameters[1];
+
+ _l.warn(criteriaList.getDescription());
+
+ String description = criteriaList.getDescription();
+ if (description
+ .trim()
+ .equals(
+ "This service issues qualified certificates for e-signing and "
+ + "e-authentication within the same process. The Relaying Party shall "
+ + "make distinction by inspection of keyUsage field contents - "
+ + "e-signature certificates have non-repudation bit set exclusively.")) {
+ criteriaList.setAssert(SIEExtensionChecker.Asssert.all.toString());
+
+ ObjectFactory of = new ObjectFactory();
+ KeyUsageType ku = of.createKeyUsageType();
+ KeyUsageBitType kb = of.createKeyUsageBitType();
+ kb.setName(SIEExtensionChecker.KeyUseageBit.nonRepudiation
+ .toString());
+ kb.setValue(true);
+ ku.getKeyUsageBit().add(kb);
+ criteriaList.getKeyUsage().add(ku);
+
+ Object mitigatedResult = null;
+ try {
+ mitigatedResult = enclosingMethod.invoke(thisObject, parameters);
+
+ } catch (IllegalAccessException e1) {
+ wrapException(e1);
+ } catch (InvocationTargetException e1) {
+ wrapException(e1);
+ }
+
+ if (mitigatedResult != null) {
+ wrapException(e, criteriaList.sourceLocation(), new Mitigation() {
+ @Override
+ public String getReport() {
+ return "Fixed invalid criteria list";
+ }
+ });
+ return mitigatedResult;
+ }
+
+ }
+ }
+ return super.throwException(e, enclosingMethod, thisObject, parameters);
+ }
+
+ @Override
+ protected long howLongWaitForThreads() {
+ return 10000;
+ }
+
+ @Override
+ protected BaseClass getCurrentBaseClass() {
+ //TODO check whether we can avoid by redesign to focus this only on import
+ return null;
+ }
+
+ @Override
+ public boolean normalizeXML() {
+ return true;
+ }
+
+ public Countries getExpectedTerritory() {
+ return null;
+ }
+
+ public MultiThreadLoggingGroup getLoggingGroup() {
+ return this;
+ }
+
+ StringBuffer log = new StringBuffer();
+
+ public void flushLog() {
+ if (log != null && log.length() > 0) {
+ synchronized (System.out) {
+ Thread currentThread = Thread.currentThread();
+ print("# # # " + getHint() + " Thread: "
+ + currentThread.getName() + "(" + currentThread.getId()
+ + ") collected logs - BEGIN # # #\n" + log.toString() + "# # # "
+ + getHint() + " Thread: " + currentThread.getName()
+ + "(" + currentThread.getId() + ") collected logs - END # # #\n");
+ }
+ log = null;
+ }
+ }
+
+ public void print(Object msg) {
+ Log.print(msg);
+ }
+} \ No newline at end of file
diff --git a/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/utils/TSLImportFromFileContext.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/utils/TSLImportFromFileContext.java
new file mode 100644
index 0000000..5d69f69
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/utils/TSLImportFromFileContext.java
@@ -0,0 +1,850 @@
+package at.gv.egovernment.moa.spss.tsl.utils;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.InvalidKeyException;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+
+import javax.xml.bind.Unmarshaller;
+import javax.xml.crypto.AlgorithmMethod;
+import javax.xml.crypto.KeySelectorException;
+
+import org.apache.log4j.Logger;
+import org.sqlite.SQLiteErrorCode;
+import org.w3c.dom.DOMError;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXParseException;
+
+import at.gv.egovernment.moa.spss.tsl.exception.MitigatedTSLSecurityException;
+import iaik.util.logging.Log.MultiThreadLoggingGroup;
+import iaik.util.logging._l;
+import iaik.utils.RFC2253NameParserException;
+import iaik.utils.Util;
+import iaik.util._15;
+import iaik.xml.crypto.dsig.keyinfo.X509DataImpl;
+import iaik.xml.crypto.tsl.DbTables;
+import iaik.xml.crypto.tsl.TSLConstants;
+import iaik.xml.crypto.tsl.TSLContext;
+import iaik.xml.crypto.tsl.TSLEngine;
+import iaik.xml.crypto.tsl.TSLImportContext;
+import iaik.xml.crypto.tsl.TSLOpenURIException;
+import iaik.xml.crypto.tsl.TSLThreadContext;
+import iaik.xml.crypto.tsl.ValidationFixupFilter;
+import iaik.xml.crypto.tsl.ValidationFixupFilter.AttributeValueFixup;
+import iaik.xml.crypto.tsl.ValidationFixupFilter.DeleteAttrFixup;
+import iaik.xml.crypto.tsl.ValidationFixupFilter.ElementStringValueFixup;
+import iaik.xml.crypto.tsl.ValidationFixupFilter.FixedSaxLevelValidationExcption;
+import iaik.xml.crypto.tsl.ValidationFixupFilter.Fixup;
+import iaik.xml.crypto.tsl.ValidationFixupFilter.LocalNameFixup;
+import iaik.xml.crypto.tsl.constants.Countries;
+import iaik.xml.crypto.tsl.ex.LocatorAspect;
+import iaik.xml.crypto.tsl.ex.TSLEngineFatalException;
+import iaik.xml.crypto.tsl.ex.TSLRuntimeWarning;
+import iaik.xml.crypto.tsl.ex.TSLSecurityException;
+import iaik.xml.crypto.tsl.ex.TSLSecurityException.Type;
+import iaik.xml.crypto.tsl.ex.TSLVerificationException;
+import iaik.xml.crypto.tsl.gen.DigitalIdentityType;
+import iaik.xml.crypto.tsl.verify.TSLDOMErrorHandler;
+import iaik.xml.crypto.tsl.verify.TSLValidationException;
+import iaik.xml.crypto.tsl.verify.TslKeySelector;
+import iaik.xml.crypto.utils.KeySelectorImpl.X509KeySelectorResultImpl;
+
+/**
+ *
+ */
+
+public class TSLImportFromFileContext extends iaik.xml.crypto.tsl.TSLImportFromFileContext {
+
+ static Logger l = Logger.getLogger(TSLImportFromFileContext.class);
+
+ public static final class ExceptionalMitigation extends Mitigation {
+ public ExceptionalMitigation(String report) {
+ super(report);
+ }
+ }
+
+ public static final class FixedValidationMitigation extends Mitigation {
+ public FixedValidationMitigation(String report) {
+ super(report);
+ }
+ }
+
+ private final String baseuri_;
+ private Map<Countries, ListIterator<X509Certificate>>
+ trustAnchorsWrongOnEuTsl_;
+
+ public TSLImportFromFileContext(
+ Countries expectedTerritory,
+ URL url,
+ Number otherTslPointerId,
+ String workingdirectory,
+ boolean sqlMultithreaded,
+ boolean throwExceptions,
+ boolean logExceptions,
+ boolean throwWarnings,
+ boolean logWarnings,
+ boolean nullRedundancies,
+ String baseuri,
+ Map <Countries, ListIterator<X509Certificate>> trustAnchorsWrongOnEuTsl,
+ TSLThreadContext parentContext) {
+ super(
+ expectedTerritory,
+ url,
+ otherTslPointerId,
+ workingdirectory,
+ sqlMultithreaded,
+ throwExceptions,
+ logExceptions,
+ throwWarnings,
+ logWarnings,
+ nullRedundancies,
+ parentContext);
+ baseuri_ = baseuri;
+ trustAnchorsWrongOnEuTsl_ = trustAnchorsWrongOnEuTsl;
+ }
+ /* (non-Javadoc)
+ * @see iaik.xml.crypto.tsl.TSLImportFromFileContext#getbaseURI()
+ */
+ @Override
+ public String getbaseURI() {
+ return this.baseuri_;
+ }
+
+
+
+
+ //@Override
+ protected RuntimeException wrapException(Throwable t, Locator l, Mitigation m) {
+ return super.wrapException(t, l, m);
+ }
+
+ @Override
+ public
+ synchronized void throwException(Throwable e) {
+
+ if (e instanceof TSLValidationException) {
+ // we do not throw dom validation errors for testing
+ // and just collect them
+ wrapException(e);
+ } else if (e instanceof TSLVerificationException) {
+
+ boolean corrected = false;
+ // we do not throw verification errors for testing
+ // and just collect them
+
+// // NEVER DO THIS! unless you want to import TSLs without signatures.
+// if (Boolean.valueOf(_.getSysProperty(TSLSecurityException.Type.NO_TSL_SIGNATURE
+// .getClass().getName(), "true"))
+// && ((TSLVerificationException) e).getType() == TSLSecurityException.Type.NO_TSL_SIGNATURE) {
+// ((TSLVerificationException) e).setMitigation(Mitigation.IGNORED);
+// }
+//
+// if (Boolean.valueOf(_.getSysProperty(TSLSecurityException.Type.NON_CONFORMANT_REFERENCE_IN_TSL_SIGNATURE
+// .getClass().getName(), "true"))
+// && ((TSLVerificationException) e).getType() == TSLSecurityException.Type.NON_CONFORMANT_REFERENCE_IN_TSL_SIGNATURE) {
+// ((TSLVerificationException) e).setMitigation(Mitigation.IGNORED);
+// }
+
+// if (Boolean.valueOf(_.getSysProperty(TSLSecurityException.Type.NON_CONFORMANT_TRANSFORMS_IN_TSL_SIGNATURE
+// .getClass().getName(), "true"))
+// && ((TSLVerificationException) e).getType() == TSLSecurityException.Type.NON_CONFORMANT_TRANSFORMS_IN_TSL_SIGNATURE) {
+// ((TSLVerificationException) e).setMitigation(Mitigation.IGNORED);
+//
+// corrected = true;
+// }
+//
+//
+// if (Boolean.valueOf(_.getSysProperty(TSLSecurityException.Type.NON_CONFORMANT_TRANSFORM_IN_TSL_SIGNATURE
+// .getClass().getName(), "true"))
+// && ((TSLVerificationException) e).getType() == TSLSecurityException.Type.NON_CONFORMANT_TRANSFORM_IN_TSL_SIGNATURE) {
+// ((TSLVerificationException) e).setMitigation(Mitigation.IGNORED);
+//
+// corrected = true;
+// }
+//
+// if (Boolean.valueOf(_.getSysProperty(TSLSecurityException.Type.NON_CONFORMANT_C14N_IN_TSL_SIGNATURE
+// .getClass().getName(), "true"))
+// && ((TSLVerificationException) e).getType() == TSLSecurityException.Type.NON_CONFORMANT_C14N_IN_TSL_SIGNATURE) {
+// ((TSLVerificationException) e).setMitigation(Mitigation.IGNORED);
+//
+// corrected = true;
+// }
+//
+// if (corrected)
+// wrapException(e);
+// else
+// super.throwException(e);
+
+ super.throwException(e);
+
+ } else if (e instanceof FileNotFoundException) {
+ // we do not stop and continue processing
+ wrapException(e);
+ } else if (e instanceof IllegalArgumentException) {
+ // we do not stop and continue processing
+ wrapException(e);
+ } else {
+ // all other errors are treated as per default
+ super.throwException(e);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see iaik.xml.crypto.tsl.TSLContext#throwException(java.lang.Exception, java.lang.reflect.Method, java.lang.Object, java.lang.Object[])
+ */
+ @Override
+ public Object throwException(
+ Throwable e, Method enclosingMethod, Object thisObject, final Object[] parameters) {
+
+ if (enclosingMethod != null){
+
+ if(
+ e instanceof FixedSaxLevelValidationExcption &&
+ enclosingMethod.getDeclaringClass().equals(ValidationFixupFilter.class)){
+ wrapException(e,
+ ((LocatorAspect) e).getLocator(),
+ new FixedValidationMitigation("Performed SAX Level Fixup."));
+ return null;
+ }
+
+ if(e instanceof CertificateException &&
+ enclosingMethod.getDeclaringClass().equals(TSLImportContext.class) &&
+ enclosingMethod.getName().equals("parseCertificate")) {
+
+ wrapException(e);
+ // ((DigitalIdentityType)parameters[1]).sourceLocation();
+
+ return null;
+ }
+
+ if (e instanceof TSLValidationException&&
+ enclosingMethod.getDeclaringClass().equals(TSLDOMErrorHandler.class) &&
+ enclosingMethod.getName().equals("handleError")) {
+
+ if (parameters[0] instanceof DOMError) {
+ DOMError domError = (DOMError) parameters[0];
+
+ _l.warn(""+domError.getRelatedData());
+
+ // domError.getRelatedData().getClass().getField("")
+
+ wrapException(e);
+ return Boolean.TRUE;
+ }
+ }
+
+ if (e instanceof RFC2253NameParserException&&
+ enclosingMethod.getDeclaringClass().equals(TSLImportContext.class) &&
+ enclosingMethod.getName().equals("getNormalizedDN") &&
+ parameters[0] instanceof DigitalIdentityType ) {
+
+ DigitalIdentityType digitalId = (DigitalIdentityType) parameters[0];
+
+ String subDN = digitalId.getX509SubjectName();
+
+ // String openSslRdnRegExp = "/([^=]+)=?(([^/]+)|\"([^\"]+)\"";
+
+ String openSslRdnRegExp = "/([^=]+)=(\"([^\"]*)\"|([^/\"][^/]*)|(.{0}))";
+ // 1 2 3 4 5
+ // 1 matches Attribute
+ // 2 matches values
+ // 2 greedy matches properly quoted values
+ // 3 greedy matches values without quotes
+ // 4 matches the empty value
+ if (subDN.matches("^("+openSslRdnRegExp+")+$")){
+ //trigger openSSL format error handling
+
+ Object mitigatedResult = null;
+
+ String[] rdns = subDN.substring(1, subDN.length()).split("/");
+
+ rdns = (String[]) _15.reverseInPlace(rdns);
+
+ subDN = "/"+_15.implode("/", rdns);
+
+ //for now we only support properly quoted values or such without quotes
+
+ subDN = subDN.replaceAll(openSslRdnRegExp, "$1=\"$2$3\",");
+ subDN = subDN.substring(0, subDN.length()-1);
+
+ digitalId.setX509SubjectName(subDN);
+ try {
+ mitigatedResult = enclosingMethod.invoke(thisObject, new Object[]{digitalId});
+
+ } catch (IllegalAccessException e1) {
+ wrapException(e1);
+ } catch (InvocationTargetException e1) {
+ wrapException(e1);
+ }
+
+ if (mitigatedResult != null){
+ wrapException(e, digitalId.sourceLocation(), new iaik.xml.crypto.tsl.ex.SeverityAspect.Mitigation() {
+ @Override
+ public String getReport() {
+ return "Converted OpenSSL SubjectDN";
+ }
+ });
+ return mitigatedResult;
+
+ }
+ }
+
+ wrapException(
+ new TSLRuntimeWarning("Could not normalize :" + (digitalId).getX509SubjectName(), e),
+ digitalId.sourceLocation());
+
+ //if we cannot Normalize the DN we simply don't
+ return (digitalId).getX509SubjectName();
+ }
+
+ //TODO check if this is really needed for ESP TSL
+ if (e instanceof RFC2253NameParserException &&
+ enclosingMethod.getDeclaringClass().equals(TSLImportContext.class) &&
+ enclosingMethod.getName().equals("getNormalizedSubjectDN") &&
+ parameters[0] instanceof X509Certificate ) {
+
+ X509Certificate cert = (X509Certificate) parameters[0];
+
+
+ wrapException(e, null);
+ //if we cannot Normalize the DN we simply don't
+ return cert.getSubjectDN().getName();
+ }
+
+ if (
+ (expectedTerritory_ == Countries.MT || expectedTerritory_ == Countries.LT)&&
+ e instanceof TSLOpenURIException &&
+ enclosingMethod.getDeclaringClass().equals(TSLImportFromFileContext.class) &&
+ enclosingMethod.getName().equals("processUrl") &&
+ parameters[1] instanceof File){
+
+ URL url = null;
+ if (
+ e.getCause() instanceof FileNotFoundException &&
+ parameters[0] instanceof URL &&
+ (url =((URL)parameters[0])).getProtocol().equalsIgnoreCase("http")
+ ){
+ try {
+ //Malta just changed their URL ...
+ if ("http://www.mca.org.mt/tsl/MT_TSL.xml".equalsIgnoreCase(url.toString())){
+ url = new URL("http://www.mca.org.mt/sites/default/files/pageattachments/MT_TSL.xml");
+ } else {
+ url = new URL("https", url.getHost(), url.getFile());
+ }
+ } catch (MalformedURLException e1) {
+ wrapException(e1);
+ }
+
+ Object mitigatedResult = null;
+ try {
+
+ mitigatedResult = enclosingMethod.invoke(thisObject, new Object[]{url,parameters[1]});
+ } catch (IllegalAccessException e1) {
+ wrapException(e1);
+ } catch (InvocationTargetException e1) {
+ wrapException(e1);
+ }
+
+ if (mitigatedResult != null){
+ wrapException(e, null, new iaik.xml.crypto.tsl.ex.SeverityAspect.Mitigation() {
+ @Override
+ public String getReport() {
+ return "Trying https:// ...";
+ }
+ });
+ return mitigatedResult;
+ }
+ }
+
+ _l.err("Ignoring download error using old: " + parameters[0], null);
+ wrapException(e);
+ return parameters[1];
+ }
+
+// if (
+// expectedTerritory_ == Countries.PL &&(
+// (e.getCause() instanceof java.io.EOFException ||
+// e.getCause() instanceof iaik.security.ssl.SSLException) &&
+// parameters[0] instanceof URL &&
+// ((URL)parameters[0]).getProtocol().equalsIgnoreCase("https")
+// )){
+// File f = null;
+// System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true");
+// TLS.register("TLSv1");
+// try {
+// f = (File) enclosingMethod.invoke(thisObject, parameters);
+// } catch (IllegalAccessException e1) {
+// wrapException(e1);
+// } catch (InvocationTargetException e1) {
+// wrapException(e1);
+// }
+//
+// // System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", null);
+// TLS.register();
+//
+// if (f != null){
+// wrapException(e, null, new Mitigation() {
+// @Override
+// public String getReport() {
+// return "Trying TLSv1 and sun.security.ssl.allowUnsafeRenegotiation=true";
+// }
+// });
+// return f;
+// }
+// }
+
+ if (
+ e instanceof TSLSecurityException &&
+ enclosingMethod.getDeclaringClass().equals(TSLContext.class) &&
+ enclosingMethod.getName().equals("securityCheck") &&
+ parameters[0] == TSLSecurityException.Type.UNTRUSTED_TSL_SIGNER &&
+ trustAnchorsWrongOnEuTsl_.containsKey(expectedTerritory_) &&
+ parameters[1] instanceof X509Certificate &&
+ parameters[2] instanceof ListIterator<?>
+ )
+ {
+ final ListIterator<X509Certificate> trustAnchorsWrongOnEuTsl =
+ trustAnchorsWrongOnEuTsl_.get(expectedTerritory_);
+
+ if (trustAnchorsWrongOnEuTsl != parameters[2]){ //prevents recursion
+ try {
+ enclosingMethod.invoke(thisObject,
+ new Object[]{parameters[0],parameters[1], trustAnchorsWrongOnEuTsl});
+ } catch (IllegalAccessException e1) {
+ wrapException(e1);
+ } catch (InvocationTargetException e1) {
+ wrapException(e1);
+ }
+ wrapException(e, getLocator(),
+ new iaik.xml.crypto.tsl.ex.SeverityAspect.Mitigation(){
+ @Override
+ public String getReport() {
+ return "make an exception for " + expectedTerritory_ + " who have the wrong certificate in " +
+ "the EU TSL and allow the certificate " +
+ parameters[1];
+ }
+ });
+ return null;
+ }
+ X509Certificate crt = (X509Certificate)parameters[1];
+
+ File f = new File("./wrong/"+expectedTerritory_+"/",
+ iaik.util._15.toHexString(getFingerPrint(crt,
+ new byte[TSLConstants.CertHash.LENGTH]))+".der");
+ File parent = f.getParentFile();
+ if(!parent.exists() && !parent.mkdirs()){
+ throw new IllegalStateException("Couldn't create dir: " + parent);
+ }
+
+ if (!f.exists()){
+ try {
+ OutputStream os = new BufferedOutputStream(
+ new FileOutputStream(f)
+ );
+ os.write(crt.getEncoded());
+ os.close();
+ } catch (Exception e1) {
+ e1.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ //continue ...
+ }
+
+ if (
+ ( expectedTerritory_ == Countries.SK ||
+ expectedTerritory_ == Countries.SE ||
+ expectedTerritory_ == Countries.NO ||
+ expectedTerritory_ == Countries.PL) &&
+ e instanceof KeySelectorException &&
+ enclosingMethod.getDeclaringClass().equals(TslKeySelector.class) &&
+ enclosingMethod.getName().equals("select") &&
+ parameters[0] instanceof X509DataImpl){
+
+ X509DataImpl x509Data = (X509DataImpl) parameters[0];
+ AlgorithmMethod method = (AlgorithmMethod) parameters[2];
+
+ List certificates = new ArrayList();
+
+ Iterator x509content = x509Data.getContent().iterator();
+ while (x509content.hasNext()) {
+ Object element = x509content.next();
+ if (element instanceof X509Certificate) {
+ X509Certificate rawCert = (X509Certificate)element;
+ certificates.add(rawCert);
+ }
+ }
+
+ if (!certificates.isEmpty()) {
+ X509Certificate[] rawCertificates = new X509Certificate[certificates.size()];
+ certificates.toArray(rawCertificates);
+ certificates.clear();
+ Iterator certs = null;
+ try {
+ // convert the certificates to IAIK certifcates
+ iaik.x509.X509Certificate[] iaikCertificates = Util.convertCertificateChain(rawCertificates);
+ // sort the certificate chain
+ iaik.x509.X509Certificate[] sortedChain = Util.arrangeCertificateChain(iaikCertificates, false);
+ if (sortedChain == null) {
+ // chain could not be sorted; maybe there are two different certificates
+ // containing the same public key; use the unsorted chain
+ certificates = Arrays.asList(iaikCertificates);
+ certs = certificates.iterator();
+ } else {
+ certs = (Collections.nCopies(1, sortedChain[0])).iterator();
+ certificates = Arrays.asList(sortedChain);
+ }
+ } catch (CertificateException e1) {
+ //cannot handle this throw error
+ return super.throwException(e, enclosingMethod, thisObject, parameters);
+ }
+
+ PublicKey oldPublicKey = null;
+ while (certs.hasNext()) {
+
+ iaik.x509.X509Certificate cert = (iaik.x509.X509Certificate)certs.next();
+
+ boolean hit = false;
+
+ PublicKey publicKey = cert.getPublicKey();
+
+ // failReason_ = "";
+
+ // Does the certificate provide a key for the requested algorithm?
+ try {
+ KeyFactory kfac = KeyFactory.getInstance(method.getAlgorithm());
+ kfac.translateKey(publicKey);
+ hit = true;
+ if (oldPublicKey != null) {
+ if (!publicKey.equals(oldPublicKey)) {
+ //cannot handle this throw error
+ return super.throwException(e, enclosingMethod, thisObject, parameters);
+ }
+ }
+ oldPublicKey = publicKey;
+ } catch (NoSuchAlgorithmException e1) {
+ //cannot handle this throw error
+ return super.throwException(e, enclosingMethod, thisObject, parameters);
+ } catch (InvalidKeyException e1) {
+ //cannot handle this throw error
+ return super.throwException(e, enclosingMethod, thisObject, parameters);
+ }
+ if (hit) {
+ //make an exception for SK, SE who violate XMLDSig ds:KeyInfo/ds:X509Data
+ wrapException(e, getLocator(),
+ new ExceptionalMitigation("make an exception for " + expectedTerritory_ + " who violate XMLDSig ds:KeyInfo"));
+ return new X509KeySelectorResultImpl(publicKey, certificates, null);
+ }
+ }
+ }
+ }
+
+ if ( expectedTerritory_ == Countries.DK &&
+ e instanceof KeySelectorException &&
+ parameters[0] instanceof X509DataImpl){
+ if (e.getMessage().equals("KeyInfo X509SubjectName (CN=Adam Arndt Digst,serialNumber=CVR:34051178-RID:25902029,O=Digitaliseringsstyrelsen // CVR:34051178,C=DK) does not match SubjectDN (serialNumber=CVR:34051178-RID:25902029+CN=Adam Arndt Digst,O=Digitaliseringsstyrelsen // CVR:34051178,C=DK) of KeyInfo X509Certificate.\n"+
+ "Any X509IssuerSerial, X509SKI, and X509SubjectName elements that appear MUST refer to the certificate or certificates containing the validation key.")) {
+
+ X509DataImpl x509DataImpl = (X509DataImpl) parameters[0];
+
+ ListIterator li = x509DataImpl.getContent().listIterator();
+ li.next();
+ String sn = (String) li.next();
+
+ _l.err(sn, null);
+
+ System.exit(1);
+
+ Object mitigatedResult = null;
+ try {
+
+ mitigatedResult = enclosingMethod.invoke(thisObject, parameters);
+ } catch (IllegalAccessException e1) {
+ wrapException(e1);
+ } catch (InvocationTargetException e1) {
+ wrapException(e1);
+ }
+
+ if (mitigatedResult != null){
+ wrapException(e, null, new iaik.xml.crypto.tsl.ex.SeverityAspect.Mitigation() {
+ @Override
+ public String getReport() {
+ return "Deleted wrong X509SubjectName from XMLDSIG Signature.";
+ }
+ });
+ return mitigatedResult;
+
+ }
+ }
+ }
+
+
+ } else {
+ if (e instanceof MitigatedTSLSecurityException){
+ // we allow to mitigate Security exceptions for testing
+ // and collect them
+ wrapException(e);
+ return null;
+ } else if (e instanceof FixedSaxLevelValidationExcption) {
+ // we allow to mitigate Sax Level Fixup for testing
+ // and collect them
+ wrapException(e);
+ return null;
+ }
+ }
+
+ return super.throwException(e, enclosingMethod, thisObject, parameters);
+ }
+
+
+
+ @Override
+ public Unmarshaller createTSLUnmarshaller()
+ throws TSLEngineFatalException {
+ if (expectedTerritory_ == Countries.FI){
+ //we cannot fix FI at SAX Level and re-validate
+ return TSLEngine.createTSLUnmarshaller(false);
+ }
+ return super.createTSLUnmarshaller();
+ }
+
+ @Override
+ public String compressStatus(String status) {
+ if(expectedTerritory_ == Countries.EL){
+ //fix the whitespace in Greece TSL
+ status = status.trim();
+ }
+ if (status != null && status.startsWith("http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/")) {
+ status = status.substring("http://uri.etsi.org/TrstSvc/TrustedList/Svcstatus/".length());
+ }
+
+ return super.compressStatus(status);
+ }
+
+
+ @Override
+ public String compressServiceType(String sType) {
+ if(expectedTerritory_ == Countries.EL){
+ //fix the whitespace in Greece TSL
+ sType = sType.trim();
+ }
+ return super.compressServiceType(sType);
+ }
+
+
+ @Override
+ public iaik.xml.crypto.tsl.ValidationFixupFilter.Fixup getSaxLevelValidationFixup(SAXParseException e) {
+
+ if (expectedTerritory_ == Countries.AT){
+ if (e.getMessage().equals("cvc-type.3.1.1: Element 'tsl:URI' is a simple type, so it cannot have attributes, excepting those whose namespace name is identical to 'http://www.w3.org/2001/XMLSchema-instance' and whose [local name] is one of 'type', 'nil', 'schemaLocation' or 'noNamespaceSchemaLocation'. However, the attribute, 'xml:lang' was found.")){
+ return new DeleteAttrFixup("http://www.w3.org/XML/1998/namespace","lang", e, this);
+ }
+ }
+
+ if (expectedTerritory_ == Countries.CZ){
+ if (e.getMessage().equals("cvc-type.3.1.1: Element 'tsl:URI' is a simple type, so it cannot have attributes, excepting those whose namespace name is identical to 'http://www.w3.org/2001/XMLSchema-instance' and whose [local name] is one of 'type', 'nil', 'schemaLocation' or 'noNamespaceSchemaLocation'. However, the attribute, 'xml:lang' was found.")){
+ return new DeleteAttrFixup("http://www.w3.org/XML/1998/namespace","lang", e, this);
+ }
+ }
+
+ if (expectedTerritory_ == Countries.FR){
+ if (e.getMessage().equals("cvc-type.3.1.1: Element 'tsl:URI' is a simple type, so it cannot have attributes, excepting those whose namespace name is identical to 'http://www.w3.org/2001/XMLSchema-instance' and whose [local name] is one of 'type', 'nil', 'schemaLocation' or 'noNamespaceSchemaLocation'. However, the attribute, 'xml:lang' was found.")){
+ return new DeleteAttrFixup("http://www.w3.org/XML/1998/namespace","lang", e, this);
+ }
+ }
+
+ if (expectedTerritory_ == Countries.NO){
+ if (e.getMessage().equals("cvc-type.3.1.1: Element 'tsl:URI' is a simple type, so it cannot have attributes, excepting those whose namespace name is identical to 'http://www.w3.org/2001/XMLSchema-instance' and whose [local name] is one of 'type', 'nil', 'schemaLocation' or 'noNamespaceSchemaLocation'. However, the attribute, 'xml:lang' was found.")){
+ return new DeleteAttrFixup("http://www.w3.org/XML/1998/namespace","lang", e, this);
+ }
+ }
+
+ if (expectedTerritory_ == Countries.SK){
+ if (e.getMessage().equals("cvc-type.3.1.1: Element 'tsl:URI' is a simple type, so it cannot have attributes, excepting those whose namespace name is identical to 'http://www.w3.org/2001/XMLSchema-instance' and whose [local name] is one of 'type', 'nil', 'schemaLocation' or 'noNamespaceSchemaLocation'. However, the attribute, 'xml:lang' was found.")){
+ return new DeleteAttrFixup("http://www.w3.org/XML/1998/namespace","lang", e, this);
+ }
+ }
+
+
+ if (expectedTerritory_ == Countries.ES && getDownloadLocation().toString().contains(".es/")){
+ if (e.getMessage().equals("cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'tslx:CertSubjectDNAttributeType'.")){
+ return new LocalNameFixup("CertSubjectDNAttributeType","CertSubjectDNAttribute",e, this);
+ }
+ }
+
+ if (expectedTerritory_ == Countries.MT && getDownloadLocation().toString().contains(".mt/")){
+ if (e.getMessage().equals("cvc-complex-type.2.4.a: Invalid content was found starting with element 'tsl:TSLPolicy'. One of '{\"http://uri.etsi.org/02231/v2#\":TSLLegalNotice}' is expected.")){
+ return new LocalNameFixup("TSLPolicy","TSLLegalNotice",e, this);
+ }
+ }
+
+ if (e.getMessage().equals("cvc-complex-type.3.2.2: Attribute 'assert' is not allowed to appear in element 'ecc:otherCriteriaList'.")){
+ return new LocalNameFixup("otherCriteriaList","CriteriaList",e, this);
+ } else if (e.getMessage().startsWith("cvc-datatype-valid.1.2.1: '") && e.getMessage().endsWith("' is not a valid value for 'dateTime'.")){
+ return new ElementStringValueFixup("-(.)-","-0$1-",e, this);
+ } else if (e.getMessage().startsWith("cvc-type.3.1.3: The value '") && e.getMessage().endsWith("' of element 'tsl:ListIssueDateTime' is not valid.")){
+ // return new DateTimeFixup();
+ } else if (e.getMessage().startsWith("cvc-datatype-valid.1.2.1: '") && e.getMessage().endsWith("' is not a valid value for 'base64Binary'.")){
+ return new ElementStringValueFixup("(\\s)=([^=]+)","$1$2",e, this);
+ } else if (e.getMessage().startsWith("cvc-type.3.1.3: The value '") && e.getMessage().endsWith("' of element 'tsl:X509Certificate' is not valid.")){
+ // return new Base64BinaryFixup();
+ } else if (e.getMessage().startsWith("cvc-datatype-valid.1.2.1: '") && e.getMessage().endsWith("' is not a valid value for 'anyURI'.")){
+
+ //TODO only for sweden and find a better discriminatory than the URI
+// if (expectedTerritory_ == Countries.SE){
+// return new ElementStringValueFixup(
+// "-http://www.pts.se/upload/Ovrigt/Internet/Branschinformation/Trusted%20List%20SE%20MR.xml",
+// "http://www.pts.se/upload/Ovrigt/Internet/Branschinformation/Trusted%20List%20SE%20MR.xml");
+ return new ElementStringValueFixup("-http://www.pts.se/", "http://www.pts.se/", e, this);
+// }
+
+
+ } else if (e.getMessage().startsWith("cvc-datatype-valid.1.2.1: '") && e.getMessage().endsWith("' is not a valid value for 'NCName'.")){
+ if (expectedTerritory_ == Countries.CY || expectedTerritory_ == Countries.LV ||
+ expectedTerritory_ == Countries.HR || expectedTerritory_ == Countries.NL){
+ return new AttributeValueFixup("","Id","(.+)","x$1",e, this);
+ }
+ } else if (e.getMessage().startsWith("cvc-complex-type.2.3: Element '") && e.getMessage().endsWith("' cannot have character [children], because the type's content type is element-only.")) {
+ //cvc-complex-type.2.3: Element 'tsl:ServiceDigitalIdentity' cannot have character [children], because the type's content type is element-only.
+ if (expectedTerritory_ == Countries.FI){
+// return new ElementStringValueFixup("(\\s*)-(\\s*)","$1$2",e, this);
+ return new Fixup(e, this){
+ {
+ changed_ = true;
+ fixupPerformed();
+ }
+ @Override
+ public String fixup(String input) {
+ return null;
+ }
+
+ @Override
+ public Mitigation getMitigation() {
+ return new Mitigation("Ignored");
+ }
+
+ };
+ }
+ }
+
+ if (e.getMessage().startsWith("cvc-elt")){
+
+ } else if (e.getMessage().startsWith("cvc-type")) {
+
+ } else if (e.getMessage().startsWith("cvc-complex-type")) {
+
+ } else if (e.getMessage().startsWith("cvc-datatype-valid")) {
+
+ } else if (e.getMessage().startsWith("cvc-attribute")) {
+
+ }
+ //cvc-complex-type.2.4.a: Invalid content was found starting with element 'tsl:TSLPolicy'. One of '{"http://uri.etsi.org/02231/v2#":TSLLegalNotice}' is expected.
+
+ //cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'ecc:PolicySet'
+ //cvc-complex-type.2.4.a: Invalid content was found starting with element 'ecc:Identifier'. One of '{"http://uri.etsi.org/02231/v2/additionaltypes#":AttributeOID}' is expected.
+ //cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'tsl:ExtensionOID'.
+ //cvc-type.3.1.3: The value '-http://www.pts.se/upload/Ovrigt/Internet/Branschinformation/Trusted%20List%20SE%20MR.xml' of element 'tsl:URI' is not valid.,locator=[node=null,object=null,url=file:/C:/Gesichert/Development/projects/TSL/./hashcache/900BA6AB3702EC9518627496749AA28129C56100.tsl.xml,line=109,col=118,offset=-1]]
+
+ return super.getSaxLevelValidationFixup(e);
+ }
+
+ @Override
+ public void securityCheck(Type securityCheckType,
+ java.security.cert.X509Certificate[] certs,
+ ListIterator<java.security.cert.X509Certificate> expectedTslSignerCerts) {
+
+ //TODO check whether we always want to do that to make sure we use the endentity
+ try {
+ certs = Util.convertCertificateChain(certs);
+ } catch (CertificateException e) {
+ throwException(e);
+ }
+ certs = Util.arrangeCertificateChain((iaik.x509.X509Certificate[]) certs, false);
+ super.securityCheck(securityCheckType, certs, expectedTslSignerCerts);
+ }
+
+
+ @Override
+ public boolean doRollback() {
+ //accept each and every TSL ... even partially ... for testing
+ return false;
+// return true;
+ }
+
+ @Override
+ public Boolean doesViolateRawHash(SQLException e, byte[] rawHash) {
+
+ String msg = e.getMessage();
+
+ _l.info(msg);
+ return(
+ msg.startsWith("["+SQLiteErrorCode.SQLITE_CONSTRAINT.name()+"]") &&
+ msg.contains("column " + DbTables.TSLDownload.C.rawHash + " is not unique")
+ );
+ }
+
+ @Override
+ protected Long getLocalLastModified(File targetFile) {
+ return super.getLocalLastModified(targetFile);
+ }
+ @Override
+ protected long howLongWaitForThreads() {
+ // TODO Auto-generated method stub
+ return 100000;
+ }
+
+ @Override
+ protected boolean normalizeXML() {
+ return true;
+ }
+ public MultiThreadLoggingGroup getLoggingGroup() {
+ return this;
+ }
+
+ StringBuilder log = new StringBuilder();
+
+ public void flushLog() {
+ if (log != null && log.length() > 0) {
+ Thread currentThread = Thread.currentThread();
+ String ncName = getNcName(currentThread);
+ synchronized (log) {
+ parentContext_.print("<" + ncName + " state=\"" + currentThread.getState()
+ + "\" " + " id=\"" + currentThread.getId() + "\">\n" + log.toString() + "</"
+ + ncName + ">" + _15.LB);
+ parentContext_.flushLog();
+ log.setLength(0);
+ }
+ }
+ }
+
+ /**
+ * Collect all the logs for this context
+ * @see iaik.util.logging.Log.MultiThreadLoggingGroup#print(java.lang.Object)
+ */
+ public void print(Object msg) {
+ synchronized (log) {
+ log.append(msg);
+ }
+ }
+
+} \ No newline at end of file