package at.gv.egovernment.moa.spss.tsl.utils; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileFilter; 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.GeneralLog; import iaik.utils.RFC2253NameParserException; import iaik.utils.Util; import iaik.util.GeneralUtils15; 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]; GeneralLog.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[]) GeneralUtils15.reverseInPlace(rdns); subDN = "/"+GeneralUtils15.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; } } GeneralLog.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.GeneralUtils15.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(); GeneralLog.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(); GeneralLog.info(msg); return( msg.startsWith("["+SQLiteErrorCode.SQLITE_CONSTRAINT.name()+"]") && msg.contains("column " + DbTables.TSLDownload.C.rawHash + " is not unique") ); } @Override protected File 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() + "" + GeneralUtils15.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); } } @Override public FileFilter getCertificateFileFilter() { return null; } }