From 0872d2d8a64fd701776b272f49222428d8def07f Mon Sep 17 00:00:00 2001 From: Andreas Fitzek Date: Tue, 3 Nov 2015 14:38:34 +0100 Subject: initial commit --- .../spss/tsl/utils/TSLImportFromFileContext.java | 850 +++++++++++++++++++++ 1 file changed, 850 insertions(+) create mode 100644 moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/utils/TSLImportFromFileContext.java (limited to 'moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/tsl/utils/TSLImportFromFileContext.java') 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> + 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 > 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 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 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() + "" + _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 -- cgit v1.2.3