From 046cb5b235866e66ca9d2c55bd20ed7ec85ef12d Mon Sep 17 00:00:00 2001 From: tknall Date: Wed, 11 Jun 2008 12:09:06 +0000 Subject: Serious bug solved. Method storeCertificate tried to fetch a certificate from store before storing it. If not found (within the store resp. via ldap) the certificate was not stored. git-svn-id: https://joinup.ec.europa.eu/svn/pdf-as/trunk@282 7b5415b0-85f9-ee4d-85bd-d5d0c3b42d1c --- dok/Issues.txt | 5 ++ pom.xml | 2 +- .../java/at/gv/egiz/pdfas/commandline/Main.java | 3 +- .../at/gv/egiz/pdfas/impl/api/PdfAsObject.java | 3 +- .../java/at/gv/egiz/pdfas/utils/ConfigUtils.java | 64 +++++++++++++++++++++ .../java/at/knowcenter/wag/egov/egiz/PdfAS.java | 2 +- .../wag/egov/egiz/cfg/SettingsReader.java | 52 ++++++----------- .../knowcenter/wag/egov/egiz/commandline/Main.java | 11 ++-- .../wag/egov/egiz/sig/SignatureObject.java | 14 ++++- .../at/knowcenter/wag/egov/egiz/sig/X509Cert.java | 21 +++++++ .../egov/egiz/web/PdfASServletContextListener.java | 10 +++- src/main/resources/DefaultConfiguration.zip | Bin 190303 -> 190303 bytes src/site/changes.xml | 4 ++ test-files/blindtext_mit_leerer_seite.pdf | Bin 0 -> 116996 bytes 14 files changed, 141 insertions(+), 50 deletions(-) create mode 100644 dok/Issues.txt create mode 100644 test-files/blindtext_mit_leerer_seite.pdf diff --git a/dok/Issues.txt b/dok/Issues.txt new file mode 100644 index 0000000..5cb5fa0 --- /dev/null +++ b/dok/Issues.txt @@ -0,0 +1,5 @@ +Issue #1 +Bei der Signatur eines Dokuments, dem zuvor eine leere letzte Seite hinzugefügt wurde, befindet +sich die Signaturmarke am Beginn dieser letzten leeren Seite selbst wenn auf der vorletzten Seite +noch genügend Platz zu Verfügung stehen würde. + diff --git a/pom.xml b/pom.xml index 51067a8..e0f16fc 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ knowcenter pdf-as PDF-AS - 3.0.5-20080610 + 3.0.5-20080611 Amtssignatur fuer elektronische Aktenfuehrung diff --git a/src/main/java/at/gv/egiz/pdfas/commandline/Main.java b/src/main/java/at/gv/egiz/pdfas/commandline/Main.java index dea19b6..8330238 100644 --- a/src/main/java/at/gv/egiz/pdfas/commandline/Main.java +++ b/src/main/java/at/gv/egiz/pdfas/commandline/Main.java @@ -28,7 +28,6 @@ import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.log4j.PropertyConfigurator; import at.gv.egiz.pdfas.PdfAsFactory; import at.gv.egiz.pdfas.api.PdfAs; @@ -192,7 +191,7 @@ public abstract class Main } SettingsReader.initializeForCommandLine(); - PropertyConfigurator.configure(SettingsReader.CONFIG_PATH + "log4j.properties"); + ConfigUtils.initializeLogger(); // printUsage(System.out); diff --git a/src/main/java/at/gv/egiz/pdfas/impl/api/PdfAsObject.java b/src/main/java/at/gv/egiz/pdfas/impl/api/PdfAsObject.java index 0450a50..635ef89 100644 --- a/src/main/java/at/gv/egiz/pdfas/impl/api/PdfAsObject.java +++ b/src/main/java/at/gv/egiz/pdfas/impl/api/PdfAsObject.java @@ -46,6 +46,7 @@ import at.gv.egiz.pdfas.impl.api.sign.SignResultImpl; import at.gv.egiz.pdfas.impl.api.verify.VerifyResultAdapter; import at.gv.egiz.pdfas.impl.api.verify.VerifyResultsImpl; import at.gv.egiz.pdfas.impl.vfilter.VerificationFilterParametersImpl; +import at.gv.egiz.pdfas.utils.ConfigUtils; import at.knowcenter.wag.egov.egiz.PdfAS; import at.knowcenter.wag.egov.egiz.PdfASID; import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; @@ -106,7 +107,7 @@ public class PdfAsObject implements PdfAs */ public void reloadConfig() throws PdfAsException { - PropertyConfigurator.configure(SettingsReader.CONFIG_PATH + "log4j.properties"); + ConfigUtils.initializeLogger(); SettingsReader.createInstance(); SignatureTypes.createInstance(); } diff --git a/src/main/java/at/gv/egiz/pdfas/utils/ConfigUtils.java b/src/main/java/at/gv/egiz/pdfas/utils/ConfigUtils.java index 0e606d7..627e611 100644 --- a/src/main/java/at/gv/egiz/pdfas/utils/ConfigUtils.java +++ b/src/main/java/at/gv/egiz/pdfas/utils/ConfigUtils.java @@ -9,11 +9,16 @@ import java.io.OutputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.SystemUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.log4j.PropertyConfigurator; import at.gv.egiz.pdfas.api.commons.Constants; import at.gv.egiz.pdfas.api.exceptions.ConfigUtilsException; +import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; +import at.knowcenter.wag.egov.egiz.pdf.Utils; /** * @author Thomas Knall @@ -179,4 +184,63 @@ public final class ConfigUtils { outputStream.flush(); } + public static String assertFileSeparator(String path) { + if (path == null) { + throw new NullPointerException("Path must not be null."); + } + if (path.endsWith(File.separator) || path.endsWith("/") || path.endsWith("\\")) { + return path; + } else { + return (path + File.separator); + } + } + + public static void initializeLogger() { + String loggerConfiguration = System.getProperty("log4j.configuration"); + if (loggerConfiguration != null) { + logger_.info("No PDF-AS logger configured because a configuration has already been set via system property \"log4j.configuration\" (=\"" + loggerConfiguration + "\")."); + return; + } + loggerConfiguration = assertFileSeparator(SettingsReader.CONFIG_PATH) + "log4j.properties"; + File loggerConfigFile = new File(loggerConfiguration); + if (!loggerConfigFile.exists()) { + logger_.info("No PDF-AS logger configured because there is no log4j.properties within the pdf-as work dir. Maybe the logger configuration is handled by an outside application (e.g. a web aplication)."); + return; + } + logger_.info("Initializing PDF-AS logger (configuration = \"" + loggerConfiguration + "\")."); + PropertyConfigurator.configure(loggerConfiguration); + } + + public static void printConfigInfo(Log logger) { + int length = Utils.max(new int[] { SettingsReader.RESOURCES_PATH.length(), SettingsReader.TMP_PATH.length(), SettingsReader.CONFIG_PATH.length(), SettingsReader.CERT_PATH.length() }); + + String separator = StringUtils.repeat("*", length + 25); + String infoResources = " resources path = \"" + SettingsReader.RESOURCES_PATH + "\""; + String infoConfiguration = " configuration path = \"" + SettingsReader.CONFIG_PATH + "\""; + String infoCertStore = " certstore path = \"" + SettingsReader.CERT_PATH + "\""; + String infoTempPath = " temporary path = \"" + SettingsReader.TMP_PATH + "\""; + + if (logger != null) { + logger.info(separator); + logger.info(infoResources); + logger.info(infoConfiguration); + logger.info(infoCertStore); + logger.info(infoTempPath); + logger.info(separator); + } else { + StringBuffer buffer = new StringBuffer(); + buffer.append(separator).append(SystemUtils.LINE_SEPARATOR); + buffer.append(infoResources).append(SystemUtils.LINE_SEPARATOR); + buffer.append(infoConfiguration).append(SystemUtils.LINE_SEPARATOR); + buffer.append(infoCertStore).append(SystemUtils.LINE_SEPARATOR); + buffer.append(infoTempPath).append(SystemUtils.LINE_SEPARATOR); + buffer.append(separator); + System.out.println(buffer.toString()); + } + } + + public static void printConfigInfo() { + printConfigInfo(null); + } + } diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java b/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java index 7def267..f6b74be 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/PdfAS.java @@ -96,7 +96,7 @@ public abstract class PdfAS * The current version of the pdf-as library. This version string is logged on every invocation * of the api or the web application. */ - public static final String PDFAS_VERSION = "3.0.5-20080610"; + public static final String PDFAS_VERSION = "3.0.5-20080611"; /** * The key of the strict mode setting. diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/cfg/SettingsReader.java b/src/main/java/at/knowcenter/wag/egov/egiz/cfg/SettingsReader.java index 31ca5e1..c7e5933 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/cfg/SettingsReader.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/cfg/SettingsReader.java @@ -152,11 +152,6 @@ public class SettingsReader implements Serializable // private static final String TEMP_FILE_PATH = // System.getProperty("java.io.tmpdir"); - /** - * The current user path - */ - private static final String USER_DIR = System.getProperty("user.dir"); - // /** // * The home path of the tomcat webaplication // */ @@ -400,7 +395,14 @@ public class SettingsReader implements Serializable logger_.info(" certstore path = \"" + CERT_PATH + "\""); logger_.info(" temporary path = \"" + TMP_PATH + "\""); logger_.info(StringUtils.repeat("*", length + 25)); - instance_ = new SettingsReader(settingsFile); + + IAIK.addAsProvider(); + ECCProvider.addAsProvider(); + // Does not conform with PKIX, but is used by belgium citizen card +// log.info("Registering RDN \"SERIALNUMBER\" as " + ObjectID.serialNumber + "."); + RFC2253NameParser.register("SERIALNUMBER", ObjectID.serialNumber); + + instance_ = new SettingsReader(settingsFile); } return instance_; } @@ -681,17 +683,6 @@ public class SettingsReader implements Serializable TempDirHelper.clearTemporaryDirectory(); } - private static String assertFileSeparator(String path) { - if (path == null) { - throw new NullPointerException("Path must not be null."); - } - if (path.endsWith(File.separator) || path.endsWith("/") || path.endsWith("\\")) { - return path; - } else { - return (path + File.separator); - } - } - public static synchronized void initialize(String configdir, String tmpdir) { String defaultConfigDeployedTo = null; @@ -710,7 +701,7 @@ public class SettingsReader implements Serializable if (userHome == null || userHome.length() == 0) { throw new RuntimeException("Unable to resolve user's home directory."); } - configdir = assertFileSeparator(userHome) + Constants.USERHOME_CONFIG_FOLDER; + configdir = ConfigUtils.assertFileSeparator(userHome) + Constants.USERHOME_CONFIG_FOLDER; try { defaultConfigDeployedTo = ConfigUtils.deployDefaultConfiguration(configdir, false); } catch (ConfigUtilsException e) { @@ -732,9 +723,9 @@ public class SettingsReader implements Serializable } File configdirFile = new File(StrSubstitutor.replaceSystemProperties(configdir)); try { - configdir = assertFileSeparator(configdirFile.getCanonicalPath()); + configdir = ConfigUtils.assertFileSeparator(configdirFile.getCanonicalPath()); } catch (IOException e) { - configdir = assertFileSeparator(configdirFile.getPath()); + configdir = ConfigUtils.assertFileSeparator(configdirFile.getPath()); } if (!configdirFile.isDirectory()) { @@ -752,26 +743,20 @@ public class SettingsReader implements Serializable } else { logger_.debug("Temporary directory explicitely set."); } - File tmpdirFile = new File(StrSubstitutor.replaceSystemProperties(assertFileSeparator(tmpdir) + Constants.TEMP_DIR_NAME)); + File tmpdirFile = new File(StrSubstitutor.replaceSystemProperties(ConfigUtils.assertFileSeparator(tmpdir) + Constants.TEMP_DIR_NAME)); try { - tmpdir = assertFileSeparator(tmpdirFile.getCanonicalPath()); + tmpdir = ConfigUtils.assertFileSeparator(tmpdirFile.getCanonicalPath()); } catch (IOException e) { - tmpdir = assertFileSeparator(tmpdirFile.getPath()); + tmpdir = ConfigUtils.assertFileSeparator(tmpdirFile.getPath()); } RESOURCES_PATH = configdir; TMP_PATH = tmpdir; CONFIG_PATH = RESOURCES_PATH + CFG + FILE_SEP; CERT_PATH = RESOURCES_PATH + CERT + FILE_SEP; + +// ConfigUtils.printConfigInfo(logger_); - int length = Utils.max(new int[] { RESOURCES_PATH.length(), TMP_PATH.length(), CONFIG_PATH.length(), CERT_PATH.length() }); - - logger_.debug(StringUtils.repeat("*", length + 25)); - logger_.debug(" resources path = \"" + RESOURCES_PATH + "\""); - logger_.debug(" configuration path = \"" + CONFIG_PATH + "\""); - logger_.debug(" certstore path = \"" + CERT_PATH + "\""); - logger_.debug(" temporary path = \"" + TMP_PATH + "\""); - logger_.debug(StringUtils.repeat("*", length + 25)); if (defaultConfigDeployedTo != null) { logger_.debug("** Default configuration successfully deployed to \"" + defaultConfigDeployedTo + "\" **"); } @@ -805,11 +790,6 @@ public class SettingsReader implements Serializable } static { - IAIK.addAsProvider(); - ECCProvider.addAsProvider(); - // Does not conform with PKIX, but is used by belgium citizen card -// log.info("Registering RDN \"SERIALNUMBER\" as " + ObjectID.serialNumber + "."); - RFC2253NameParser.register("SERIALNUMBER", ObjectID.serialNumber); String versionString = "* PDF-AS library version " + PdfAS.PDFAS_VERSION + " *"; String paddingString = StringUtils.repeat("*", versionString.length()); diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/commandline/Main.java b/src/main/java/at/knowcenter/wag/egov/egiz/commandline/Main.java index 76159ec..9e45469 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/commandline/Main.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/commandline/Main.java @@ -24,7 +24,6 @@ import java.io.PrintStream; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.util.ArrayList; -import java.util.Date; import java.util.Iterator; import java.util.List; @@ -45,7 +44,6 @@ import at.gv.egiz.pdfas.framework.vfilter.VerificationFilterParameters; import at.gv.egiz.pdfas.impl.input.FileBasedPdfDataSourceImpl; import at.gv.egiz.pdfas.impl.input.TextDataSourceImpl; import at.gv.egiz.pdfas.impl.output.FileBasedDataSink; -import at.gv.egiz.pdfas.impl.vfilter.VerificationFilterParametersImpl; import at.knowcenter.wag.egov.egiz.PdfAS; import at.knowcenter.wag.egov.egiz.PdfASID; import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; @@ -57,8 +55,6 @@ import at.knowcenter.wag.egov.egiz.exceptions.SettingNotFoundException; import at.knowcenter.wag.egov.egiz.exceptions.SignatureException; import at.knowcenter.wag.egov.egiz.exceptions.SignatureTypesException; import at.knowcenter.wag.egov.egiz.framework.SignatorFactory; -import at.knowcenter.wag.egov.egiz.framework.signators.BinarySignator_1_0_0; -import at.knowcenter.wag.egov.egiz.framework.signators.TextualSignator_1_0_0; import at.knowcenter.wag.egov.egiz.pdf.SignatureHolder; import at.knowcenter.wag.egov.egiz.pdf.TablePos; import at.knowcenter.wag.egov.egiz.sig.ConnectorFactory; @@ -159,6 +155,12 @@ public abstract class Main * * @deprecated use {@link at.gv.egiz.pdfas.commandline.Main} instead */ + public static void main(String[] args) throws IOException { + System.out.println("\nWarning: The entry point at.knowcenter.wag.egov.egiz.commandline.Main is deprecated. Use at.gv.egiz.pdfas.commandline.Main instead.\n"); + at.gv.egiz.pdfas.commandline.Main.main(args); + } + + /* public static void main(String[] args) throws IOException { // ConfigLogger.setLevel(Level.DEBUG); @@ -420,6 +422,7 @@ public abstract class Main SettingsReader.clearTemporaryDirectory(); } } + */ protected static void carryOutCommand(final String mode, final String signature_mode, final String connector, final String signature_type, final String user_name, final String user_password, final int verify_which, final String input, String output, final String pos_string) throws PresentableException diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureObject.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureObject.java index b4818cd..1b9b6a6 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureObject.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/SignatureObject.java @@ -696,9 +696,12 @@ public class SignatureObject implements Serializable { try { - byte [] der = cert.getEncoded(); - String certStr = CodingHelper.encodeBase64(der); - setX509Certificate(certStr); +// byte [] der = cert.getEncoded(); +// String certStr = CodingHelper.encodeBase64(der); +// setX509Certificate(certStr); + X509Cert knowcenterCert = X509Cert.initByX509Certificate(cert); + setSigValue(SIG_CER, knowcenterCert.getCertString()); + storeCertificate(cert.getSerialNumber().toString(), knowcenterCert.getIssuerName(), knowcenterCert.getCertString(), knowcenterCert.getCertDigest()); } catch (CertificateEncodingException e) { @@ -1322,17 +1325,20 @@ public class SignatureObject implements Serializable boolean store_complete = false; if (issuer != null && serialNumber != null) { + logger_.debug("Storing certificate."); // String issuer_b64 = CodingHelper.encodeBase64(issuer.getBytes()); String iss_hash = getIssuerFileHash(issuer); File cert_path_dir = new File(certPath_); if (!cert_path_dir.exists()) { + logger_.debug("Certstore path \"" + cert_path_dir + "\" does not exist. Creating."); cert_path_dir.mkdir(); } String cert_store_path = certPath_ + iss_hash; File cert_store_dir = new File(cert_store_path); if (!cert_store_dir.exists()) { + logger_.debug("Certstore dir \"" + cert_store_dir + "\" does not exist. Creating."); cert_store_dir.mkdir(); } if (cert_store_dir.isDirectory()) @@ -1344,6 +1350,8 @@ public class SignatureObject implements Serializable } boolean store_cert_file = FileHelper.writeToFile(cert_file_name, x509Certificate); store_complete = store_cert_file;// && store_cert_meta; + } else { + logger_.warn("Certstore dir \"" + cert_store_dir + "\" is not a directory. Skipping storage."); } } return store_complete; diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/sig/X509Cert.java b/src/main/java/at/knowcenter/wag/egov/egiz/sig/X509Cert.java index 71ca754..148ac41 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/sig/X509Cert.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/sig/X509Cert.java @@ -166,6 +166,27 @@ public class X509Cert implements Serializable } return x509_cert; } + + public static X509Cert initByX509Certificate(X509Certificate cert) throws CertificateEncodingException { + X509Cert x509_cert = new X509Cert(); + x509_cert.setX509Cert(cert); + x509_cert.setCertString(CodingHelper.encodeBase64(cert.getEncoded())); + + String serial_num = cert.getSerialNumber().toString(); + String issuer = cert.getIssuerDN().getName(); + issuer = issuer.replaceAll(", ", ","); + String subject_name = cert.getSubjectDN().getName(); + x509_cert.setSerialNumber(serial_num); + x509_cert.setIssuerName(issuer); + x509_cert.setSubjectName(subject_name); + if (logger_.isDebugEnabled()) + { + logger_.debug("Serial number from certificate:" + serial_num); + logger_.debug("Issuer name from certificate :" + issuer); + logger_.debug("Subject name from certificate :" + subject_name); + } + return x509_cert; + } public static X509Cert initByByteArray(byte[] data) { diff --git a/src/main/java/at/knowcenter/wag/egov/egiz/web/PdfASServletContextListener.java b/src/main/java/at/knowcenter/wag/egov/egiz/web/PdfASServletContextListener.java index 219fec2..95cb041 100644 --- a/src/main/java/at/knowcenter/wag/egov/egiz/web/PdfASServletContextListener.java +++ b/src/main/java/at/knowcenter/wag/egov/egiz/web/PdfASServletContextListener.java @@ -21,11 +21,12 @@ import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.apache.log4j.Logger; -import org.apache.log4j.PropertyConfigurator; import at.gv.egiz.pdfas.api.commons.Constants; +import at.gv.egiz.pdfas.utils.ConfigUtils; import at.knowcenter.wag.egov.egiz.cfg.ConfigLogger; import at.knowcenter.wag.egov.egiz.cfg.SettingsReader; +import at.knowcenter.wag.egov.egiz.exceptions.SettingsException; /** * The ServletContextListener is notified when the webapplication starts up and shuts down. @@ -93,7 +94,12 @@ public class PdfASServletContextListener implements ServletContextListener SettingsReader.initializeForWeb(work_dir); - PropertyConfigurator.configure(SettingsReader.CONFIG_PATH + "log4j.properties"); + ConfigUtils.initializeLogger(); + try { + SettingsReader.getInstance(); + } catch (SettingsException e) { + logger.error(e); + } SettingsReader.clearTemporaryDirectory(); } diff --git a/src/main/resources/DefaultConfiguration.zip b/src/main/resources/DefaultConfiguration.zip index a8a9a06..4682add 100644 Binary files a/src/main/resources/DefaultConfiguration.zip and b/src/main/resources/DefaultConfiguration.zip differ diff --git a/src/site/changes.xml b/src/site/changes.xml index 25e5838..fc2b488 100644 --- a/src/site/changes.xml +++ b/src/site/changes.xml @@ -13,6 +13,10 @@ --> + + Serious bug solved. Method storeCertificate tried to fetch a certificate from store before storing it. If not found (within the store resp. via ldap) the certificate was not stored!!! + + Manual deployment of pdf-as configuration (commandline parameter -ddc) considers the system property pdf-as.work-dir. Internal default configuration updated. diff --git a/test-files/blindtext_mit_leerer_seite.pdf b/test-files/blindtext_mit_leerer_seite.pdf new file mode 100644 index 0000000..c68c448 Binary files /dev/null and b/test-files/blindtext_mit_leerer_seite.pdf differ -- cgit v1.2.3