diff options
8 files changed, 336 insertions, 3 deletions
| diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/ErrorConstants.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/ErrorConstants.java index 7c2fb03c..d99299a9 100644 --- a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/ErrorConstants.java +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/ErrorConstants.java @@ -22,8 +22,12 @@ public interface ErrorConstants {  	// Verification Errors +	  	// Configuration Errors:  	public static final long ERROR_SET_INVALID_SETTINGS_OBJ = 13001;  	public static final long ERROR_INVALID_CERTIFICATE = 13002;  	public static final long ERROR_INVALID_PLACEHOLDER_MODE = 13003; +	 +	//Validation Errors +	public static final long ERROR_NO_CONF_VALIDATION_BACKEND = 14001;  } diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsSettingsValidationException.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsSettingsValidationException.java new file mode 100644 index 00000000..869855ef --- /dev/null +++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/PdfAsSettingsValidationException.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * <copyright> Copyright 2014 by E-Government Innovation Center EGIZ, Graz, Austria </copyright> + * PDF-AS has been contracted by the E-Government Innovation Center EGIZ, a + * joint initiative of the Federal Chancellery Austria and Graz University of + * Technology. + *  + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + *  + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + *  + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + ******************************************************************************/ +package at.gv.egiz.pdfas.common.exceptions; + +/** + * Created with IntelliJ IDEA. + * User: afitzek + * Date: 9/10/13 + * Time: 10:54 AM + * To change this template use File | Settings | File Templates. + */ +public class PdfAsSettingsValidationException extends PdfAsException { + +    /** +	 *  +	 */ +	private static final long serialVersionUID = 3277787631624822104L; + + +	public PdfAsSettingsValidationException(String msgId) { +        super(msgId); +    } + + +    public PdfAsSettingsValidationException(String msgId, Throwable e) { +        super(msgId, e); +    } +} diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java index cd0a4699..72d182ed 100644 --- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/PdfAsFactory.java @@ -37,9 +37,10 @@ import java.io.OutputStream;  import java.lang.management.ManagementFactory;  import java.lang.management.OperatingSystemMXBean;  import java.lang.management.RuntimeMXBean; -import java.lang.reflect.Field;  import java.security.Provider;  import java.security.Security; +import java.util.Map; +import java.util.Map.Entry;  import java.util.zip.ZipEntry;  import java.util.zip.ZipInputStream; @@ -49,12 +50,16 @@ import javax.crypto.Cipher;  import org.slf4j.Logger;  import org.slf4j.LoggerFactory; +import at.gv.egiz.pdfas.common.exceptions.PdfAsSettingsException; +import at.gv.egiz.pdfas.common.exceptions.PdfAsSettingsValidationException;  import at.gv.egiz.pdfas.common.settings.ISettings;  import at.gv.egiz.pdfas.lib.api.sign.SignParameter;  import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter; +import at.gv.egiz.pdfas.lib.configuration.ConfigurationValidator;  import at.gv.egiz.pdfas.lib.impl.PdfAsImpl;  import at.gv.egiz.pdfas.lib.impl.SignParameterImpl;  import at.gv.egiz.pdfas.lib.impl.VerifyParameterImpl; +import at.gv.egiz.pdfas.lib.impl.configuration.ConfigValidatorLoader;  public class PdfAsFactory implements IConfigurationConstants { @@ -359,4 +364,22 @@ public class PdfAsFactory implements IConfigurationConstants {  		Package pack = PdfAsFactory.class.getPackage();  		return pack.getImplementationVersion();  	} +	 +	/** +	 * Execute all loaded Configuration Validators +	 *  +	 * @throws PdfAsSettingsValidationException  +	 */ +	public static void validateConfiguration(ISettings configuration) throws PdfAsSettingsValidationException{ +		Map<String, ConfigurationValidator> availableValidators = ConfigValidatorLoader.getAvailableValidators(); +		if(availableValidators.isEmpty()){ +			logger.info("No configuration validators available"); +		} +		for(Entry<String, ConfigurationValidator> validatorEntry : availableValidators.entrySet()){ +			logger.info("Running configuration validator: "+validatorEntry.getKey()); +			validatorEntry.getValue().validate(configuration); +		} +		logger.info("All configuration validators succeded."); + +	}  } diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/ConfigValidatorLoader.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/ConfigValidatorLoader.java new file mode 100644 index 00000000..0e1e2580 --- /dev/null +++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/ConfigValidatorLoader.java @@ -0,0 +1,108 @@ +package at.gv.egiz.pdfas.lib.impl.configuration; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.ServiceLoader; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.gv.egiz.pdfas.common.exceptions.ErrorConstants; +import at.gv.egiz.pdfas.common.exceptions.PDFASError; +import at.gv.egiz.pdfas.lib.api.Configuration; +import at.gv.egiz.pdfas.lib.backend.PDFASBackend; +import at.gv.egiz.pdfas.lib.configuration.ConfigurationValidator; + +public class ConfigValidatorLoader implements ErrorConstants{ +	/** The Constant logger. */ +	private static final Logger logger = LoggerFactory +			.getLogger(ConfigValidatorLoader.class); +	 +	/** The configuration verifier loader. */ +	private static ServiceLoader<ConfigurationValidator> configurationValidator = ServiceLoader.load(ConfigurationValidator.class); +	 +	/** The available verification backends. */ +	private static Map<String, ConfigurationValidator> availableValidators = new HashMap<String, ConfigurationValidator>(); +	 +	/** The Constant VALIDATOR_CONFIG. */ +	public static final String VALIDATOR_CONFIG = "runtime.config.validator"; +	 +	/** The default validator. */ +	private static ConfigurationValidator defaultValidator = null;  +	 +	static { +		logger.debug("building Configuration Validator"); +		 +		Iterator<ConfigurationValidator> backendIterator = configurationValidator.iterator(); +		 +		while(backendIterator.hasNext()) { +			ConfigurationValidator backend = backendIterator.next(); +			logger.debug("Loading " + backend.getName() + " [" + backend.getClass().getName() + "]"); +			availableValidators.put(backend.getName(), backend); +			logger.debug("PDF-Backend added " + backend.getName()); +			if(backend.usedAsDefault()) { +				defaultValidator = backend; +				logger.debug("PDF-Backend added as default " + backend.getName()); +			} +		} +		 +		logger.debug("Configuration Validator Backends constructed"); +		 +		if(defaultValidator != null) { +			logger.debug("Default backend is " + defaultValidator.getName()); +		} +	} +	 +	/** +	 * Gets the Configuration valdiator. +	 * +	 * @param configuration the configuration +	 * @return the validator backend +	 * @throws PDFASError the PDFAS error +	 */ +	public static ConfigurationValidator getConfigurationValidator(Configuration configuration) throws PDFASError { +		String backendName = configuration.getValue(VALIDATOR_CONFIG); +		return getConfigurationValidator(backendName); +	} +	 +	/** +	 * Gets the Validator by name. +	 * +	 * @param name the name +	 * @return the validator backend +	 * @throws PDFASError the PDFAS error +	 */ +	public static ConfigurationValidator getConfigurationValidator(String name) throws PDFASError { +		if(name != null) { +			if(availableValidators.containsKey(name)) { +				return availableValidators.get(name); +			} +			throw new PDFASError(ERROR_NO_CONF_VALIDATION_BACKEND); +		} +		 +		if(defaultValidator != null) { +			return defaultValidator; +		} +		 +		throw new PDFASError(ERROR_NO_CONF_VALIDATION_BACKEND); +	} +	 +	/** +	 * Gets the Configuration Validator. +	 * +	 * @return the validator backend +	 * @throws PDFASError the PDFAS error +	 */ +	public static ConfigurationValidator getConfigurationValidator() throws PDFASError { +		if(defaultValidator != null) { +			return defaultValidator; +		} +		 +		throw new PDFASError(ERROR_NO_CONF_VALIDATION_BACKEND); +	} +	 +	public static Map<String, ConfigurationValidator> getAvailableValidators(){ +			return availableValidators; +	} +} diff --git a/pdf-as-pdfbox-2/build.gradle b/pdf-as-pdfbox-2/build.gradle index 4fe4b427..f62604a3 100644 --- a/pdf-as-pdfbox-2/build.gradle +++ b/pdf-as-pdfbox-2/build.gradle @@ -25,9 +25,13 @@ dependencies {  	compile 'org.slf4j:jcl-over-slf4j:1.7.18'  	compile group: 'org.apache.pdfbox', name: 'pdfbox', version: '2.0.2'  	compile group: 'org.apache.pdfbox', name: 'pdfbox-tools', version: '2.0.2' +	testCompile group: 'org.apache.pdfbox', name: 'preflight', version: '2.0.2'  	compile group: 'commons-io', name: 'commons-io', version: '2.4'  	compile group: 'ognl', name: 'ognl', version: '3.0.6'  	testCompile group: 'junit', name: 'junit', version: '4.+' +	compile group: 'com.github.jai-imageio', name: 'jai-imageio-jpeg2000', version: '1.3.0' +	compile group: 'com.github.jai-imageio', name: 'jai-imageio-core', version: '1.3.1' +	compile group: 'com.levigo.jbig2', name: 'levigo-jbig2-imageio', version: '1.6.5'  }  test { diff --git a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/configuration/ProfileValidator.java b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/configuration/ProfileValidator.java new file mode 100644 index 00000000..8d02d1b3 --- /dev/null +++ b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/configuration/ProfileValidator.java @@ -0,0 +1,131 @@ +package at.gv.egiz.pdfas.lib.impl.pdfbox2.configuration; + +import iaik.asn1.ObjectID; +import iaik.asn1.structures.Name; +import iaik.x509.X509Certificate; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.common.PDRectangle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.gv.egiz.pdfas.common.exceptions.PdfAsSettingsValidationException; +import at.gv.egiz.pdfas.common.settings.ISettings; +import at.gv.egiz.pdfas.common.settings.SignatureProfileSettings; +import at.gv.egiz.pdfas.lib.api.ByteArrayDataSource; +import at.gv.egiz.pdfas.lib.configuration.ConfigurationValidator; +import at.gv.egiz.pdfas.lib.impl.pdfbox2.PDFBOXObject; +import at.gv.egiz.pdfas.lib.impl.stamping.TableFactory; +import at.gv.egiz.pdfas.lib.impl.stamping.pdfbox2.PDFBoxTable; +import at.gv.egiz.pdfas.lib.impl.status.ICertificateProvider; +import at.gv.egiz.pdfas.lib.impl.status.OperationStatus; +import at.knowcenter.wag.egov.egiz.table.Table; + +public class ProfileValidator implements ConfigurationValidator{ + +	private static final String NAME = "PDFBOX_2_PROFILE_VALIDATOR"; + +	private static final Logger logger = LoggerFactory +			.getLogger(ProfileValidator.class); + +	@Override +	public void validate(ISettings settings) throws PdfAsSettingsValidationException{ +		Set<String> profileIds = new HashSet<String>(); + +		Iterator<String> itKeys = settings.getFirstLevelKeys("sig_obj.types.") +				.iterator(); +		while (itKeys.hasNext()) { +			String key = itKeys.next(); +			String profile = key.substring("sig_obj.types.".length()); + +			if (settings.getValue(key).equals("on")) { +				profileIds.add(profile); +			} +		} +		logger.debug("Validating "+profileIds.size()+ " Profiles."); + +		ArrayList<SignatureProfileSettings> profileSettings = new ArrayList<SignatureProfileSettings>(); + +		OperationStatus opState = new OperationStatus(settings, null, null); +		 +		X509Certificate dummyCert = new X509Certificate(); +		dummyCert.setSerialNumber(new BigInteger("123")); +		Name n = new Name(); +		n.addRDN(ObjectID.country, "AT"); +		n.addRDN(ObjectID.locality, "Graz"); +		n.addRDN(ObjectID.organization ,"test"); +		n.addRDN(ObjectID.organizationalUnit ,"test"); +		n.addRDN(ObjectID.commonName ,"testca"); +		dummyCert.setIssuerDN(n); +		dummyCert.setSubjectDN(n); + +		ICertificateProvider certProvider = new DummyCertificateProvider(dummyCert); + +		PDFBOXObject pdfBoxObject = new PDFBOXObject(opState); +		PDDocument origDoc = new PDDocument(); +		origDoc.addPage(new PDPage(PDRectangle.A4)); +		ByteArrayOutputStream baos = new ByteArrayOutputStream(); +		try { + +			origDoc.save(baos); +			baos.close(); +			origDoc.close(); + +			pdfBoxObject.setOriginalDocument(new ByteArrayDataSource(baos.toByteArray())); +		} catch (IOException e1) { +			logger.info("Configuration Validation failed!"); +			throw new PdfAsSettingsValidationException("Configuration Validationfailed!", e1); +		} + + +		for(String id:profileIds){ +			SignatureProfileSettings profileSetting = new SignatureProfileSettings(id, settings); +			profileSettings.add(profileSetting); +			if(profileSetting.getValue("isvisible")!=null){ +				if(profileSetting.getValue("isvisible").equals("false")){ +					continue; +				} +			} +			Table t; +			try { +				t = TableFactory.createSigTable(profileSetting, "main", opState, certProvider); +				new PDFBoxTable(t, null, settings, pdfBoxObject); +			} catch (Exception e) { +				logger.info("Configuration Validation for profile "+id+" failed!"); +				throw new PdfAsSettingsValidationException("Configuration Validation for profile "+id+" failed!", e); +			}  + +		} +	} + +	@Override +	public boolean usedAsDefault() { +		return true; +	} + +	@Override +	public String getName() { +		return NAME; +	} +	 +	private class DummyCertificateProvider implements ICertificateProvider { +		private X509Certificate cert;		 +		public DummyCertificateProvider(X509Certificate cert) { +			this.cert = cert; +		} +		public X509Certificate getCertificate() { +			return cert; +		} + +	} + +} diff --git a/pdf-as-pdfbox-2/src/main/resources/META-INF/services/at.gv.egiz.pdfas.lib.configuration.ConfigurationValidator b/pdf-as-pdfbox-2/src/main/resources/META-INF/services/at.gv.egiz.pdfas.lib.configuration.ConfigurationValidator new file mode 100644 index 00000000..ac38ebbf --- /dev/null +++ b/pdf-as-pdfbox-2/src/main/resources/META-INF/services/at.gv.egiz.pdfas.lib.configuration.ConfigurationValidator @@ -0,0 +1 @@ +at.gv.egiz.pdfas.lib.impl.pdfbox2.configuration.ProfileValidator
\ No newline at end of file diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ExternSignServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ExternSignServlet.java index b70539a4..f21447dd 100644 --- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ExternSignServlet.java +++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ExternSignServlet.java @@ -40,6 +40,10 @@ import org.slf4j.LoggerFactory;  import at.gv.egiz.pdfas.common.exceptions.PDFASError;  import at.gv.egiz.pdfas.common.exceptions.PdfAsException; +import at.gv.egiz.pdfas.common.exceptions.PdfAsSettingsException; +import at.gv.egiz.pdfas.common.exceptions.PdfAsSettingsValidationException; +import at.gv.egiz.pdfas.common.settings.ISettings; +import at.gv.egiz.pdfas.lib.api.PdfAsFactory;  import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter.SignatureVerificationLevel;  import at.gv.egiz.pdfas.web.config.WebConfiguration;  import at.gv.egiz.pdfas.web.exception.PdfAsWebException; @@ -49,10 +53,10 @@ import at.gv.egiz.pdfas.web.helper.PdfAsHelper;  import at.gv.egiz.pdfas.web.helper.PdfAsParameterExtractor;  import at.gv.egiz.pdfas.web.helper.RemotePDFFetcher;  import at.gv.egiz.pdfas.web.stats.StatisticEvent; -import at.gv.egiz.pdfas.web.stats.StatisticFrontend;  import at.gv.egiz.pdfas.web.stats.StatisticEvent.Operation;  import at.gv.egiz.pdfas.web.stats.StatisticEvent.Source;  import at.gv.egiz.pdfas.web.stats.StatisticEvent.Status; +import at.gv.egiz.pdfas.web.stats.StatisticFrontend;  /**   * Servlet implementation class Sign @@ -71,8 +75,9 @@ public class ExternSignServlet extends HttpServlet {  	/**  	 * Default constructor. +  	 */ -	public ExternSignServlet() { +	public ExternSignServlet(){  		String webconfig = System.getProperty(PDF_AS_WEB_CONF);  		if(webconfig == null) { @@ -82,6 +87,14 @@ public class ExternSignServlet extends HttpServlet {  		WebConfiguration.configure(webconfig);  		PdfAsHelper.init(); +		 +		try { +			PdfAsFactory.validateConfiguration((ISettings)PdfAsHelper.getPdfAsConfig()); +		} catch (PdfAsSettingsValidationException e) { +			// TODO Auto-generated catch block +			logger.error(e.getLocalizedMessage(),e.getCause()); +			//e.printStackTrace(); +		}  	}  	protected void doGet(HttpServletRequest request, | 
