aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--build.gradle27
-rw-r--r--doc/AnbindungExterneWebanwendung.docxbin470686 -> 348150 bytes
-rw-r--r--doc/AnbindungExterneWebanwendung.pdfbin614939 -> 574940 bytes
-rw-r--r--doc/PDFAS4_Dokumentation.docxbin133651 -> 94659 bytes
-rw-r--r--doc/PDFAS4_Dokumentation.pdfbin423016 -> 450334 bytes
-rw-r--r--doc/PDFAS4_WebDokumentation.docxbin183745 -> 134755 bytes
-rw-r--r--doc/PDFAS4_WebDokumentation.pdfbin296122 -> 434616 bytes
-rw-r--r--pdf-as-cli/build.gradle2
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/api/processing/DocumentToSign.java4
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/api/ws/PDFASPropertyEntry.java10
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/api/ws/PDFASPropertyMap.java7
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/SLPdfAsException.java2
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/IProfileConstants.java1
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/ISettings.java16
-rw-r--r--pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/SignatureProfileSettings.java442
-rw-r--r--pdf-as-common/src/main/resources/resources/messages/common.properties3
-rw-r--r--pdf-as-common/src/main/resources/resources/messages/error.properties2
-rw-r--r--pdf-as-common/src/test/java/at/gv/egiz/pdfas/common/test/utils/CheckSignatureParametersTest.java48
-rw-r--r--pdf-as-legacy/src/main/java/at/gv/egiz/pdfas/api/commons/DynamicSignatureProfileImpl.java14
-rw-r--r--pdf-as-lib/build.gradle6
-rw-r--r--pdf-as-lib/src/configuration/cfg/advancedconfig.properties2
-rw-r--r--pdf-as-lib/src/configuration/cfg/log4j.properties23
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/IConfigurationConstants.java6
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/SignParameter.java33
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/ErrorExtractor.java5
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java30
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/SignParameterImpl.java13
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/ConfigurationImpl.java281
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/PlaceholderConfiguration.java103
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/PlaceholderWebConfiguration.java24
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/PlaceholderExtractor.java7
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/PlaceholderFilter.java186
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/SignaturePlaceholderContext.java95
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/settings/Settings.java700
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/util/SignatureUtils.java250
-rw-r--r--pdf-as-lib/src/test/java/at/gv/egiz/pdfas/lib/test/stamping/CertificateAndRequestParameterResolverTest.java42
-rw-r--r--pdf-as-moa/build.gradle2
-rw-r--r--pdf-as-moa/src/generated/java/at/gv/e_government/reference/namespace/moa/_20020822_/SignatureCreationService.java11
-rw-r--r--pdf-as-moa/src/generated/java/at/gv/e_government/reference/namespace/moa/_20020822_/SignatureVerificationService.java11
-rw-r--r--pdf-as-pdfbox-2/build.gradle5
-rw-r--r--pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/PDFBOXObject.java13
-rw-r--r--pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/placeholder/PDFBoxPlaceholderExtractor.java28
-rw-r--r--pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/placeholder/SignatureFieldsAndPlaceHolderExtractor.java134
-rw-r--r--pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/placeholder/SignaturePlaceholderExtractor.java860
-rw-r--r--pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/positioning/Positioning.java52
-rw-r--r--pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox2/PADESPDFBOXSigner.java788
-rw-r--r--pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox2/PDFAsVisualSignatureBuilder.java20
-rw-r--r--pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox2/PDFAsVisualSignatureProperties.java2
-rw-r--r--pdf-as-pdfbox-2/src/test/java/at/gv/egiz/pdfas/lib/testpdfbox/PDFBoxPlaceholderExtractorTest.java51
-rw-r--r--pdf-as-pdfbox-2/src/test/java/at/gv/egiz/pdfas/lib/testpdfbox/SignatureFieldsAndPlaceHolderExtractorTest.java8
-rw-r--r--pdf-as-pdfbox-2/src/test/resources/data/platzhalter_en_de_test.pdfbin0 -> 46732 bytes
-rw-r--r--pdf-as-web-db/build.gradle6
-rw-r--r--pdf-as-web-db/src/main/java/at/gv/egiz/pdfas/web/store/DBRequestStore.java11
-rw-r--r--pdf-as-web/build.gradle11
-rw-r--r--pdf-as-web/src/main/configuration/pdf-as-web.properties1
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java5
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/ExceptionCatchFilter.java86
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/UserAgentFilter.java9
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsHelper.java80
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsParameterExtractor.java16
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ErrorPage.java15
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ExternSignServlet.java19
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PDFData.java24
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PlaceholderGeneratorServlet.java14
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/SoapServiceServlet.java8
-rw-r--r--pdf-as-web/src/main/resources/META-INF/context.xml3
-rw-r--r--pdf-as-web/src/main/webapp/WEB-INF/web.xml4
-rw-r--r--signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESSignerKeystore.java341
69 files changed, 2419 insertions, 2607 deletions
diff --git a/.gitignore b/.gitignore
index 8ef6c6aa..9497274f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,6 +19,10 @@ pdf-as-tests/src/test/test-suites/*/
pdf-as-tests/src/test/test-suites/**/index.html
pdf-as-tests/src/test/test-suites/**/test_result.html
pdf-as-tests/src/test/test-suites/**/out
+pdf-as-tests/src/test/public_pdfbox1/*
+pdf-as-tests/src/test/public_pdfbox1/*/
+
+pdf-as-lib/src/main/resources/config/config.zip
**/generated/**
diff --git a/build.gradle b/build.gradle
index be66b393..9eb8a547 100644
--- a/build.gradle
+++ b/build.gradle
@@ -18,7 +18,7 @@ allprojects {
url "https://repo.spring.io/milestone/"
}
}
- version = '4.3.0-SNAPSHOT'
+ version = '4.3.3-SNAPSHOT'
}
subprojects {
@@ -58,8 +58,9 @@ subprojects {
}
dependencies {
- compileOnly group: 'org.projectlombok', name: 'lombok', version: '1.18.24'
- annotationProcessor group: 'org.projectlombok', name: 'lombok', version: '1.18.24'
+ implementation "org.projectlombok:lombok:1.18.28"
+ annotationProcessor "org.projectlombok:lombok:1.18.28"
+ testAnnotationProcessor "org.projectlombok:lombok:1.18.28"
testImplementation 'junit:junit:4.13.2'
}
@@ -83,7 +84,7 @@ subprojects {
revision = getCheckedOutGitCommitHash()
//tomcatVersion = '7.0.54';
//tomcatVersion = '8.0.36';
- tomcatVersion = '9.0.46';
+ tomcatVersion = '9.0.73';
slf4jVersion = '1.7.36'
cxfVersion = '3.5.5'
}
@@ -187,21 +188,9 @@ task releases(type: Copy) {
def getCheckedOutGitCommitHash() {
- def gitFolder = "$projectDir/.git/"
- def takeFromHash = 40
- /*
- * '.git/HEAD' contains either
- * in case of detached head: the currently checked out commit hash
- * otherwise: a reference to a file containing the current commit hash
- */
- def head = new File(gitFolder + "HEAD").text.split(":") // .git/HEAD
- def isCommit = head.length == 1 // e5a7c79edabbf7dd39888442df081b1c9d8e88fd
- // def isRef = head.length > 1 // ref: refs/heads/master
-
- if(isCommit) return head[0].trim().take(takeFromHash) // e5a7c79edabb
-
- def refHead = new File(gitFolder + head[1].trim()) // .git/refs/heads/master
- refHead.text.trim().take takeFromHash
+ def takeFromHash = 40
+ 'git rev-parse --verify HEAD'.execute().text.trim().take takeFromHash
+
}
/*
task docs(type: Javadoc) {
diff --git a/doc/AnbindungExterneWebanwendung.docx b/doc/AnbindungExterneWebanwendung.docx
index 764b9517..6a98e7a1 100644
--- a/doc/AnbindungExterneWebanwendung.docx
+++ b/doc/AnbindungExterneWebanwendung.docx
Binary files differ
diff --git a/doc/AnbindungExterneWebanwendung.pdf b/doc/AnbindungExterneWebanwendung.pdf
index 00338b3c..a1869361 100644
--- a/doc/AnbindungExterneWebanwendung.pdf
+++ b/doc/AnbindungExterneWebanwendung.pdf
Binary files differ
diff --git a/doc/PDFAS4_Dokumentation.docx b/doc/PDFAS4_Dokumentation.docx
index 9112d5b5..4ebc4a33 100644
--- a/doc/PDFAS4_Dokumentation.docx
+++ b/doc/PDFAS4_Dokumentation.docx
Binary files differ
diff --git a/doc/PDFAS4_Dokumentation.pdf b/doc/PDFAS4_Dokumentation.pdf
index 3dbafb00..cd01a613 100644
--- a/doc/PDFAS4_Dokumentation.pdf
+++ b/doc/PDFAS4_Dokumentation.pdf
Binary files differ
diff --git a/doc/PDFAS4_WebDokumentation.docx b/doc/PDFAS4_WebDokumentation.docx
index 880a3dcc..0e7b21ba 100644
--- a/doc/PDFAS4_WebDokumentation.docx
+++ b/doc/PDFAS4_WebDokumentation.docx
Binary files differ
diff --git a/doc/PDFAS4_WebDokumentation.pdf b/doc/PDFAS4_WebDokumentation.pdf
index 83207e5d..a75ad5da 100644
--- a/doc/PDFAS4_WebDokumentation.pdf
+++ b/doc/PDFAS4_WebDokumentation.pdf
Binary files differ
diff --git a/pdf-as-cli/build.gradle b/pdf-as-cli/build.gradle
index 94087093..3033cd00 100644
--- a/pdf-as-cli/build.gradle
+++ b/pdf-as-cli/build.gradle
@@ -35,7 +35,7 @@ dependencies {
implementation group: 'commons-collections', name: 'commons-collections', version: '3.2.2'
implementation group: 'commons-cli', name: 'commons-cli', version: '1.2'
implementation group: 'javax.activation', name: 'activation', version: '1.1.1'
- implementation 'ch.qos.logback:logback-classic:1.2.11'
+ implementation 'ch.qos.logback:logback-classic:1.2.12'
testImplementation group: 'junit', name: 'junit', version: '4.+'
}
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/api/processing/DocumentToSign.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/api/processing/DocumentToSign.java
index 6cc3a933..7d1928df 100644
--- a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/api/processing/DocumentToSign.java
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/api/processing/DocumentToSign.java
@@ -19,4 +19,8 @@ public class DocumentToSign implements Serializable {
String profile;
+ boolean placeholderSearchEnabled = true;
+
+ String placeHolderId;
+
}
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/api/ws/PDFASPropertyEntry.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/api/ws/PDFASPropertyEntry.java
index d02c7bbc..0b9b21af 100644
--- a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/api/ws/PDFASPropertyEntry.java
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/api/ws/PDFASPropertyEntry.java
@@ -1,11 +1,15 @@
package at.gv.egiz.pdfas.api.ws;
+import java.io.Serializable;
+
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
-@XmlType(name="PropertyEntry")
-public class PDFASPropertyEntry {
- String key;
+@XmlType(name="PropertyEntry")
+public class PDFASPropertyEntry implements Serializable {
+ private static final long serialVersionUID = -312145729002273058L;
+
+ String key;
String value;
@XmlElement(required = true, nillable = false, name="key")
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/api/ws/PDFASPropertyMap.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/api/ws/PDFASPropertyMap.java
index 34dca6d2..c3949849 100644
--- a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/api/ws/PDFASPropertyMap.java
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/api/ws/PDFASPropertyMap.java
@@ -1,5 +1,6 @@
package at.gv.egiz.pdfas.api.ws;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -11,8 +12,10 @@ import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
@XmlType(name="PropertyMap")
-public class PDFASPropertyMap {
- List<PDFASPropertyEntry> propertyEntries;
+public class PDFASPropertyMap implements Serializable {
+ private static final long serialVersionUID = -8099703140108251423L;
+
+ List<PDFASPropertyEntry> propertyEntries;
@XmlElement(required = true, nillable = false, name="propertyEntries")
public List<PDFASPropertyEntry> getPropertyEntries() {
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/SLPdfAsException.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/SLPdfAsException.java
index f22fc134..74462a03 100644
--- a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/SLPdfAsException.java
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/exceptions/SLPdfAsException.java
@@ -28,7 +28,7 @@ import java.util.List;
public class SLPdfAsException extends PdfAsException {
- private static final List<Integer> ERRORCODES_ON_INFO_LEVEL = Arrays.asList(6001, 6002);
+ private static final List<Integer> ERRORCODES_ON_INFO_LEVEL = Arrays.asList(6000, 6001, 6002);
/**
*
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/IProfileConstants.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/IProfileConstants.java
index 3f07f774..95eaa8ea 100644
--- a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/IProfileConstants.java
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/IProfileConstants.java
@@ -94,6 +94,7 @@ public interface IProfileConstants {
public final static String SIG_PDFA1B_VALID = "SIG_PDFA1B_VALID";
public final static String SIG_PDFA_VALID = "SIG_PDFA_VALID";
public final static String SIG_PDFUA_FORCE = "SIG_PDFUA_FORCE";
+ public final static String SIG_NEWPAGE_FORCE = "SIGNED_NEWPAGE_FORCE";
public final static String LATIN1_ENCODING = "latin1_encoding";
public final static String SIGNATURE_BLOCK_PARAMETER = "sbp";
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/ISettings.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/ISettings.java
index 42cdb8ab..43139966 100644
--- a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/ISettings.java
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/ISettings.java
@@ -29,6 +29,22 @@ import java.util.Vector;
public interface ISettings {
public String getValue(String key);
public boolean hasValue(String key);
+
+ /**
+ * Get boolean configuration value.
+ * @param key Configuration key
+ * @return <code>true</code> if configuration exists and has value <code>true</code>, otherwise <code>false</code>
+ */
+ public boolean isValue(String key);
+
+ /**
+ * Get boolean configuration value.
+ * @param key Configuration key
+ * @param defaultValue Value if configuration does not exist
+ * @return <code>true</code> if configuration exists and has value <code>true</code>, otherwise default value
+ */
+ public boolean isValue(String key, boolean defaultValue);
+
public boolean hasPrefix(String prefix);
public Map<String, String> getValuesPrefix(String prefix);
public Vector<String> getFirstLevelKeys(String prefix);
diff --git a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/SignatureProfileSettings.java b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/SignatureProfileSettings.java
index 7f047278..65722f88 100644
--- a/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/SignatureProfileSettings.java
+++ b/pdf-as-common/src/main/java/at/gv/egiz/pdfas/common/settings/SignatureProfileSettings.java
@@ -3,19 +3,19 @@
* 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
@@ -24,7 +24,6 @@
package at.gv.egiz.pdfas.common.settings;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.Map;
import org.slf4j.Logger;
@@ -35,241 +34,222 @@ import at.gv.egiz.pdfas.common.exceptions.PDFASError;
public class SignatureProfileSettings implements IProfileConstants {
- private static final Logger logger = LoggerFactory
- .getLogger(SignatureProfileSettings.class);
+ private static final Logger logger = LoggerFactory
+ .getLogger(SignatureProfileSettings.class);
- private Map<String, SignatureProfileEntry> profileInformations = new HashMap<String, SignatureProfileEntry>();
+ private final Map<String, SignatureProfileEntry> profileInformations =
+ new HashMap<>();
- private Map<String, String> profileSettings = new HashMap<String, String>();
+ private final Map<String, String> profileSettings = new HashMap<>();
- private String profileID;
+ private final String profileID;
- private String pdfAVersion = null;
+ private String pdfAVersion = null;
- private ISettings configuration;
+ private final ISettings configuration;
- public SignatureProfileSettings(String profileID, ISettings configuration) throws PDFASError {
-
- if (!configuration.hasPrefix(SIG_OBJ + profileID)) {
+ public SignatureProfileSettings(String profileID, ISettings configuration) throws PDFASError {
+
+ if (!configuration.hasPrefix(SIG_OBJ + profileID)) {
throw new PDFASError(ErrorConstants.ERROR_SIG_INVALID_PROFILE,
PDFASError.buildInfoString(ErrorConstants.ERROR_SIG_INVALID_PROFILE,
profileID));
}
-
- this.profileID = profileID;
- String profilePrefix = SIG_OBJ + profileID + KEY_SEPARATOR;
- String keysPrefix = profilePrefix + PROFILE_KEY;
- String valuesPrefix = profilePrefix + PROFILE_VALUE;
- String tablePrefix = profilePrefix + TABLE;
- this.configuration = configuration;
-
- logger.debug("Reading Profile: " + profileID);
- logger.debug("Keys Prefix: " + keysPrefix);
- logger.debug("Values Prefix: " + valuesPrefix);
- logger.debug("Table Prefix: " + tablePrefix);
-
- Map<String, String> keys = configuration.getValuesPrefix(keysPrefix);
- Map<String, String> values = configuration.getValuesPrefix(valuesPrefix);
-
- if (keys != null) {
- Iterator<String> keyIterator = keys.keySet().iterator();
-
- while (keyIterator.hasNext()) {
- String key = keyIterator.next();
- key = key.substring(key.lastIndexOf('.') + 1);
- String valueKey = keys.get(keysPrefix + KEY_SEPARATOR + key);
-
- String valueValue = values.get(valuesPrefix + KEY_SEPARATOR
- + key);
-
- // Lookup default values
- if(valueKey == null) {
- valueKey = DefaultSignatureProfileSettings.getDefaultKeyCaption(key);
- }
-
- if(valueValue == null) {
- valueValue = DefaultSignatureProfileSettings.getDefaultKeyValue(key);
- }
-
- SignatureProfileEntry entry = new SignatureProfileEntry();
- entry.setKey(key);
- entry.setCaption(valueKey);
- entry.setValue(valueValue);
- profileInformations.put(key, entry);
- logger.debug(" " + entry.toString());
- }
- }
-
- if (values != null) {
- // Find entries where only values exists
- Iterator<String> valuesIterator = values.keySet().iterator();
-
- while (valuesIterator.hasNext()) {
- String key = valuesIterator.next();
- key = key.substring(key.lastIndexOf('.') + 1);
-
- String valueValue = values.get(valuesPrefix + KEY_SEPARATOR
- + key);
-
- // Lookup default values
- if(valueValue == null) {
- valueValue = DefaultSignatureProfileSettings.getDefaultKeyValue(key);
- }
-
- SignatureProfileEntry entry = profileInformations.get(key);
- if (entry == null) {
- entry = new SignatureProfileEntry();
- entry.setKey(key);
- entry.setCaption(null);
- entry.setValue(valueValue);
- profileInformations.put(key, entry);
- }
-
- logger.debug(" " + entry.toString());
- }
- }
-
- Map<String, String> others = configuration
- .getValuesPrefix(profilePrefix);
-
- if(others != null) {
- Iterator<String> otherIterator = others.keySet().iterator();
-
- while (otherIterator.hasNext()) {
- String key = otherIterator.next();
-
- logger.trace("Checking key " + key);
- if (key.startsWith(keysPrefix) || key.startsWith(valuesPrefix)
- || key.startsWith(tablePrefix)) {
- continue;
- }
-
- String value = others.get(key);
- key = key.substring(key.lastIndexOf('.') + 1);
-
- profileSettings.put(key, value);
-
- logger.debug(" Settings: " + key + " : " + value);
- }
- }
-
- Iterator<SignatureProfileEntry> dumpIterator =
- profileInformations.values().iterator();
-
- logger.debug("Settings for profile {}", profileID);
- while(dumpIterator.hasNext()) {
- SignatureProfileEntry entry = dumpIterator.next();
- logger.debug(" " + entry.toString());
- }
- }
-
- public String getCaption(String key) {
- SignatureProfileEntry entry = profileInformations.get(key);
- if (entry != null) {
- return entry.getCaption();
- }
- return null;
- }
-
- protected String getDefaultValue(String key) {
- String profilePrefix = SIG_OBJ + profileID + KEY_SEPARATOR;
- logger.debug("Searching default value for: " + key);
- if (key.startsWith(profilePrefix)) {
- key = key.substring(profilePrefix.length());
- }
- key = "default." + key;
- logger.debug("Searching default value for: " + key);
- return this.configuration.getValue(key);
- }
-
- public String getValue(String key) {
- logger.debug("Searching: " + key);
- SignatureProfileEntry entry = profileInformations.get(key);
- if (entry != null) {
- String value = entry.getValue();
-
- if (value == null) {
- return getDefaultValue(key);
- }
-
- return value;
- }
- String v = profileSettings.get(key);
- if (v != null) {
- return v;
- }
- return getDefaultValue(key);
- }
-
- public String getProfileID() {
- return profileID;
- }
-
- public String getSigningReason() {
- return this.getValue(SIGNING_REASON);
- }
-
- public String getSignFieldValue() {
- return this.getValue(SIGNFIELD_VALUE);
- }
-
- public String getProfileTimeZone() {
- return this.getValue(TIMEZONE_BASE);
- }
-
- public void setPDFAVersion(String version) {
- this.pdfAVersion = version;
- }
-
- public boolean isPDFA() {
-
- if(this.pdfAVersion != null) {
- return "1".equals(this.pdfAVersion);
- }
-
- SignatureProfileEntry entry = profileInformations.get(SIG_PDFA_VALID);
- if (entry != null) {
- String value = entry.getCaption();
- return "true".equals(value);
- }
-
- entry = profileInformations.get(SIG_PDFA1B_VALID);
- if (entry != null) {
- String value = entry.getCaption();
- return "true".equals(value);
- }
- return false;
- }
-
- public boolean isPDFUA() {
- SignatureProfileEntry entry = profileInformations.get(SIG_PDFUA_FORCE);
- if (entry != null) {
- String value = entry.getCaption();
- return "true".equals(value);
- }
- return false;
- }
-
-
- public boolean isLatin1Encoding() {
- SignatureProfileEntry entry = profileInformations.get(LATIN1_ENCODING);
- if (entry != null) {
- String value = entry.getCaption();
- return "true".equals(value);
- }
- return false;
- }
-
- public boolean isPDFA3() {
- if(this.pdfAVersion != null) {
- return "3".equals(this.pdfAVersion);
- }
-
- SignatureProfileEntry entry = profileInformations.get(SIG_PDFA_VALID);
- if (entry != null) {
- String value = entry.getCaption();
- return "true".equals(value);
- }
- return false;
- }
+
+ this.profileID = profileID;
+ final String profilePrefix = SIG_OBJ + profileID + KEY_SEPARATOR;
+ final String keysPrefix = profilePrefix + PROFILE_KEY;
+ final String valuesPrefix = profilePrefix + PROFILE_VALUE;
+ final String tablePrefix = profilePrefix + TABLE;
+ this.configuration = configuration;
+
+ logger.debug("Reading Profile: " + profileID);
+ logger.debug("Keys Prefix: " + keysPrefix);
+ logger.debug("Values Prefix: " + valuesPrefix);
+ logger.debug("Table Prefix: " + tablePrefix);
+
+ final Map<String, String> keys = configuration.getValuesPrefix(keysPrefix);
+ final Map<String, String> values = configuration.getValuesPrefix(valuesPrefix);
+
+ for (String key : keys.keySet()) {
+ key = key.substring(key.lastIndexOf('.') + 1);
+ String valueKey = keys.get(keysPrefix + KEY_SEPARATOR + key);
+
+ String valueValue = values.get(valuesPrefix + KEY_SEPARATOR
+ + key);
+
+ // Lookup default values
+ if (valueKey == null) {
+ valueKey = DefaultSignatureProfileSettings.getDefaultKeyCaption(key);
+ }
+
+ if (valueValue == null) {
+ valueValue = DefaultSignatureProfileSettings.getDefaultKeyValue(key);
+ }
+
+ final SignatureProfileEntry entry = new SignatureProfileEntry();
+ entry.setKey(key);
+ entry.setCaption(valueKey);
+ entry.setValue(valueValue);
+ profileInformations.put(key, entry);
+ logger.debug(" " + entry.toString());
+ }
+
+ for (String key : values.keySet()) {
+ key = key.substring(key.lastIndexOf('.') + 1);
+
+ String valueValue = values.get(valuesPrefix + KEY_SEPARATOR
+ + key);
+
+ // Lookup default values
+ if (valueValue == null) {
+ valueValue = DefaultSignatureProfileSettings.getDefaultKeyValue(key);
+ }
+
+ SignatureProfileEntry entry = profileInformations.get(key);
+ if (entry == null) {
+ entry = new SignatureProfileEntry();
+ entry.setKey(key);
+ entry.setCaption(null);
+ entry.setValue(valueValue);
+ profileInformations.put(key, entry);
+ }
+
+ logger.debug(" " + entry.toString());
+ }
+
+ final Map<String, String> others = configuration
+ .getValuesPrefix(profilePrefix);
+
+ if (others != null) {
+ for (String key : others.keySet()) {
+ logger.trace("Checking key " + key);
+ if (key.startsWith(keysPrefix) || key.startsWith(valuesPrefix)
+ || key.startsWith(tablePrefix)) {
+ continue;
+ }
+
+ final String value = others.get(key);
+ key = key.substring(key.lastIndexOf('.') + 1);
+
+ profileSettings.put(key, value);
+
+ logger.debug(" Settings: " + key + " : " + value);
+ }
+ }
+
+ logger.debug("Settings for profile {}", profileID);
+ for (final SignatureProfileEntry entry : profileInformations.values()) {
+ logger.debug(" " + entry.toString());
+ }
+ }
+
+ public String getCaption(String key) {
+ final SignatureProfileEntry entry = profileInformations.get(key);
+ if (entry != null) {
+ return entry.getCaption();
+ }
+ return null;
+ }
+
+ protected String getDefaultValue(String key) {
+ final String profilePrefix = SIG_OBJ + profileID + KEY_SEPARATOR;
+ logger.debug("Searching default value for: " + key);
+ if (key.startsWith(profilePrefix)) {
+ key = key.substring(profilePrefix.length());
+ }
+ key = "default." + key;
+ logger.debug("Searching default value for: " + key);
+ return this.configuration.getValue(key);
+ }
+
+ public String getValue(String key) {
+ logger.debug("Searching: " + key);
+ final SignatureProfileEntry entry = profileInformations.get(key);
+ if (entry != null) {
+ final String value = entry.getValue();
+
+ if (value == null) {
+ return getDefaultValue(key);
+ }
+
+ return value;
+ }
+ final String v = profileSettings.get(key);
+ if (v != null) {
+ return v;
+ }
+ return getDefaultValue(key);
+ }
+
+ public String getProfileID() {
+ return profileID;
+ }
+
+ public String getSigningReason() {
+ return this.getValue(SIGNING_REASON);
+ }
+
+ public String getSignFieldValue() {
+ return this.getValue(SIGNFIELD_VALUE);
+ }
+
+ public String getProfileTimeZone() {
+ return this.getValue(TIMEZONE_BASE);
+ }
+
+ public void setPDFAVersion(String version) {
+ this.pdfAVersion = version;
+ }
+
+ public boolean isPDFA() {
+
+ if (this.pdfAVersion != null) {
+ return "1".equals(this.pdfAVersion);
+ }
+
+ SignatureProfileEntry entry = profileInformations.get(SIG_PDFA_VALID);
+ if (entry != null) {
+ final String value = entry.getCaption();
+ return "true".equals(value);
+ }
+
+ entry = profileInformations.get(SIG_PDFA1B_VALID);
+ if (entry != null) {
+ final String value = entry.getCaption();
+ return "true".equals(value);
+ }
+ return false;
+ }
+
+ public boolean isPDFUA() {
+ final SignatureProfileEntry entry = profileInformations.get(SIG_PDFUA_FORCE);
+ if (entry != null) {
+ final String value = entry.getCaption();
+ return "true".equals(value);
+ }
+ return false;
+ }
+
+ public boolean isLatin1Encoding() {
+ final SignatureProfileEntry entry = profileInformations.get(LATIN1_ENCODING);
+ if (entry != null) {
+ final String value = entry.getCaption();
+ return "true".equals(value);
+ }
+ return false;
+ }
+
+ public boolean isPDFA3() {
+ if (this.pdfAVersion != null) {
+ return "3".equals(this.pdfAVersion);
+ }
+
+ final SignatureProfileEntry entry = profileInformations.get(SIG_PDFA_VALID);
+ if (entry != null) {
+ final String value = entry.getCaption();
+ return "true".equals(value);
+ }
+ return false;
+ }
}
diff --git a/pdf-as-common/src/main/resources/resources/messages/common.properties b/pdf-as-common/src/main/resources/resources/messages/common.properties
index d8695619..f3baebad 100644
--- a/pdf-as-common/src/main/resources/resources/messages/common.properties
+++ b/pdf-as-common/src/main/resources/resources/messages/common.properties
@@ -1,3 +1,6 @@
+# Configuration errors
+error.config.sl20.01=Signing of SL2.0 messages are enabled, but not Keystore available
+
# PDF Permission Errors
error.pdf.perm.01=You do not have permission to extract images
diff --git a/pdf-as-common/src/main/resources/resources/messages/error.properties b/pdf-as-common/src/main/resources/resources/messages/error.properties
index 4f67fff6..dd873f1e 100644
--- a/pdf-as-common/src/main/resources/resources/messages/error.properties
+++ b/pdf-as-common/src/main/resources/resources/messages/error.properties
@@ -21,6 +21,8 @@
11017=Failed to retrieve certificate
11018=Given Alias contains no private key
11019=Signature was created for wrong certificate
+11020=Failed to process PDF document. Reason: {0}
+11021=Signer certificate is not valid, because notBefore or notAfter does not match
13001=Invalid Configuration Objects
13002=Given certificate is invalid
diff --git a/pdf-as-common/src/test/java/at/gv/egiz/pdfas/common/test/utils/CheckSignatureParametersTest.java b/pdf-as-common/src/test/java/at/gv/egiz/pdfas/common/test/utils/CheckSignatureParametersTest.java
new file mode 100644
index 00000000..5ec0541b
--- /dev/null
+++ b/pdf-as-common/src/test/java/at/gv/egiz/pdfas/common/test/utils/CheckSignatureParametersTest.java
@@ -0,0 +1,48 @@
+package at.gv.egiz.pdfas.common.test.utils;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+import at.gv.egiz.pdfas.common.settings.DefaultSignatureProfileSettings;
+import at.gv.egiz.pdfas.common.utils.CheckSignatureBlockParameters;
+
+@RunWith(BlockJUnit4ClassRunner.class)
+public class CheckSignatureParametersTest {
+
+ @Test
+ public void singleTest() {
+ assertTrue("valid characters are not possilbe",
+ CheckSignatureBlockParameters.isValid("Güssing",
+ DefaultSignatureProfileSettings.SIG_BLOCK_PARAMETER_DEFAULT_VALUE_REGEX));
+
+ }
+
+ @Test
+ public void specialCharactersCompiletimeConfig() {
+ Map<String, String> toTest = new HashMap<>();
+ toTest.put("test", "Güssing");
+
+ assertTrue("valid characters are not possilbe",
+ CheckSignatureBlockParameters.checkSignatureBlockParameterMapIsValid(toTest , null, null));
+
+ }
+
+ @Test
+ public void specialCharactersExampleConfig() {
+ Map<String, String> toTest = new HashMap<>();
+ toTest.put("test", "Güssing");
+
+ assertFalse("valid characters are not possilbe",
+ CheckSignatureBlockParameters.checkSignatureBlockParameterMapIsValid(toTest ,
+ "^([A-za-z]){1,20}$", "^([\\p{Print}]){1,100}$"));
+
+ }
+
+}
diff --git a/pdf-as-legacy/src/main/java/at/gv/egiz/pdfas/api/commons/DynamicSignatureProfileImpl.java b/pdf-as-legacy/src/main/java/at/gv/egiz/pdfas/api/commons/DynamicSignatureProfileImpl.java
index cc51d5e4..ce36fb9f 100644
--- a/pdf-as-legacy/src/main/java/at/gv/egiz/pdfas/api/commons/DynamicSignatureProfileImpl.java
+++ b/pdf-as-legacy/src/main/java/at/gv/egiz/pdfas/api/commons/DynamicSignatureProfileImpl.java
@@ -186,19 +186,7 @@ public class DynamicSignatureProfileImpl implements DynamicSignatureProfile {
cfg = (ISettings)configuration;
String parentKey = "sig_obj." + parentProfile + ".";
- Map<String, String> properties = cfg.getValuesPrefix(parentKey);
- //Properties props = cfg.getProperties();
- // DTI: props.keys() does not support default properties, therefore we should better use props.propertyNames()
-// for (Enumeration e = props.keys(); e.hasMoreElements();) {
- /*for (Enumeration e = props.propertyNames(); e.hasMoreElements();) {
- String oldKey = (String) e.nextElement();
- if (oldKey.startsWith("sig_obj." + parentProfile + ".")) {
- String newKey = StringUtils.replace(oldKey, parentProfile, name);
- String val = props.getProperty(oldKey);
- this.newProps.put(newKey, val);
- }
- }*/
-
+ Map<String, String> properties = cfg.getValuesPrefix(parentKey);
Iterator<String> keyIt = properties.keySet().iterator();
while(keyIt.hasNext()) {
diff --git a/pdf-as-lib/build.gradle b/pdf-as-lib/build.gradle
index e63dfe2d..67e4b6ac 100644
--- a/pdf-as-lib/build.gradle
+++ b/pdf-as-lib/build.gradle
@@ -69,7 +69,7 @@ dependencies {
api group: 'javax.activation', name: 'activation', version: '1.1.1'
api group: 'javax.xml.bind', name: 'jaxb-api', version: '2.3.1'
api group: 'com.google.code.gson', name: 'gson', version: '2.10.1'
- api group: 'org.bitbucket.b_c', name: 'jose4j', version: '0.9.2'
+ api group: 'org.bitbucket.b_c', name: 'jose4j', version: '0.9.3'
api group: 'commons-io', name: 'commons-io', version: '2.11.0'
api group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '2.3.3'
api 'org.apache.commons:commons-collections4:4.4'
@@ -80,8 +80,8 @@ dependencies {
api files('libs/iaik_cms-5.1.1.jar')
api group: 'org.slf4j', name: 'slf4j-api', version: slf4jVersion
api group: 'org.slf4j', name: 'jcl-over-slf4j', version: slf4jVersion
- api group: 'com.google.zxing', name: 'core', version: '3.4.1'
- api group: 'com.google.zxing', name: 'javase', version: '3.4.1'
+ api group: 'com.google.zxing', name: 'core', version: '3.5.0'
+ api group: 'com.google.zxing', name: 'javase', version: '3.5.0'
ws group: 'org.apache.cxf', name: 'cxf-tools', version: cxfVersion
ws group: 'org.apache.cxf', name: 'cxf-tools-wsdlto-databinding-jaxb', version: cxfVersion
diff --git a/pdf-as-lib/src/configuration/cfg/advancedconfig.properties b/pdf-as-lib/src/configuration/cfg/advancedconfig.properties
index 7eb1ec37..d00f2872 100644
--- a/pdf-as-lib/src/configuration/cfg/advancedconfig.properties
+++ b/pdf-as-lib/src/configuration/cfg/advancedconfig.properties
@@ -41,6 +41,8 @@
# MATCH_MODE_SORTED = 3
#placeholder_mode=
+# Allow profile over-write from placeholder content [true|false], default=true
+#placeholder_profile_overwrite=true
### stop processing it signature-block can not valid placed on document
sigblock.placement.less.space.failing=false
diff --git a/pdf-as-lib/src/configuration/cfg/log4j.properties b/pdf-as-lib/src/configuration/cfg/log4j.properties
deleted file mode 100644
index 9cc9f155..00000000
--- a/pdf-as-lib/src/configuration/cfg/log4j.properties
+++ /dev/null
@@ -1,23 +0,0 @@
-log4j.rootLogger = INFO, CONSOLE
-#, ROLLINGFILE
-
-# DETAIL LEVELS
-log4j.logger.at.gv.egiz = INFO
-log4j.logger.at.knowcenter = INFO
-# Statistical logger
-#log4j.logger.statistic = INFO, STATISTIC
-
-# CONSOLE
-log4j.appender.CONSOLE = org.apache.log4j.ConsoleAppender
-log4j.appender.CONSOLE.layout = org.apache.log4j.PatternLayout
-log4j.appender.CONSOLE.layout.ConversionPattern = %-4r [%t] %-5p %c %x - %m%n
-log4j.appender.CONSOLE.threshold = DEBUG
-log4j.appender.CONSOLE.Target = System.out
-
-# ROLLINGFILE
-#log4j.appender.ROLLINGFILE = org.apache.log4j.RollingFileAppender
-#log4j.appender.ROLLINGFILE.File = ${catalina.base}/logs/pdf-as.log
-#log4j.appender.ROLLINGFILE.MaxFileSize = 10240KB
-#log4j.appender.ROLLINGFILE.MaxBackupIndex = 1
-#log4j.appender.ROLLINGFILE.layout = org.apache.log4j.PatternLayout
-#log4j.appender.ROLLINGFILE.layout.ConversionPattern = [%-5p@%d{dd.MM.yyyy HH:mm:ss}] %c:%M:%L - %m%n
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/IConfigurationConstants.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/IConfigurationConstants.java
index 21a8e3b9..d031e2f7 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/IConfigurationConstants.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/IConfigurationConstants.java
@@ -45,9 +45,13 @@ public interface IConfigurationConstants {
public static final String LEGACY_40_POSITIONING = ".legacy40.pos";
public static final String MIN_WIDTH = "minWidth";
- public static final String PLACEHOLDER_WEB_ID = "placeholder_web_id";
public static final String PLACEHOLDER_ID = "placeholder_id";
public static final String PLACEHOLDER_MODE = "placeholder_mode";
+ public static final String PLACEHOLDER_PROFILE_OVERWRITE = "placeholder_profile_overwrite";
+
+
+ public static final String PLACEHOLDER_WEB_ID = "placeholder_web_id";
+ public static final String PLACEHOLDER_WEB_ENABLED = "placeholder_web_enabled";
public static final String PLACEHOLDER_SEARCH_ENABLED = "enable_placeholder_search";
public static final String DEFAULT_SIGNATURE_PROFILE = SIG_OBJECT + SEPERATOR + TYPE + SEPERATOR + DEFAULT;
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/SignParameter.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/SignParameter.java
index 6a7ccf24..e123d453 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/SignParameter.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/api/sign/SignParameter.java
@@ -54,6 +54,39 @@ public interface SignParameter extends PdfAsParameter {
*/
public void setSignaturePosition(String signaturePosition);
+
+ /**
+ * Get Id of a placeholder that should be used for positioning.
+ *
+ * @return Id of a placeholder
+ */
+ String getPlaceHolderId();
+
+
+ /**
+ * Set Id of a placeholder that should be used for positioning.
+ *
+ * @param id Id of a placeholder
+ */
+ void setPlaceHolderId(String id);
+
+ /**
+ * Is QR-Code placeholder search enabled for this request.
+ *
+ * @return <code>true</code> if it's enabled, otherwise <code>false</code>
+ */
+ boolean isPlaceHolderSearchEnabled();
+
+
+ /**
+ * Enable / disable QR-Code placeholder search on request level.
+ *
+ * <p>Default value is <code>true</code></p>
+ *
+ * @param flag <code>true</code> to enable, <code>false</code> to disable
+ */
+ void setPlaceHolderSearchEnabled(boolean flag);
+
/**
* Sets the signer to use
*
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/ErrorExtractor.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/ErrorExtractor.java
index 9b2a8d79..bcf04611 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/ErrorExtractor.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/ErrorExtractor.java
@@ -5,6 +5,7 @@ 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.common.exceptions.PdfAsException;
import at.gv.egiz.pdfas.common.exceptions.PdfAsMOAException;
import at.gv.egiz.pdfas.common.exceptions.SLPdfAsException;
import at.gv.egiz.pdfas.lib.impl.status.OperationStatus;
@@ -42,6 +43,10 @@ public class ErrorExtractor implements ErrorConstants {
} else {
return new PDFASError(code, e);
}
+
+ } else if(e instanceof PdfAsException) {
+ return new PDFASError(11020, e.getMessage(), e);
+
}
// TODO: Handle more exceptions
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java
index 47e46bcf..ebd8ec90 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java
@@ -27,6 +27,7 @@ import java.awt.Image;
import java.io.File;
import java.io.IOException;
import java.util.Calendar;
+import java.util.Date;
import java.util.Iterator;
import java.util.List;
@@ -165,8 +166,9 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants,
status.setRequestedSignature(requestedSignature);
- try {
- requestedSignature.setCertificate(status.getSignParamter().getPlainSigner().getCertificate(parameter));
+ try {
+ requestedSignature.setCertificate(getValidCertificate(
+ status.getSignParamter().getPlainSigner().getCertificate(parameter)));
} finally {
if (parameter instanceof BKUHeaderHolder) {
@@ -208,9 +210,10 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants,
// Create signature
try {
- signer.signPDF(status.getPdfObject(), requestedSignature, signer
- .buildSignaturInterface(status.getSignParamter()
- .getPlainSigner(), parameter, requestedSignature));
+ signer.signPDF(status.getPdfObject(), requestedSignature,
+ signer.buildSignaturInterface(status.getSignParamter().getPlainSigner(),
+ parameter, requestedSignature));
+
} finally {
if (parameter instanceof BKUHeaderHolder) {
final BKUHeaderHolder holder = (BKUHeaderHolder) parameter;
@@ -266,6 +269,22 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants,
}
}
+ private X509Certificate getValidCertificate(X509Certificate certificate) throws PDFASError {
+ Date notAfter = certificate.getNotAfter();
+ Date notBefore = certificate.getNotBefore();
+ Date now = new Date();
+
+ if (now.after(notAfter) || now.before(notBefore)) {
+ logger.warn("Signer certificate is not valid. notBefore:{} | notAfter:{} | now:{}",
+ notBefore, notAfter, now);
+ throw new PDFASError(11021);
+
+ } else {
+ return certificate;
+
+ }
+ }
+
@Override
public List<VerifyResult> verify(VerifyParameter parameter)
throws PDFASError {
@@ -400,6 +419,7 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants,
} catch (final Throwable e) {
logger.warn("process", e);
throw ErrorExtractor.searchPdfAsError(e, status);
+
}
} else if (request.needSignature()) {
request.setNeedSignature(false);
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/SignParameterImpl.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/SignParameterImpl.java
index d2786f53..06b1b34f 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/SignParameterImpl.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/SignParameterImpl.java
@@ -25,9 +25,7 @@ package at.gv.egiz.pdfas.lib.impl;
import java.io.OutputStream;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import javax.activation.DataSource;
@@ -35,10 +33,21 @@ import at.gv.egiz.pdfas.lib.api.Configuration;
import at.gv.egiz.pdfas.lib.api.sign.IPlainSigner;
import at.gv.egiz.pdfas.lib.api.sign.SignParameter;
import at.gv.egiz.sl.util.BKUHeader;
+import lombok.Getter;
+import lombok.Setter;
public class SignParameterImpl extends PdfAsParameterImpl implements SignParameter, BKUHeaderHolder {
protected String signatureProfileId = null;
protected String signaturePosition = null;
+
+ @Getter
+ @Setter
+ protected String placeHolderId;
+
+ @Getter
+ @Setter
+ protected boolean placeHolderSearchEnabled;
+
protected DataSource output = null;
protected IPlainSigner signer = null;
protected OutputStream outputStream = null;
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/ConfigurationImpl.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/ConfigurationImpl.java
index bfc05c85..8c841301 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/ConfigurationImpl.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/ConfigurationImpl.java
@@ -3,19 +3,19 @@
* 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
@@ -23,147 +23,166 @@
******************************************************************************/
package at.gv.egiz.pdfas.lib.impl.configuration;
-import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Vector;
+import org.apache.commons.lang3.StringUtils;
+
import at.gv.egiz.pdfas.common.settings.ISettings;
import at.gv.egiz.pdfas.lib.api.Configuration;
import at.gv.egiz.pdfas.lib.settings.Settings;
public class ConfigurationImpl implements ISettings, Configuration {
- protected Properties overwrittenProperties = new Properties();
-
- protected ISettings settings;
-
- public ConfigurationImpl(ISettings settings) {
- this.settings = settings;
- }
-
- public void setValue(String key, String value) {
- overwrittenProperties.setProperty(key, value);
- }
-
- public String getValue(String key) {
- if(overwrittenProperties.containsKey(key)) {
- return overwrittenProperties.getProperty(key);
- } else {
- return this.settings.getValue(key);
- }
- }
-
- public boolean hasValue(String key) {
- if(overwrittenProperties.containsKey(key)) {
- return true;
- } else {
- return this.settings.hasValue(key);
- }
- }
-
- public Map<String, String> getValuesPrefix(String prefix) {
-
- Map<String, String> valueMap = null;
- valueMap = this.settings.getValuesPrefix(prefix);
- if(valueMap == null) {
- valueMap = new HashMap<String, String>();
- }
-
- Iterator<Object> keyIterator = overwrittenProperties.keySet().iterator();
+ protected Properties overwrittenProperties = new Properties();
+
+ protected ISettings settings;
+
+ public ConfigurationImpl(ISettings settings) {
+ this.settings = settings;
+ }
+
+ @Override
+ public void setValue(String key, String value) {
+ overwrittenProperties.setProperty(key, value);
+ }
+
+ @Override
+ public String getValue(String key) {
+ if (overwrittenProperties.containsKey(key)) {
+ return overwrittenProperties.getProperty(key);
+ } else {
+ return this.settings.getValue(key);
+ }
+ }
+
+ @Override
+ public boolean isValue(String key) {
+ return isValue(key, false);
+ }
+
+ @Override
+ public boolean isValue(String key, boolean defaultValue) {
+ if (overwrittenProperties.containsKey(key)) {
+ String value = overwrittenProperties.getProperty(key);
+ if (StringUtils.isNotEmpty(value)) {
+ return Boolean.valueOf(value);
- while(keyIterator.hasNext()) {
- String key = keyIterator.next().toString();
-
- if(key.startsWith(prefix)) {
- valueMap.put(key, overwrittenProperties.getProperty(key));
- }
- }
-
- if(valueMap.isEmpty()) {
- return null;
- }
-
- return valueMap;
- }
-
- public Vector<String> getFirstLevelKeys(String prefix) {
-
- Vector<String> valueMap = this.settings.getFirstLevelKeys(prefix);
- if(valueMap == null) {
- valueMap = new Vector<String>();
- }
-
-
- String mPrefix = prefix.endsWith(".")?prefix:prefix+".";
- Iterator<Object> keyIterator = overwrittenProperties.keySet().iterator();
+ } else {
+ return defaultValue;
- while(keyIterator.hasNext()) {
- String key = keyIterator.next().toString();
-
- if(key.startsWith(prefix)) {
- int keyIdx = key.indexOf('.', mPrefix.length()) > 0 ? key.indexOf('.', mPrefix.length()) : key.length();
- String firstLevels = key.substring(0, keyIdx);
- if(!valueMap.contains(firstLevels)) {
- valueMap.add(firstLevels);
- }
- }
- }
-
- if(valueMap.isEmpty()) {
- return null;
- }
-
- return valueMap;
- }
-
- public boolean hasPrefix(String prefix) {
-
- if(this.settings.hasPrefix(prefix)) {
- return true;
- }
-
- Iterator<Object> keyIterator = overwrittenProperties.keySet().iterator();
- while(keyIterator.hasNext()) {
- String key = keyIterator.next().toString();
-
- if(key.startsWith(prefix)) {
- return true;
- }
- }
- return false;
- }
-
- public String getWorkingDirectory() {
- return this.settings.getWorkingDirectory();
- }
-
- public void cloneProfile(String originalPrefix, String clonedPrefix) {
- Map<String, String> source = getValuesPrefix(originalPrefix);
-
- Iterator<String> keyIt = source.keySet().iterator();
-
- while(keyIt.hasNext()) {
- String origKey = keyIt.next();
- String cloneKey = origKey.replace(originalPrefix, clonedPrefix);
- this.overwrittenProperties.setProperty(cloneKey, source.get(origKey));
- }
- }
-
- public void removeProfile(String configurationPrefix) {
- Iterator<Object> keyIterator = overwrittenProperties.keySet().iterator();
- while(keyIterator.hasNext()) {
- String key = keyIterator.next().toString();
-
- if(key.startsWith(configurationPrefix)) {
- overwrittenProperties.remove(key);
- }
+ }
+ } else {
+ return this.settings.isValue(key, defaultValue);
+
+ }
+ }
+
+ @Override
+ public boolean hasValue(String key) {
+ if (overwrittenProperties.containsKey(key)) {
+ return true;
+ } else {
+ return this.settings.hasValue(key);
+ }
+ }
+
+ @Override
+ public Map<String, String> getValuesPrefix(String prefix) {
+ final Map<String, String> valueMap = this.settings.getValuesPrefix(prefix);
+ final Iterator<Object> keyIterator = overwrittenProperties.keySet().iterator();
+
+ while (keyIterator.hasNext()) {
+ final String key = keyIterator.next().toString();
+
+ if (key.startsWith(prefix)) {
+ valueMap.put(key, overwrittenProperties.getProperty(key));
+ }
+ }
+
+ return valueMap;
+ }
+
+ @Override
+ public Vector<String> getFirstLevelKeys(String prefix) {
+
+ Vector<String> valueMap = this.settings.getFirstLevelKeys(prefix);
+ if (valueMap == null) {
+ valueMap = new Vector<>();
+ }
+
+ final String mPrefix = prefix.endsWith(".") ? prefix : prefix + ".";
+ final Iterator<Object> keyIterator = overwrittenProperties.keySet().iterator();
+
+ while (keyIterator.hasNext()) {
+ final String key = keyIterator.next().toString();
+
+ if (key.startsWith(prefix)) {
+ final int keyIdx = key.indexOf('.', mPrefix.length()) > 0 ? key.indexOf('.', mPrefix.length())
+ : key.length();
+ final String firstLevels = key.substring(0, keyIdx);
+ if (!valueMap.contains(firstLevels)) {
+ valueMap.add(firstLevels);
}
- }
+ }
+ }
+
+ if (valueMap.isEmpty()) {
+ return null;
+ }
+
+ return valueMap;
+ }
+
+ @Override
+ public boolean hasPrefix(String prefix) {
+
+ if (this.settings.hasPrefix(prefix)) {
+ return true;
+ }
+
+ final Iterator<Object> keyIterator = overwrittenProperties.keySet().iterator();
+ while (keyIterator.hasNext()) {
+ final String key = keyIterator.next().toString();
+
+ if (key.startsWith(prefix)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public String getWorkingDirectory() {
+ return this.settings.getWorkingDirectory();
+ }
+
+ @Override
+ public void cloneProfile(String originalPrefix, String clonedPrefix) {
+ final Map<String, String> source = getValuesPrefix(originalPrefix);
+
+ for (final String origKey : source.keySet()) {
+ final String cloneKey = origKey.replace(originalPrefix, clonedPrefix);
+ this.overwrittenProperties.setProperty(cloneKey, source.get(origKey));
+ }
+ }
+
+ @Override
+ public void removeProfile(String configurationPrefix) {
+ final Iterator<Object> keyIterator = overwrittenProperties.keySet().iterator();
+ while (keyIterator.hasNext()) {
+ final String key = keyIterator.next().toString();
+
+ if (key.startsWith(configurationPrefix)) {
+ overwrittenProperties.remove(key);
+ }
+ }
+ }
+
+ public void debugDumpProfileSettings(String profileName) {
+ ((Settings) settings).debugDumpProfileSettings(profileName);
+ }
- public void debugDumpProfileSettings(String profileName) {
- ((Settings)settings).debugDumpProfileSettings(profileName);
- }
-
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/PlaceholderConfiguration.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/PlaceholderConfiguration.java
index 326ed142..a3719168 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/PlaceholderConfiguration.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/PlaceholderConfiguration.java
@@ -3,19 +3,19 @@
* 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
@@ -25,60 +25,57 @@ package at.gv.egiz.pdfas.lib.impl.configuration;
import at.gv.egiz.pdfas.common.settings.ISettings;
import at.gv.egiz.pdfas.lib.api.IConfigurationConstants;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import lombok.extern.slf4j.Slf4j;
-import java.util.Map;
+@Slf4j
+public class PlaceholderConfiguration extends SpecificBaseConfiguration
+ implements IConfigurationConstants {
+ public PlaceholderConfiguration(ISettings configuration) {
+ super(configuration);
+ }
-public class PlaceholderConfiguration extends SpecificBaseConfiguration
- implements IConfigurationConstants {
+ public boolean isGlobalPlaceholderEnabled() {
+ if (configuration.hasValue(PLACEHOLDER_SEARCH_ENABLED)) {
+ final String value = configuration.getValue(PLACEHOLDER_SEARCH_ENABLED);
+ if (value.equalsIgnoreCase(TRUE)) {
+ return true;
+ }
+ }
+ return false;
+ }
- private static final Logger logger = LoggerFactory.getLogger(PlaceholderConfiguration.class);
+ /**
+ * Match selected Profile for Placeholder Enables to activate placeholder
+ * search/match for different profiles
+ *
+ * @return
+ */
+ public boolean isProfileConfigurationEnabled(String profileID) {
+ log.trace("Check if placeHolders are enabled for profile: {}", profileID);
+
+ final String profileMatch = SIG_OBJECT + SEPERATOR + profileID + SEPERATOR
+ + PLACEHOLDER_SEARCH_ENABLED;
+ final String value = configuration.getValue(profileMatch);
+ if (TRUE.equalsIgnoreCase(value)) {
+ log.debug("Placeholders enabled for profile: {} ", profileID);
+ return true;
+
+ }
+ return false;
+
+ }
- public PlaceholderConfiguration(ISettings configuration) {
- super(configuration);
- }
+ /**
+ * Get placeholderId for a specific profile.
+ *
+ * @param selectedProfileID ProfileName
+ * @return Placeholder Id
+ */
+ public String getProfilePlaceholderID(String selectedProfileID) {
+ log.info("SelectedProfileID in ProfileConfEnabled: " + selectedProfileID);
+ final String profileMatch = SIG_OBJECT + SEPERATOR + selectedProfileID + SEPERATOR + PLACEHOLDER_ID;
+ return configuration.getValue(profileMatch);
- public boolean isGlobalPlaceholderEnabled() {
- if (configuration.hasValue(PLACEHOLDER_SEARCH_ENABLED)) {
- String value = configuration.getValue(PLACEHOLDER_SEARCH_ENABLED);
- if (value.equalsIgnoreCase(TRUE)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Match selected Profile for Placeholder
- * Enables to activate placeholder search/match for different profiles
- * @return
- */
- public boolean isProfileConfigurationEnabled(String selectedProfileID)
- {
- logger.info("SelectedProfileID in ProfileConfEnabled: "+selectedProfileID);
- String profileMatch = SIG_OBJECT+SEPERATOR+selectedProfileID+SEPERATOR+PLACEHOLDER_SEARCH_ENABLED;
- if (configuration.getValuesPrefix(profileMatch)!=null) {
- Map<String, String> map = configuration.getValuesPrefix(profileMatch);
- String value = map.get(profileMatch);
- if (value.equalsIgnoreCase(TRUE)) {
- logger.info("Configuration has Value: "+value);
- return true;
- }
- }
- return false;
- }
-
- public String getProfilePlaceholderID(String selectedProfileID)
- {
- logger.info("SelectedProfileID in ProfileConfEnabled: "+selectedProfileID);
- String profileMatch = SIG_OBJECT+SEPERATOR+selectedProfileID+SEPERATOR+PLACEHOLDER_ID;
- if (configuration.getValuesPrefix(profileMatch)!=null) {
- Map<String, String> map = configuration.getValuesPrefix(profileMatch);
- return map.get(profileMatch);
- }
- return null;
- }
+ }
}
-
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/PlaceholderWebConfiguration.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/PlaceholderWebConfiguration.java
deleted file mode 100644
index 3a78f24f..00000000
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/configuration/PlaceholderWebConfiguration.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package at.gv.egiz.pdfas.lib.impl.configuration;
-
-import java.util.Properties;
-
-public class PlaceholderWebConfiguration {
-
- protected static Properties properties = new Properties();
-
- //todo properties not cleaned
- public static void setValue(String key, String value)
- {
- properties.clear();
- properties.setProperty(key,value);
- }
- public static String getValue(String key)
- {
- return properties.getProperty(key);
- }
-
- public static void clear () {
- properties.clear();
- }
-
-}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/PlaceholderExtractor.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/PlaceholderExtractor.java
index 0a55b834..436024cd 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/PlaceholderExtractor.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/PlaceholderExtractor.java
@@ -3,10 +3,7 @@ package at.gv.egiz.pdfas.lib.impl.placeholder;
import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
import at.gv.egiz.pdfas.lib.impl.status.PDFObject;
-import java.util.List;
-
public interface PlaceholderExtractor {
- SignaturePlaceholderData extract(PDFObject doc, String placeholderId, int matchMode) throws PdfAsException;
-
- List<SignaturePlaceholderData> extractList(PDFObject pdfObject, String placeholderID, int placeholderMode) throws PdfAsException;
+ SignaturePlaceholderData extract(PDFObject pdfObject, String placeholderID, int placeholderMode) throws PdfAsException;
+
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/PlaceholderFilter.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/PlaceholderFilter.java
index 99c09295..1615482f 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/PlaceholderFilter.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/PlaceholderFilter.java
@@ -24,145 +24,77 @@
package at.gv.egiz.pdfas.lib.impl.placeholder;
import java.io.IOException;
-import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
import at.gv.egiz.pdfas.common.exceptions.PDFASError;
import at.gv.egiz.pdfas.common.exceptions.PdfAsErrorCarrier;
import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
import at.gv.egiz.pdfas.common.settings.ISettings;
import at.gv.egiz.pdfas.lib.api.IConfigurationConstants;
-import at.gv.egiz.pdfas.lib.impl.configuration.PlaceholderWebConfiguration;
import at.gv.egiz.pdfas.lib.impl.status.OperationStatus;
-import org.apache.commons.lang3.StringUtils;
+import lombok.extern.slf4j.Slf4j;
+@Slf4j
public class PlaceholderFilter implements IConfigurationConstants,
PlaceholderExtractorConstants {
-
+
public static SignaturePlaceholderData checkPlaceholderSignatureLocation(
- OperationStatus status, ISettings settings, String signatureLocation) throws PdfAsException,
- IOException {
-
- String placeholderID;
-
- if (status.getPlaceholderConfiguration().isGlobalPlaceholderEnabled()) {
- PlaceholderExtractor extractor = status.getBackend().getPlaceholderExtractor();
-
- if(StringUtils.isNotEmpty(signatureLocation)) {
- placeholderID = signatureLocation;
- } else {
- placeholderID = PlaceholderWebConfiguration.getValue(PLACEHOLDER_WEB_ID);
- if(StringUtils.isEmpty(placeholderID)) {
- placeholderID = settings.getValue(PLACEHOLDER_ID);
- }
- }
-
- String placeholderModeString = settings.getValue(PLACEHOLDER_MODE);
- int placeholderMode = PLACEHOLDER_MATCH_MODE_MODERATE;
- if (StringUtils.isNotEmpty(placeholderModeString)) {
- try {
- placeholderMode = Integer.parseInt(placeholderModeString);
- if (placeholderMode < PLACEHOLDER_MODE_MIN
- || placeholderMode > PLACEHOLDER_MODE_MAX) {
- throw new PdfAsErrorCarrier(new PDFASError(
- PDFASError.ERROR_INVALID_PLACEHOLDER_MODE));
- }
- } catch (NumberFormatException e) {
- throw new PdfAsErrorCarrier(new PDFASError(
- PDFASError.ERROR_INVALID_PLACEHOLDER_MODE, e));
- }
- }
- SignaturePlaceholderData signaturePlaceholderData = extractor.extract(status.getPdfObject(), placeholderID, placeholderMode);
- return signaturePlaceholderData;
-
- } else if (status.getPlaceholderConfiguration().isProfileConfigurationEnabled(status.getRequestedSignature().getSignatureProfileID())) {
- //filter for local placeholder in selected profiles
- PlaceholderExtractor extractor = status.getBackend().getPlaceholderExtractor();
- int placeholderMode = PLACEHOLDER_MATCH_MODE_SORTED;
-
- placeholderID = status.getPlaceholderConfiguration().getProfilePlaceholderID(status.getRequestedSignature().getSignatureProfileID());
- if(StringUtils.isNotEmpty(placeholderID)) {
- placeholderMode = PLACEHOLDER_MATCH_MODE_MODERATE;
- }
- String placeholderModeString = settings.getValue(PLACEHOLDER_MODE);
- if (StringUtils.isNotEmpty(placeholderModeString)) {
- try {
- placeholderMode = Integer.parseInt(placeholderModeString);
- if (placeholderMode < PLACEHOLDER_MODE_MIN
- || placeholderMode > PLACEHOLDER_MODE_MAX) {
- throw new PdfAsErrorCarrier(new PDFASError(
- PDFASError.ERROR_INVALID_PLACEHOLDER_MODE));
- }
- } catch (NumberFormatException e) {
- throw new PdfAsErrorCarrier(new PDFASError(
- PDFASError.ERROR_INVALID_PLACEHOLDER_MODE, e));
- }
- }
- SignaturePlaceholderData signaturePlaceholderData = extractor.extract(status.getPdfObject(), placeholderID, placeholderMode);
- return signaturePlaceholderData;
- }
+ OperationStatus status, ISettings settings, String placeholderId) throws PdfAsException, IOException {
+
+ String signingProfile = status.getRequestedSignature().getSignatureProfileID();
+
+ if (status.getSignParamter().isPlaceHolderSearchEnabled()) {
+ if (status.getPlaceholderConfiguration().isGlobalPlaceholderEnabled()) {
+ String defaultPlaceHolderId = settings.getValue(PLACEHOLDER_ID);
+ return status.getBackend().getPlaceholderExtractor().extract(
+ status.getPdfObject(), getPlaceHolderId(placeholderId, defaultPlaceHolderId) ,
+ getPlaceHolderMode(settings, PLACEHOLDER_MATCH_MODE_SORTED));
+
+ } else if (status.getPlaceholderConfiguration().isProfileConfigurationEnabled(signingProfile)) {
+ String defaultPlaceHolderId = status.getPlaceholderConfiguration().getProfilePlaceholderID(signingProfile);
+ return status.getBackend().getPlaceholderExtractor().extract(
+ status.getPdfObject(), getPlaceHolderId(placeholderId, defaultPlaceHolderId),
+ getPlaceHolderMode(settings,
+ StringUtils.isNotEmpty(defaultPlaceHolderId) ? PLACEHOLDER_MATCH_MODE_MODERATE : PLACEHOLDER_MATCH_MODE_SORTED));
+ }
+ } else {
+ log.debug("Searching placeholders are disabled for this request");
+
+ }
+
return null;
}
-
- public static List<SignaturePlaceholderData> checkPlaceholderSignatureLocationList(OperationStatus status, ISettings settings, String signatureLocation) throws PdfAsException,
- IOException {
- String placeholderID;
-
- if (status.getPlaceholderConfiguration().isGlobalPlaceholderEnabled()) {
- PlaceholderExtractor extractor = status.getBackend().getPlaceholderExtractor();
-
- if(StringUtils.isNotEmpty(signatureLocation)) {
- placeholderID = signatureLocation;
- } else {
- placeholderID = PlaceholderWebConfiguration.getValue(PLACEHOLDER_WEB_ID);
- if(StringUtils.isEmpty(placeholderID)) {
- placeholderID = settings.getValue(PLACEHOLDER_ID);
- }
- }
-
- String placeholderModeString = settings.getValue(PLACEHOLDER_MODE);
- int placeholderMode = PLACEHOLDER_MATCH_MODE_MODERATE;
- if (StringUtils.isNotEmpty(placeholderModeString)) {
- try {
- placeholderMode = Integer.parseInt(placeholderModeString);
- if (placeholderMode < PLACEHOLDER_MODE_MIN
- || placeholderMode > PLACEHOLDER_MODE_MAX) {
- throw new PdfAsErrorCarrier(new PDFASError(
- PDFASError.ERROR_INVALID_PLACEHOLDER_MODE));
- }
- } catch (NumberFormatException e) {
- throw new PdfAsErrorCarrier(new PDFASError(
- PDFASError.ERROR_INVALID_PLACEHOLDER_MODE, e));
- }
- }
- return extractor.extractList(status.getPdfObject(), placeholderID,
- placeholderMode);
-
- } else if (status.getPlaceholderConfiguration().isProfileConfigurationEnabled(status.getRequestedSignature().getSignatureProfileID())) {
- //filter for local placeholder in selected profiles
- PlaceholderExtractor extractor = status.getBackend().getPlaceholderExtractor();
- int placeholderMode = PLACEHOLDER_MATCH_MODE_SORTED;
-
- placeholderID = status.getPlaceholderConfiguration().getProfilePlaceholderID(status.getRequestedSignature().getSignatureProfileID());
- if(StringUtils.isNotEmpty(placeholderID)) {
- placeholderMode = PLACEHOLDER_MATCH_MODE_MODERATE;
- }
- String placeholderModeString = settings.getValue(PLACEHOLDER_MODE);
- if (StringUtils.isNotEmpty(placeholderModeString)) {
- try {
- placeholderMode = Integer.parseInt(placeholderModeString);
- if (placeholderMode < PLACEHOLDER_MODE_MIN
- || placeholderMode > PLACEHOLDER_MODE_MAX) {
- throw new PdfAsErrorCarrier(new PDFASError(
- PDFASError.ERROR_INVALID_PLACEHOLDER_MODE));
- }
- } catch (NumberFormatException e) {
- throw new PdfAsErrorCarrier(new PDFASError(
- PDFASError.ERROR_INVALID_PLACEHOLDER_MODE, e));
- }
- }
- return extractor.extractList(status.getPdfObject(), placeholderID,
- placeholderMode);
- }
- return null;
+
+ private static int getPlaceHolderMode(ISettings settings, int defaultValue) throws PdfAsErrorCarrier {
+ String placeholderModeString = settings.getValue(PLACEHOLDER_MODE);
+ if (StringUtils.isNotEmpty(placeholderModeString)) {
+ try {
+ int placeholderMode = Integer.parseInt(placeholderModeString);
+ if (placeholderMode < PLACEHOLDER_MODE_MIN || placeholderMode > PLACEHOLDER_MODE_MAX) {
+ throw new PdfAsErrorCarrier(new PDFASError(PDFASError.ERROR_INVALID_PLACEHOLDER_MODE));
+
+ }
+ return placeholderMode;
+
+ } catch (NumberFormatException e) {
+ throw new PdfAsErrorCarrier(new PDFASError(
+ PDFASError.ERROR_INVALID_PLACEHOLDER_MODE, e));
+ }
+
+ } else {
+ return defaultValue;
+
+ }
}
+
+ private static String getPlaceHolderId(String requestId, String defaultValue) {
+ if (StringUtils.isEmpty(requestId)) {
+ return defaultValue;
+
+ } else {
+ return requestId;
+
+ }
+ }
} \ No newline at end of file
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/SignaturePlaceholderContext.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/SignaturePlaceholderContext.java
deleted file mode 100644
index 3c8a6d76..00000000
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/placeholder/SignaturePlaceholderContext.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*******************************************************************************
- * <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.
- ******************************************************************************/
-/**
- * <copyright> Copyright 2006 by Know-Center, 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.lib.impl.placeholder;
-
-/**
- * Store and retrieve {@link SignaturePlaceholderData} in/from a thread local context.
- *
- * @author exthex
- *
- */
-public class SignaturePlaceholderContext {
-
- private ThreadLocal<SignaturePlaceholderData> sigHolder = new ThreadLocal<SignaturePlaceholderData>();
-
- private static SignaturePlaceholderContext instance = new SignaturePlaceholderContext();
-
- /**
- * Constructor. Private because this is a singleton.
- */
- private SignaturePlaceholderContext() {
-
- }
-
- /**
- * Get the {@link SignaturePlaceholderData} which is currently bound to this thread.
- * Might be null.
- *
- * @return
- */
- public static SignaturePlaceholderData getSignaturePlaceholderData(){
- return instance.sigHolder.get();
- }
-
- /**
- *
- * @return true if there is currently a {@link SignaturePlaceholderData} bound to this thread, false otherwise.
- */
- public static boolean isSignaturePlaceholderDataSet() {
- return instance.sigHolder.get() != null;
- }
-
- /**
- * Bind a {@link SignaturePlaceholderData} to this thread.
- * If the given data is null, the context will be cleared.
- *
- * @param data if null, clears the ThreadLocal, else binds the data to the current thread.
- */
- public static void setSignaturePlaceholderData(SignaturePlaceholderData data) {
- instance.sigHolder.set(data);
- }
-}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/settings/Settings.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/settings/Settings.java
index c5b6dc57..8138f061 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/settings/Settings.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/settings/Settings.java
@@ -35,438 +35,380 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Vector;
+import java.util.stream.Collectors;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOCase;
import org.apache.commons.io.filefilter.WildcardFileFilter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.commons.lang3.StringUtils;
import at.gv.egiz.pdfas.common.exceptions.PdfAsSettingsException;
import at.gv.egiz.pdfas.common.settings.IProfileConstants;
import at.gv.egiz.pdfas.common.settings.ISettings;
import at.gv.egiz.pdfas.common.settings.Profiles;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class Settings implements ISettings, IProfileConstants {
+ protected Properties properties = new Properties();
+ protected File workDirectory;
+
+ public Settings(File workDirectory) {
+ try {
+ this.workDirectory = workDirectory;
+ loadSettings(workDirectory);
+ } catch (final PdfAsSettingsException e) {
+ log.error(e.getMessage(), e);
+ }
+ }
-public class Settings implements ISettings, IProfileConstants {
+ private void loadSettingsRecursive(File workDirectory, File file)
+ throws RuntimeException {
+ try {
+ final String configDir = workDirectory.getAbsolutePath() + File.separator
+ + CFG_DIR;
+ final Properties tmpProps = new Properties();
+ log.debug("Loading: " + file.getName());
+ tmpProps.load(new FileInputStream(file));
- private static final Logger logger = LoggerFactory
- .getLogger(Settings.class);
+ properties.putAll(tmpProps);
- protected Properties properties = new Properties();
+ this.getValuesPrefix(INCLUDE, tmpProps).values()
+ .forEach(el -> loadAdditionConfigFile(el, configDir));
- protected File workDirectory;
+ } catch (final IOException e) {
+ throw new RuntimeException(e);
- public Settings(File workDirectory) {
- try {
- this.workDirectory = workDirectory;
- loadSettings(workDirectory);
- } catch (PdfAsSettingsException e) {
- logger.error(e.getMessage(), e);
- }
}
+ }
- private void loadSettingsRecursive(File workDirectory, File file)
- throws PdfAsSettingsException {
- try {
- String configDir = workDirectory.getAbsolutePath() + File.separator
- + CFG_DIR;
- Properties tmpProps = new Properties();
- logger.debug("Loading: " + file.getName());
- tmpProps.load(new FileInputStream(file));
-
- properties.putAll(tmpProps);
-
- Map<String, String> includes = this.getValuesPrefix(INCLUDE,
- tmpProps);
- File contextFolder = new File(configDir);
- if (includes != null) {
- Iterator<String> includeIterator = includes.values().iterator();
- while (includeIterator.hasNext()) {
- contextFolder = new File(configDir);
- String includeFileName = includeIterator.next();
-
- File includeInstruction = new File(contextFolder,
- includeFileName);
- contextFolder = includeInstruction.getParentFile();
- String includeName = includeInstruction.getName();
-
- WildcardFileFilter fileFilter = new WildcardFileFilter(
- includeName, IOCase.SENSITIVE);
- Collection<File> includeFiles = null;
-
- if (contextFolder != null && contextFolder.exists()
- && contextFolder.isDirectory()) {
- includeFiles = FileUtils.listFiles(contextFolder,
- fileFilter, null);
- }
- if (includeFiles != null && !includeFiles.isEmpty()) {
- logger.debug("Including '" + includeFileName + "'.");
- for (File includeFile : includeFiles) {
- loadSettingsRecursive(workDirectory, includeFile);
- }
- }
- }
- }
-
- } catch (IOException e) {
- throw new PdfAsSettingsException("Failed to read settings!", e);
- }
- }
+ private void loadAdditionConfigFile(String includeFileName, String configDir) {
+ File contextFolder = new File(configDir);
- private void showAugments(Profiles profiles) {
- if (!profiles.getAugments().isEmpty()) {
- logger.debug("\tAugments for {}", profiles.getName());
- for (int i = 0; i < profiles.getAugments().size(); i++) {
- logger.debug("\t\t{}", profiles.getAugments().get(i).getName());
- }
- }
+ final File includeInstruction = new File(contextFolder, includeFileName);
+ contextFolder = includeInstruction.getParentFile();
+ final String includeName = includeInstruction.getName();
+
+ final WildcardFileFilter fileFilter = new WildcardFileFilter(
+ includeName, IOCase.SENSITIVE);
+ Collection<File> includeFiles = null;
+
+ if (contextFolder != null && contextFolder.exists()
+ && contextFolder.isDirectory()) {
+ includeFiles = FileUtils.listFiles(contextFolder,
+ fileFilter, null);
+ }
+ if (includeFiles != null && !includeFiles.isEmpty()) {
+ log.debug("Including '" + includeFileName + "'.");
+ for (final File includeFile : includeFiles) {
+ loadSettingsRecursive(workDirectory, includeFile);
+ }
}
- private boolean isAugmentsReady(Profiles profiles) {
- Iterator<Profiles> augmentingProfiles = profiles.getAugments().iterator();
- boolean allInitialized = true;
- while (augmentingProfiles.hasNext()) {
- if (!augmentingProfiles.next().isInitialized()) {
- allInitialized = false;
- }
+ }
+
+ private void showAugments(Profiles profiles) {
+ if (!profiles.getAugments().isEmpty()) {
+ log.debug("\tAugments for {}", profiles.getName());
+ for (final Profiles element : profiles.getAugments()) {
+ log.debug("\t\t{}", element.getName());
+ }
+ }
+ }
+
+ private boolean isAugmentsReady(Profiles profiles) {
+ boolean allInitialized = true;
+ for (final Profiles element : profiles.getAugments()) {
+ if (!element.isInitialized()) {
+ allInitialized = false;
+ }
+ }
+ return allInitialized;
+ }
+
+ private boolean isParentReady(Profiles profiles) {
+ if (profiles.getParent() != null) {
+ return profiles.getParent().isInitialized();
+ } else {
+ return false;
+ }
+ }
+
+ private void performAugmentConfiguration(Profiles profiles) {
+ final String childBase = "sig_obj."
+ + profiles.getName();
+
+ for (final Profiles augmentingProfile : profiles.getAugments()) {
+ final String augmentingBase = "sig_obj." + augmentingProfile.getName();
+
+ for (final String key : this.getKeys(
+ augmentingBase + ".")) {
+ final String keyToCopy = key.substring(augmentingBase
+ .length());
+ // log.debug("Profile: {} => {}",
+ // key, childBase+keyToCopy);
+ final String sourceKey = augmentingBase + keyToCopy;
+ final String targetKey = childBase + keyToCopy;
+
+ if (!this.hasValue(targetKey)) {
+ properties.setProperty(targetKey,
+ this.getValue(sourceKey));
+ // log.debug("Replaced: {} with Value from {}",
+ // childBase+keyToCopy, parentBase+keyToCopy);
+ } else {
+ // log.debug("NOT Replaced: {} with Value from {}",
+ // childBase+keyToCopy, parentBase+keyToCopy);
}
- return allInitialized;
+ }
}
-
- private boolean isParentReady(Profiles profiles) {
- if (profiles.getParent() != null) {
- return profiles.getParent().isInitialized();
+ }
+
+ private void performParentConfiguration(Profiles profiles) {
+ if (profiles.getParent() != null) {
+ // If Parent is initialized Copy Properties from Parent
+ // to this profile
+ final String parentBase = "sig_obj." + profiles.getParent().getName();
+ final String childBase = "sig_obj."
+ + profiles.getName();
+
+ for (final String key : this.getKeys(
+ parentBase + ".")) {
+ final String keyToCopy = key.substring(parentBase
+ .length());
+ // log.debug("Profile: {} => {}",
+ // key, childBase+keyToCopy);
+ final String sourceKey = parentBase + keyToCopy;
+ final String targetKey = childBase + keyToCopy;
+
+ if (!this.hasValue(targetKey)) {
+ properties.setProperty(targetKey,
+ this.getValue(sourceKey));
+ // log.debug("Replaced: {} with Value from {}",
+ // childBase+keyToCopy, parentBase+keyToCopy);
} else {
- return false;
+ // log.debug("NOT Replaced: {} with Value from {}",
+ // childBase+keyToCopy, parentBase+keyToCopy);
}
+ }
+ }
+ }
+
+ private void buildProfiles() {
+ final Map<String, Profiles> profiles = new HashMap<>();
+
+ for (final String key : this.getFirstLevelKeys("sig_obj.types.")) {
+ final String profile = key.substring("sig_obj.types.".length());
+ // System.out.println("[" + profile + "]: " + this.getValue(key));
+ if (this.getValue(key).equals("on")) {
+ final Profiles prof = new Profiles(profile);
+ profiles.put(profile, prof);
+ }
}
- private void performAugmentConfiguration(Profiles profiles) {
- Iterator<Profiles> augmentingProfiles = profiles.getAugments().iterator();
-
- String childBase = "sig_obj."
- + profiles.getName();
-
- while (augmentingProfiles.hasNext()) {
- Profiles augmentingProfile = augmentingProfiles.next();
- String augmentingBase = "sig_obj." + augmentingProfile.getName();
-
- Iterator<String> augmentingKeyIt = this.getKeys(
- augmentingBase + ".").iterator();
-
- while (augmentingKeyIt.hasNext()) {
- String key = augmentingKeyIt.next();
- String keyToCopy = key.substring(augmentingBase
- .length());
- //logger.debug("Profile: {} => {}",
- // key, childBase+keyToCopy);
- String sourceKey = augmentingBase + keyToCopy;
- String targetKey = childBase + keyToCopy;
-
- if (!this.hasValue(targetKey)) {
- properties.setProperty(targetKey,
- this.getValue(sourceKey));
- //logger.debug("Replaced: {} with Value from {}",
- // childBase+keyToCopy, parentBase+keyToCopy);
- } else {
- //logger.debug("NOT Replaced: {} with Value from {}",
- // childBase+keyToCopy, parentBase+keyToCopy);
- }
- }
- }
+ for (final Entry<String, Profiles> entry : profiles.entrySet()) {
+ entry.getValue().findParent(properties, profiles);
}
- private void performParentConfiguration(Profiles profiles) {
- if (profiles.getParent() != null) {
- // If Parent is initialized Copy Properties from Parent
- // to this profile
- String parentBase = "sig_obj." + profiles.getParent().getName();
- String childBase = "sig_obj."
- + profiles.getName();
-
- Iterator<String> parentKeyIt = this.getKeys(
- parentBase + ".").iterator();
- while (parentKeyIt.hasNext()) {
- String key = parentKeyIt.next();
- String keyToCopy = key.substring(parentBase
- .length());
- //logger.debug("Profile: {} => {}",
- // key, childBase+keyToCopy);
- String sourceKey = parentBase + keyToCopy;
- String targetKey = childBase + keyToCopy;
-
- if (!this.hasValue(targetKey)) {
- properties.setProperty(targetKey,
- this.getValue(sourceKey));
- //logger.debug("Replaced: {} with Value from {}",
- // childBase+keyToCopy, parentBase+keyToCopy);
- } else {
- //logger.debug("NOT Replaced: {} with Value from {}",
- // childBase+keyToCopy, parentBase+keyToCopy);
- }
- }
- }
+ for (final Entry<String, Profiles> entry : profiles.entrySet()) {
+ if (entry.getValue().getParent() == null) {
+ log.debug("Got Profile: [{}] : {}", entry.getKey(), entry.getValue().getName());
+ showAugments(entry.getValue());
+ } else {
+ log.debug("Got Profile: [{}] : {} (Parent {})", entry.getKey(),
+ entry.getValue().getName(), entry.getValue().getParent().getName());
+ showAugments(entry.getValue());
+ }
}
- private void buildProfiles() {
- Map<String, Profiles> profiles = new HashMap<String, Profiles>();
-
- Iterator<String> itKeys = this.getFirstLevelKeys("sig_obj.types.")
- .iterator();
- while (itKeys.hasNext()) {
- String key = itKeys.next();
- String profile = key.substring("sig_obj.types.".length());
- //System.out.println("[" + profile + "]: " + this.getValue(key));
- if (this.getValue(key).equals("on")) {
- Profiles prof = new Profiles(profile);
- profiles.put(profile, prof);
- }
- }
+ log.debug("Configured Settings: {}",
+ properties.size());
+
+ // Resolve Parent Structures ...
+ while (!profiles.isEmpty()) {
+ final List<String> removes = new ArrayList<>();
+ for (final Entry<String, Profiles> entry : profiles.entrySet()) {
+ // Remove all base Profiles ...
+ if (entry.getValue().getParent() == null && entry.getValue().getAugments().isEmpty()) {
+ // Has neither parent or augmenting profiles
+
+ entry.getValue().setInitialized(true);
+ removes.add(entry.getKey());
+ } else if (entry.getValue().getParent() == null) {
+ // Has augmenting profiles but no parent
+
+ // check if all augmenting profiles are initialized if so
+ // add them
+
+ final Profiles profile = entry.getValue();
+ if (this.isAugmentsReady(profile)) {
+ this.performAugmentConfiguration(profile);
+ // Copy done
+ entry.getValue().setInitialized(true);
+ removes.add(entry.getKey());
+ } else {
+ log.debug("Not all augmenting profiles are ready yet for {}", entry.getValue().getName());
+ }
+ } else if (entry.getValue().getAugments().isEmpty()) {
+
+ // Has parent but no augmenting profiles
+ final Profiles profile = entry.getValue();
+
+ if (this.isParentReady(profile)) {
+ this.performParentConfiguration(profile);
+ // Copy done
+ entry.getValue().setInitialized(true);
+ removes.add(entry.getKey());
+ }
+ } else {
- // Initialize Parent Structure ...
- Iterator<Entry<String, Profiles>> profileIterator = profiles.entrySet()
- .iterator();
- while (profileIterator.hasNext()) {
- Entry<String, Profiles> entry = profileIterator.next();
- entry.getValue().findParent(properties, profiles);
- }
+ // Has parent and augmenting profiles
- // Debug Output
- Iterator<Entry<String, Profiles>> profileIteratorDbg = profiles.entrySet()
- .iterator();
- while (profileIteratorDbg.hasNext()) {
- Entry<String, Profiles> entry = profileIteratorDbg.next();
- if (entry.getValue().getParent() == null) {
- logger.debug("Got Profile: [{}] : {}", entry.getKey(), entry.getValue().getName());
- showAugments(entry.getValue());
- } else {
- logger.debug("Got Profile: [{}] : {} (Parent {})", entry.getKey(),
- entry.getValue().getName(), entry.getValue().getParent().getName());
- showAugments(entry.getValue());
- }
- }
+ final Profiles profile = entry.getValue();
+ if (this.isAugmentsReady(profile) && this.isParentReady(profile)) {
+ // order is curcial, augments preceed over parent configuration
+ this.performAugmentConfiguration(profile);
+ this.performParentConfiguration(profile);
- logger.debug("Configured Settings: {}",
- properties.size());
-
- // Resolve Parent Structures ...
- while (!profiles.isEmpty()) {
- List<String> removes = new ArrayList<String>();
- Iterator<Entry<String, Profiles>> profileIt = profiles.entrySet()
- .iterator();
- while (profileIt.hasNext()) {
- Entry<String, Profiles> entry = profileIt.next();
-
- // Remove all base Profiles ...
- if (entry.getValue().getParent() == null && entry.getValue().getAugments().isEmpty()) {
- // Has neither parent or augmenting profiles
-
- entry.getValue().setInitialized(true);
- removes.add(entry.getKey());
- } else if (entry.getValue().getParent() == null) {
- // Has augmenting profiles but no parent
-
- // check if all augmenting profiles are initialized if so
- // add them
-
- Profiles profile = entry.getValue();
- if (this.isAugmentsReady(profile)) {
- this.performAugmentConfiguration(profile);
- // Copy done
- entry.getValue().setInitialized(true);
- removes.add(entry.getKey());
- } else {
- logger.debug("Not all augmenting profiles are ready yet for {}", entry.getValue().getName());
- }
- } else if (entry.getValue().getAugments().isEmpty()) {
-
- // Has parent but no augmenting profiles
- Profiles profile = entry.getValue();
-
- if (this.isParentReady(profile)) {
- this.performParentConfiguration(profile);
- // Copy done
- entry.getValue().setInitialized(true);
- removes.add(entry.getKey());
- }
- } else {
-
- // Has parent and augmenting profiles
-
- Profiles profile = entry.getValue();
- if (this.isAugmentsReady(profile) && this.isParentReady(profile)) {
- // order is curcial, augments preceed over parent configuration
- this.performAugmentConfiguration(profile);
- this.performParentConfiguration(profile);
-
- // Copy done
- entry.getValue().setInitialized(true);
- removes.add(entry.getKey());
- }
- }
- }
-
- // Remove all Profiles from Remove List
-
- if (removes.isEmpty() && !profiles.isEmpty()) {
- logger.error("Failed to build inheritant Profiles, running in infinite loop! (aborting ...)");
- logger.error("Profiles that cannot be resolved completly:");
- Iterator<Entry<String, Profiles>> failedProfiles = profiles.entrySet().iterator();
- while (failedProfiles.hasNext()) {
- Entry<String, Profiles> entry = failedProfiles.next();
- logger.error("Problem Profile: [{}] : {}", entry.getKey(), entry.getValue().getName());
- }
- return;
- }
-
- Iterator<String> removeIt = removes.iterator();
- while (removeIt.hasNext()) {
- profiles.remove(removeIt.next());
- }
+ // Copy done
+ entry.getValue().setInitialized(true);
+ removes.add(entry.getKey());
+ }
}
+ }
- logger.debug("Derived Settings: {}",
- properties.size());
+ // Remove all Profiles from Remove List
- }
-
- public void debugDumpProfileSettings(String profileName) {
- Iterator<String> keysIterator = this.getKeys("sig_obj." + profileName + ".").iterator();
-
- logger.debug("Configuration for {}", profileName);
- while(keysIterator.hasNext()) {
- String key = keysIterator.next();
- logger.debug(" {}: {}", key, this.getValue(key));
+ if (removes.isEmpty() && !profiles.isEmpty()) {
+ log.error("Failed to build inheritant Profiles, running in infinite loop! (aborting ...)");
+ log.error("Profiles that cannot be resolved completly:");
+ for (final Entry<String, Profiles> entry : profiles.entrySet()) {
+ log.error("Problem Profile: [{}] : {}", entry.getKey(), entry.getValue().getName());
}
- }
+ return;
+ }
- public void loadSettings(File workDirectory) throws PdfAsSettingsException {
- // try {
- String configDir = workDirectory.getAbsolutePath() + File.separator
- + CFG_DIR;
- String configFile = configDir + File.separator + CFG_FILE;
- loadSettingsRecursive(workDirectory, new File(configFile));
- buildProfiles();
- /*
- * logger.debug("Loading cfg file: " + configFile);
- *
- *
- * properties.load(new FileInputStream(configFile));
- *
- * Map<String, String> includes = this.getValuesPrefix(INCLUDE); File
- * contextFolder = new File(configDir); if (includes != null) {
- * Iterator<String> includeIterator = includes.values().iterator();
- * while (includeIterator.hasNext()) { String includeFileName =
- * includeIterator.next(); if (includeFileName.contains("*")) {
- * WildcardFileFilter fileFilter = new WildcardFileFilter(
- * includeFileName, IOCase.SENSITIVE); Collection<File> includeFiles =
- * null;
- *
- * if (contextFolder != null && contextFolder.exists() &&
- * contextFolder.isDirectory()) { includeFiles =
- * FileUtils.listFiles(contextFolder, fileFilter, null); } if
- * (includeFiles != null && !includeFiles.isEmpty()) {
- * logger.info("Including '" + includeFileName + "'."); for (File
- * includeFile : includeFiles) { properties .load(new
- * FileInputStream(includeFile)); } } } else { String includeFile =
- * configDir + File.separator + includeFileName;
- * logger.debug("Loading included cfg file: " + includeFile); try {
- * properties.load(new FileInputStream(includeFile)); } catch (Throwable
- * e) { logger.error("Failed to load cfg file " + includeFile, e); } } }
- * }
- */
- // logger.debug("Configured Properties:");
- /*
- * if(logger.isDebugEnabled()) { properties.list(System.out); }
- */
-
- // } catch (IOException e) {
- // throw new PdfAsSettingsException("Failed to read settings!", e);
- // }
+ for (final String element : removes) {
+ profiles.remove(element);
+ }
}
- public String getValue(String key) {
- return properties.getProperty(key);
- }
+ log.debug("Derived Settings: {}",
+ properties.size());
- public boolean hasValue(String key) {
- return properties.containsKey(key);
- }
+ }
- private Map<String, String> getValuesPrefix(String prefix, Properties props) {
- Iterator<Object> keyIterator = props.keySet().iterator();
- Map<String, String> valueMap = new HashMap<String, String>();
- while (keyIterator.hasNext()) {
- String key = keyIterator.next().toString();
+ public void debugDumpProfileSettings(String profileName) {
+ log.debug("Configuration for {}", profileName);
+ for (final String key : this.getKeys("sig_obj." + profileName + ".")) {
+ log.debug(" {}: {}", key, this.getValue(key));
+ }
+ }
+ public void loadSettings(File workDirectory) throws PdfAsSettingsException {
+ try {
+ final String configDir = workDirectory.getAbsolutePath() + File.separator
+ + CFG_DIR;
+ final String configFile = configDir + File.separator + CFG_FILE;
+ loadSettingsRecursive(workDirectory, new File(configFile));
+ buildProfiles();
- if (key.startsWith(prefix)) {
- valueMap.put(key, props.getProperty(key));
- }
- }
+ } catch (final RuntimeException e) {
+ throw new PdfAsSettingsException("Failed to read settings!", e);
- if (valueMap.isEmpty()) {
- return null;
- }
-
- return valueMap;
}
-
- public Map<String, String> getValuesPrefix(String prefix) {
- return getValuesPrefix(prefix, properties);
+ }
+
+ @Override
+ public String getValue(String key) {
+ return properties.getProperty(key);
+ }
+
+ public boolean isValue(String key) {
+ return isValue(key, false);
+
+ }
+ public boolean isValue(String key, boolean defaultValue) {
+ String value = getValue(key);
+ if (StringUtils.isNotEmpty(value)) {
+ return Boolean.valueOf(value);
+
+ } else {
+ return defaultValue;
+
}
-
- public Vector<String> getKeys(String prefix) {
- Iterator<Object> keyIterator = properties.keySet().iterator();
- Vector<String> valueMap = new Vector<String>();
- while (keyIterator.hasNext()) {
- String key = keyIterator.next().toString();
-
- if (key.startsWith(prefix)) {
- valueMap.add(key);
- }
- }
- return valueMap;
+ }
+
+ @Override
+ public boolean hasValue(String key) {
+ return properties.containsKey(key);
+ }
+
+ private Map<String, String> getValuesPrefix(String prefix, Properties props) {
+ return props.entrySet().stream()
+ .filter(el -> el.getKey().toString().startsWith(prefix))
+ .collect(Collectors.toMap(key -> key.getKey().toString(), value -> value.getValue().toString()));
+
+ }
+
+ @Override
+ public Map<String, String> getValuesPrefix(String prefix) {
+ return getValuesPrefix(prefix, properties);
+ }
+
+ public Vector<String> getKeys(String prefix) {
+ final Iterator<Object> keyIterator = properties.keySet().iterator();
+ final Vector<String> valueMap = new Vector<>();
+ while (keyIterator.hasNext()) {
+ final String key = keyIterator.next().toString();
+
+ if (key.startsWith(prefix)) {
+ valueMap.add(key);
+ }
}
-
- public Vector<String> getFirstLevelKeys(String prefix) {
- String mPrefix = prefix.endsWith(".") ? prefix : prefix + ".";
- Iterator<Object> keyIterator = properties.keySet().iterator();
- Vector<String> valueMap = new Vector<String>();
- while (keyIterator.hasNext()) {
- String key = keyIterator.next().toString();
-
- if (key.startsWith(prefix)) {
- int keyIdx = key.indexOf('.', mPrefix.length()) > 0 ? key
- .indexOf('.', mPrefix.length()) : key.length();
- String firstLevels = key.substring(0, keyIdx);
- if (!valueMap.contains(firstLevels)) {
- valueMap.add(firstLevels);
- }
- }
- }
-
- if (valueMap.isEmpty()) {
- return null;
+ return valueMap;
+ }
+
+ @Override
+ public Vector<String> getFirstLevelKeys(String prefix) {
+ final String mPrefix = prefix.endsWith(".") ? prefix : prefix + ".";
+ final Iterator<Object> keyIterator = properties.keySet().iterator();
+ final Vector<String> valueMap = new Vector<>();
+ while (keyIterator.hasNext()) {
+ final String key = keyIterator.next().toString();
+
+ if (key.startsWith(prefix)) {
+ final int keyIdx = key.indexOf('.', mPrefix.length()) > 0 ? key
+ .indexOf('.', mPrefix.length()) : key.length();
+ final String firstLevels = key.substring(0, keyIdx);
+ if (!valueMap.contains(firstLevels)) {
+ valueMap.add(firstLevels);
}
+ }
+ }
- return valueMap;
+ if (valueMap.isEmpty()) {
+ return null;
}
- public boolean hasPrefix(String prefix) {
- Iterator<Object> keyIterator = properties.keySet().iterator();
- while (keyIterator.hasNext()) {
- String key = keyIterator.next().toString();
+ return valueMap;
+ }
- if (key.startsWith(prefix)) {
- return true;
- }
- }
- return false;
- }
+ @Override
+ public boolean hasPrefix(String prefix) {
+ final Iterator<Object> keyIterator = properties.keySet().iterator();
+ while (keyIterator.hasNext()) {
+ final String key = keyIterator.next().toString();
- public String getWorkingDirectory() {
- return this.workDirectory.getAbsolutePath();
+ if (key.startsWith(prefix)) {
+ return true;
+ }
}
+ return false;
+ }
+
+ @Override
+ public String getWorkingDirectory() {
+ return this.workDirectory.getAbsolutePath();
+ }
}
diff --git a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/util/SignatureUtils.java b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/util/SignatureUtils.java
index 6e584f32..6282d9c1 100644
--- a/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/util/SignatureUtils.java
+++ b/pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/util/SignatureUtils.java
@@ -1,144 +1,138 @@
package at.gv.egiz.pdfas.lib.util;
-import iaik.asn1.CodingException;
-import iaik.asn1.ObjectID;
-import iaik.asn1.structures.Attribute;
-import iaik.cms.CMSException;
-import iaik.cms.SignedData;
-import iaik.cms.SignerInfo;
-import iaik.smime.ess.ESSCertID;
-import iaik.smime.ess.ESSCertIDv2;
-import iaik.smime.ess.SigningCertificate;
-import iaik.smime.ess.SigningCertificateV2;
-import iaik.x509.X509Certificate;
-
import java.io.ByteArrayInputStream;
import java.io.IOException;
-import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
-import java.security.cert.CertificateException;
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.common.exceptions.PdfAsSignatureException;
-import at.gv.egiz.pdfas.common.utils.StreamUtils;
import at.gv.egiz.pdfas.lib.api.verify.VerifyResult;
import at.gv.egiz.pdfas.lib.impl.verify.VerifyResultImpl;
+import iaik.asn1.ObjectID;
+import iaik.asn1.structures.Attribute;
+import iaik.cms.CMSException;
+import iaik.cms.SignedData;
+import iaik.cms.SignerInfo;
+import iaik.smime.ess.SigningCertificate;
+import iaik.smime.ess.SigningCertificateV2;
+import iaik.x509.X509Certificate;
public class SignatureUtils implements ErrorConstants {
-
- private static final Logger logger = LoggerFactory
- .getLogger(SignatureUtils.class);
-
- public static VerifyResult verifySignature(byte[] signature, byte[] input)
- throws PDFASError {
- // List<VerifyResult> results = new ArrayList<VerifyResult>();
- try {
- SignedData signedData = new SignedData(new ByteArrayInputStream(
- signature));
-
- signedData.setContent(input);
-
- // get the signer infos
- SignerInfo[] signerInfos = signedData.getSignerInfos();
- if (signerInfos.length == 0) {
- logger.warn("Invalid signature (no signer information)");
- throw new PDFASError(ERROR_SIG_INVALID_BKU_SIG);
- }
-
- if (signerInfos.length != 1) {
- logger.warn("Invalid signature (multiple signer information)");
- throw new PDFASError(ERROR_SIG_INVALID_BKU_SIG);
- }
- // verify the signatures
- // for (int i = 0; i < signerInfos.length; i++) {
- VerifyResultImpl verifyResult = new VerifyResultImpl();
- // results.add(verifyResult);
- try {
- logger.debug("Signature Algo: {}, Digest {}",
- signedData.getSignerInfos()[0].getSignatureAlgorithm(),
- signedData.getSignerInfos()[0].getDigestAlgorithm());
- // verify the signature for SignerInfo at index i
- X509Certificate signer_cert = signedData.verify(0);
-
- // Must include Signing Certificate!
- Attribute signedCertificate = signerInfos[0]
- .getSignedAttribute(ObjectID.signingCertificate);
-
- if (signedCertificate == null) {
- signedCertificate = signerInfos[0]
- .getSignedAttribute(ObjectID.signingCertificateV2);
- if (signedCertificate == null) {
- logger.warn("Signature ERROR missing signed Signing Certificate: ");
-
- throw new PDFASError(ERROR_SIG_INVALID_BKU_SIG);
- } else {
- // Validate signingCertificate2
- try {
- SigningCertificateV2 signingCert = (SigningCertificateV2)signedCertificate.getAttributeValue();
-
- if (signingCert.isSignerCertificate(signer_cert)) {
- // OK
- logger.debug("Found and verified SigningCertificateV2");
- } else {
- logger.error("Signature ERROR certificate missmatch, misbehaving Signature Backend?");
-
- throw new PDFASError(ERROR_SIG_INVALID_BKU_SIG);
- }
- } catch (Throwable e) {
- logger.error("Signature ERROR wrong encoding for ESSCertIDv2, misbehaving Signature Backend?");
-
- throw new PDFASError(ERROR_SIG_INVALID_BKU_SIG, e);
- }
- }
- } else {
- // Validate signingCertificate
- try {
- SigningCertificate signingCert = (SigningCertificate)signedCertificate.getAttributeValue();
- if (signingCert.isSignerCertificate(signer_cert)) {
- // OK
- logger.debug("Found and verified SigningCertificate");
- } else {
- logger.warn("Signature ERROR certificate missmatch, misbehaving Signature Backend?");
-
- throw new PDFASError(ERROR_SIG_INVALID_BKU_SIG);
- }
- } catch (Throwable e) {
- logger.error("Signature ERROR wrong encoding for ESSCertIDv2, misbehaving Signature Backend?");
-
- throw new PDFASError(ERROR_SIG_INVALID_BKU_SIG, e);
- }
- }
-
- // if the signature is OK the certificate of the
- // signer is returned
- logger.debug("Signature OK");
- verifyResult.setSignerCertificate(signer_cert);
-
- } catch (SignatureException ex) {
- // if the signature is not OK a SignatureException
- // is thrown
- logger.warn(
- "Signature ERROR from signer: "
- + signedData.getCertificate(
- signerInfos[0].getSignerIdentifier())
- .getSubjectDN(), ex);
-
- verifyResult.setSignerCertificate(signedData
- .getCertificate(signerInfos[0].getSignerIdentifier()));
- throw new PDFASError(ERROR_SIG_INVALID_BKU_SIG, ex);
- }
-
- return verifyResult;
- // }
- } catch (CMSException e) {
- throw new PDFASError(ERROR_SIG_INVALID_BKU_SIG, e);
- } catch (IOException e) {
- throw new PDFASError(ERROR_SIG_INVALID_BKU_SIG, e);
- }
-
- }
+ private static final Logger logger = LoggerFactory.getLogger(SignatureUtils.class);
+
+ public static VerifyResult verifySignature(byte[] signature, byte[] input)
+ throws PDFASError {
+ // List<VerifyResult> results = new ArrayList<VerifyResult>();
+ try {
+ final SignedData signedData = new SignedData(new ByteArrayInputStream(signature));
+ signedData.setContent(input);
+
+ // get the signer infos
+ final SignerInfo[] signerInfos = signedData.getSignerInfos();
+ if (signerInfos.length == 0) {
+ logger.warn("Invalid signature (no signer information)");
+ throw new PDFASError(ERROR_SIG_INVALID_BKU_SIG);
+
+ }
+
+ if (signerInfos.length != 1) {
+ logger.warn("Invalid signature (multiple signer information)");
+ throw new PDFASError(ERROR_SIG_INVALID_BKU_SIG);
+
+ }
+ // verify the signatures
+ // for (int i = 0; i < signerInfos.length; i++) {
+ final VerifyResultImpl verifyResult = new VerifyResultImpl();
+ // results.add(verifyResult);
+ try {
+ logger.debug("Signature Algo: {}, Digest {}",
+ signedData.getSignerInfos()[0].getSignatureAlgorithm(),
+ signedData.getSignerInfos()[0].getDigestAlgorithm());
+ // verify the signature for SignerInfo at index i
+ final X509Certificate signer_cert = signedData.verify(0);
+
+ // Must include Signing Certificate!
+ Attribute signedCertificate = signerInfos[0].getSignedAttribute(ObjectID.signingCertificate);
+
+ if (signedCertificate == null) {
+ signedCertificate = signerInfos[0].getSignedAttribute(ObjectID.signingCertificateV2);
+
+ if (signedCertificate == null) {
+ logger.warn("Signature ERROR missing signed Signing Certificate: ");
+ throw new PDFASError(ERROR_SIG_INVALID_BKU_SIG);
+
+ } else {
+ // Validate signingCertificate2
+ try {
+ final SigningCertificateV2 signingCert = (SigningCertificateV2) signedCertificate.getAttributeValue();
+ if (signingCert.isSignerCertificate(signer_cert)) {
+ // OK
+ logger.debug("Found and verified SigningCertificateV2");
+
+ } else {
+ logger.error("Signature ERROR certificate missmatch, misbehaving Signature Backend?");
+
+ throw new PDFASError(ERROR_SIG_INVALID_BKU_SIG);
+ }
+
+ } catch (final Throwable e) {
+ logger.error("Signature ERROR wrong encoding for ESSCertIDv2, misbehaving Signature Backend?");
+ throw new PDFASError(ERROR_SIG_INVALID_BKU_SIG, e);
+
+ }
+ }
+
+ } else {
+ // Validate signingCertificate
+ try {
+ final SigningCertificate signingCert = (SigningCertificate) signedCertificate.getAttributeValue();
+ if (signingCert.isSignerCertificate(signer_cert)) {
+ // OK
+ logger.debug("Found and verified SigningCertificate");
+ } else {
+ logger.warn("Signature ERROR certificate missmatch, misbehaving Signature Backend?");
+
+ throw new PDFASError(ERROR_SIG_INVALID_BKU_SIG);
+ }
+ } catch (final Throwable e) {
+ logger.error("Signature ERROR wrong encoding for ESSCertIDv2, misbehaving Signature Backend?");
+
+ throw new PDFASError(ERROR_SIG_INVALID_BKU_SIG, e);
+ }
+ }
+
+ // if the signature is OK the certificate of the
+ // signer is returned
+ logger.debug("Signature OK");
+ verifyResult.setSignerCertificate(signer_cert);
+
+ } catch (final SignatureException ex) {
+ // if the signature is not OK a SignatureException
+ // is thrown
+ logger.warn(
+ "Signature ERROR from signer: "
+ + signedData.getCertificate(
+ signerInfos[0].getSignerIdentifier())
+ .getSubjectDN(), ex);
+
+ verifyResult.setSignerCertificate(signedData
+ .getCertificate(signerInfos[0].getSignerIdentifier()));
+ throw new PDFASError(ERROR_SIG_INVALID_BKU_SIG, ex);
+
+ }
+
+ return verifyResult;
+ // }
+ } catch (final CMSException e) {
+ throw new PDFASError(ERROR_SIG_INVALID_BKU_SIG, e);
+
+ } catch (final IOException e) {
+ throw new PDFASError(ERROR_SIG_INVALID_BKU_SIG, e);
+
+ }
+
+ }
}
diff --git a/pdf-as-lib/src/test/java/at/gv/egiz/pdfas/lib/test/stamping/CertificateAndRequestParameterResolverTest.java b/pdf-as-lib/src/test/java/at/gv/egiz/pdfas/lib/test/stamping/CertificateAndRequestParameterResolverTest.java
index fdc8fa7e..e94d21e8 100644
--- a/pdf-as-lib/src/test/java/at/gv/egiz/pdfas/lib/test/stamping/CertificateAndRequestParameterResolverTest.java
+++ b/pdf-as-lib/src/test/java/at/gv/egiz/pdfas/lib/test/stamping/CertificateAndRequestParameterResolverTest.java
@@ -4,8 +4,10 @@ import static org.junit.Assert.assertEquals;
import java.io.IOException;
import java.security.cert.CertificateException;
+import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
+import java.util.stream.Collectors;
import org.junit.Before;
import org.junit.Test;
@@ -13,6 +15,7 @@ import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import at.gv.egiz.pdfas.common.exceptions.PDFASError;
+import at.gv.egiz.pdfas.common.settings.IProfileConstants;
import at.gv.egiz.pdfas.common.settings.ISettings;
import at.gv.egiz.pdfas.common.settings.SignatureProfileSettings;
import at.gv.egiz.pdfas.lib.api.sign.SignParameter;
@@ -76,18 +79,23 @@ public class CertificateAndRequestParameterResolverTest {
}
private ISettings buildDummySettings() {
- return new ISettings() {
-
+ Map<String, String> configMap = new HashMap<>();
+ configMap.put(IProfileConstants.SIG_OBJ + "test", "test");
+
+ return new ISettings() {
+
@Override
public boolean hasValue(String key) {
- // TODO Auto-generated method stub
- return false;
+ return configMap.containsKey(key);
}
@Override
public boolean hasPrefix(String prefix) {
- // TODO Auto-generated method stub
- return false;
+ return configMap.keySet().stream()
+ .filter(el -> el.startsWith(prefix))
+ .findFirst()
+ .isPresent();
+
}
@Override
@@ -98,14 +106,16 @@ public class CertificateAndRequestParameterResolverTest {
@Override
public Map<String, String> getValuesPrefix(String prefix) {
- // TODO Auto-generated method stub
- return null;
+ return configMap.entrySet().stream()
+ .filter(el -> el.getKey().startsWith(prefix))
+ .collect(Collectors.toMap(key -> key.getKey(), value -> value.getValue()));
+
}
@Override
public String getValue(String key) {
- // TODO Auto-generated method stub
- return null;
+ return configMap.get(key);
+
}
@Override
@@ -113,6 +123,16 @@ public class CertificateAndRequestParameterResolverTest {
// TODO Auto-generated method stub
return null;
}
- };
+
+ @Override
+ public boolean isValue(String key) {
+ return isValue(key, false);
+ }
+
+ @Override
+ public boolean isValue(String key, boolean defaultValue) {
+ return hasValue(key) ? Boolean.valueOf(getValue(key)) : defaultValue;
+ }
+ };
}
}
diff --git a/pdf-as-moa/build.gradle b/pdf-as-moa/build.gradle
index 0e1032e2..d0fe8c0b 100644
--- a/pdf-as-moa/build.gradle
+++ b/pdf-as-moa/build.gradle
@@ -35,7 +35,7 @@ project.ext {
generatedWsdlDir = file("src/generated/java")
wsdlsToGenerate = [
['-xjc',
- "$wsdlDir/MOA-SPSS-1.5.2.wsdl"],
+ "$wsdlDir/MOA-SPSS-2.0.0.wsdl"],
]
}
diff --git a/pdf-as-moa/src/generated/java/at/gv/e_government/reference/namespace/moa/_20020822_/SignatureCreationService.java b/pdf-as-moa/src/generated/java/at/gv/e_government/reference/namespace/moa/_20020822_/SignatureCreationService.java
index 67ad0fc0..1dabeb00 100644
--- a/pdf-as-moa/src/generated/java/at/gv/e_government/reference/namespace/moa/_20020822_/SignatureCreationService.java
+++ b/pdf-as-moa/src/generated/java/at/gv/e_government/reference/namespace/moa/_20020822_/SignatureCreationService.java
@@ -1,11 +1,12 @@
package at.gv.e_government.reference.namespace.moa._20020822_;
import java.net.URL;
+
import javax.xml.namespace.QName;
+import javax.xml.ws.Service;
import javax.xml.ws.WebEndpoint;
import javax.xml.ws.WebServiceClient;
import javax.xml.ws.WebServiceFeature;
-import javax.xml.ws.Service;
/**
* This class was generated by Apache CXF 3.0.1
@@ -14,7 +15,7 @@ import javax.xml.ws.Service;
*
*/
@WebServiceClient(name = "SignatureCreationService",
- wsdlLocation = "/wsdl/MOA-SPSS-1.5.2.wsdl",
+ wsdlLocation = "/wsdl/MOA-SPSS-2.0.0.wsdl",
targetNamespace = "http://reference.e-government.gv.at/namespace/moa/20020822#")
public class SignatureCreationService extends Service {
@@ -23,14 +24,14 @@ public class SignatureCreationService extends Service {
public final static QName SERVICE = new QName("http://reference.e-government.gv.at/namespace/moa/20020822#", "SignatureCreationService");
public final static QName SignatureCreationPort = new QName("http://reference.e-government.gv.at/namespace/moa/20020822#", "SignatureCreationPort");
static {
- URL url = SignatureCreationService.class.getResource("/wsdl/MOA-SPSS-1.5.2.wsdl");
+ URL url = SignatureCreationService.class.getResource("/wsdl/MOA-SPSS-2.0.0.wsdl");
if (url == null) {
- url = SignatureCreationService.class.getClassLoader().getResource("/wsdl/MOA-SPSS-1.5.2.wsdl");
+ url = SignatureCreationService.class.getClassLoader().getResource("/wsdl/MOA-SPSS-2.0.0.wsdl");
}
if (url == null) {
java.util.logging.Logger.getLogger(SignatureCreationService.class.getName())
.log(java.util.logging.Level.INFO,
- "Can not initialize the default wsdl from {0}", "/wsdl/MOA-SPSS-1.5.2.wsdl");
+ "Can not initialize the default wsdl from {0}", "/wsdl/MOA-SPSS-2.0.0.wsdl");
}
WSDL_LOCATION = url;
}
diff --git a/pdf-as-moa/src/generated/java/at/gv/e_government/reference/namespace/moa/_20020822_/SignatureVerificationService.java b/pdf-as-moa/src/generated/java/at/gv/e_government/reference/namespace/moa/_20020822_/SignatureVerificationService.java
index 2de494b7..f5ec7b54 100644
--- a/pdf-as-moa/src/generated/java/at/gv/e_government/reference/namespace/moa/_20020822_/SignatureVerificationService.java
+++ b/pdf-as-moa/src/generated/java/at/gv/e_government/reference/namespace/moa/_20020822_/SignatureVerificationService.java
@@ -1,11 +1,12 @@
package at.gv.e_government.reference.namespace.moa._20020822_;
import java.net.URL;
+
import javax.xml.namespace.QName;
+import javax.xml.ws.Service;
import javax.xml.ws.WebEndpoint;
import javax.xml.ws.WebServiceClient;
import javax.xml.ws.WebServiceFeature;
-import javax.xml.ws.Service;
/**
* This class was generated by Apache CXF 3.0.1
@@ -14,7 +15,7 @@ import javax.xml.ws.Service;
*
*/
@WebServiceClient(name = "SignatureVerificationService",
- wsdlLocation = "/wsdl/MOA-SPSS-1.5.2.wsdl",
+ wsdlLocation = "/wsdl/MOA-SPSS-2.0.0.wsdl",
targetNamespace = "http://reference.e-government.gv.at/namespace/moa/20020822#")
public class SignatureVerificationService extends Service {
@@ -23,14 +24,14 @@ public class SignatureVerificationService extends Service {
public final static QName SERVICE = new QName("http://reference.e-government.gv.at/namespace/moa/20020822#", "SignatureVerificationService");
public final static QName SignatureVerificationPort = new QName("http://reference.e-government.gv.at/namespace/moa/20020822#", "SignatureVerificationPort");
static {
- URL url = SignatureVerificationService.class.getResource("/wsdl/MOA-SPSS-1.5.2.wsdl");
+ URL url = SignatureVerificationService.class.getResource("/wsdl/MOA-SPSS-2.0.0.wsdl");
if (url == null) {
- url = SignatureVerificationService.class.getClassLoader().getResource("/wsdl/MOA-SPSS-1.5.2.wsdl");
+ url = SignatureVerificationService.class.getClassLoader().getResource("/wsdl/MOA-SPSS-2.0.0.wsdl");
}
if (url == null) {
java.util.logging.Logger.getLogger(SignatureVerificationService.class.getName())
.log(java.util.logging.Level.INFO,
- "Can not initialize the default wsdl from {0}", "/wsdl/MOA-SPSS-1.5.2.wsdl");
+ "Can not initialize the default wsdl from {0}", "/wsdl/MOA-SPSS-2.0.0.wsdl");
}
WSDL_LOCATION = url;
}
diff --git a/pdf-as-pdfbox-2/build.gradle b/pdf-as-pdfbox-2/build.gradle
index 6a2a0bfa..f6f14a5d 100644
--- a/pdf-as-pdfbox-2/build.gradle
+++ b/pdf-as-pdfbox-2/build.gradle
@@ -32,7 +32,7 @@ releases.dependsOn sourcesJar
dependencies {
implementation project (':pdf-as-lib')
implementation group: 'org.slf4j', name: 'slf4j-api', version: slf4jVersion
- implementation 'org.slf4j:jcl-over-slf4j:1.7.35'
+ implementation 'org.slf4j:jcl-over-slf4j:1.7.36'
api group: 'org.apache.pdfbox', name: 'pdfbox', version: '2.0.27'
api group: 'org.apache.pdfbox', name: 'pdfbox-tools', version: '2.0.27'
api group: 'org.apache.pdfbox', name: 'preflight', version: '2.0.27'
@@ -42,6 +42,9 @@ dependencies {
api group: 'com.github.jai-imageio', name: 'jai-imageio-core', version: '1.4.0'
api group: 'com.levigo.jbig2', name: 'levigo-jbig2-imageio', version: '2.0'
implementation group: 'javax.activation', name: 'activation', version: '1.1.1'
+
+ testImplementation 'ch.qos.logback:logback-classic:1.2.12'
+ testImplementation 'ch.qos.logback:logback-core:1.2.12'
}
diff --git a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/PDFBOXObject.java b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/PDFBOXObject.java
index 891ebe39..53b87d86 100644
--- a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/PDFBOXObject.java
+++ b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/PDFBOXObject.java
@@ -1,14 +1,10 @@
package at.gv.egiz.pdfas.lib.impl.pdfbox2;
import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
import javax.activation.DataSource;
-import org.apache.pdfbox.io.MemoryUsageSetting;
import org.apache.pdfbox.pdmodel.PDDocument;
-import org.apache.pdfbox.pdmodel.font.PDFont;
import at.gv.egiz.pdfas.lib.impl.stamping.pdfbox2.PDFAsFontCache;
import at.gv.egiz.pdfas.lib.impl.status.OperationStatus;
@@ -17,9 +13,7 @@ import at.gv.egiz.pdfas.lib.impl.status.PDFObject;
public class PDFBOXObject extends PDFObject {
private PDDocument doc;
-
- private Map<String, PDFont> fontCache = new HashMap<String, PDFont>();
-
+
private PDFAsFontCache sigBlockFontCache = new PDFAsFontCache();
public PDFAsFontCache getSigBlockFontCache() {
@@ -54,11 +48,6 @@ public class PDFBOXObject extends PDFObject {
}
}
- private MemoryUsageSetting getMemoryUsageSettings() {
- // TODO: allow fine tuning of memory usage (divided main memory vs file memory)
- return MemoryUsageSetting.setupMainMemoryOnly();
- }
-
public void setOriginalDocument(DataSource originalDocument) throws IOException {
this.originalDocument = originalDocument;
if(doc != null) {
diff --git a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/placeholder/PDFBoxPlaceholderExtractor.java b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/placeholder/PDFBoxPlaceholderExtractor.java
index 63b006bf..ad874bc0 100644
--- a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/placeholder/PDFBoxPlaceholderExtractor.java
+++ b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/placeholder/PDFBoxPlaceholderExtractor.java
@@ -1,5 +1,7 @@
package at.gv.egiz.pdfas.lib.impl.pdfbox2.placeholder;
+import java.io.IOException;
+
import at.gv.egiz.pdfas.common.exceptions.PDFIOException;
import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
import at.gv.egiz.pdfas.lib.impl.pdfbox2.PDFBOXObject;
@@ -7,9 +9,6 @@ import at.gv.egiz.pdfas.lib.impl.placeholder.PlaceholderExtractor;
import at.gv.egiz.pdfas.lib.impl.placeholder.SignaturePlaceholderData;
import at.gv.egiz.pdfas.lib.impl.status.PDFObject;
-import java.io.IOException;
-import java.util.List;
-
public class PDFBoxPlaceholderExtractor implements PlaceholderExtractor {
@@ -18,27 +17,8 @@ public class PDFBoxPlaceholderExtractor implements PlaceholderExtractor {
if (doc instanceof PDFBOXObject) {
PDFBOXObject object = (PDFBOXObject) doc;
try {
- SignaturePlaceholderExtractor extractor = new SignaturePlaceholderExtractor(placeholderId,
- matchMode, object.getDocument());
- return extractor.extract(object.getDocument(),
- placeholderId, matchMode);
- } catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException e2) {
- throw new PDFIOException("error.pdf.io.04", e2);
- }
-
- }
- throw new PdfAsException("INVALID STATE");
- }
-
- @Override
- public List<SignaturePlaceholderData> extractList(PDFObject doc, String placeholderId, int matchMode) throws PdfAsException {
- if (doc instanceof PDFBOXObject) {
- PDFBOXObject object = (PDFBOXObject) doc;
- try {
- SignaturePlaceholderExtractor extractor = new SignaturePlaceholderExtractor(placeholderId,
- matchMode, object.getDocument());
- return extractor.extractList(object.getDocument(),
- placeholderId, matchMode);
+ SignaturePlaceholderExtractor extractor = new SignaturePlaceholderExtractor();
+ return extractor.extract(object.getDocument(), placeholderId, matchMode);
} catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException e2) {
throw new PDFIOException("error.pdf.io.04", e2);
}
diff --git a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/placeholder/SignatureFieldsAndPlaceHolderExtractor.java b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/placeholder/SignatureFieldsAndPlaceHolderExtractor.java
index 609f8254..8e5e5d4e 100644
--- a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/placeholder/SignatureFieldsAndPlaceHolderExtractor.java
+++ b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/placeholder/SignatureFieldsAndPlaceHolderExtractor.java
@@ -1,106 +1,58 @@
package at.gv.egiz.pdfas.lib.impl.pdfbox2.placeholder;
-import at.gv.egiz.pdfas.lib.impl.placeholder.PlaceholderExtractorConstants;
-import at.gv.egiz.pdfas.lib.impl.placeholder.SignaturePlaceholderData;
+import java.util.ArrayList;
+import java.util.List;
+
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
+import at.gv.egiz.pdfas.lib.impl.placeholder.PlaceholderExtractorConstants;
+import at.gv.egiz.pdfas.lib.impl.placeholder.SignaturePlaceholderData;
public class SignatureFieldsAndPlaceHolderExtractor {
- //Search for empty signature fields
- public static List<String> findEmptySignatureFields(PDDocument doc)
- {
- PDSignature signature;
- List<PDField> signatureField;
- List<String> signatureFieldNames = new ArrayList<>();
- PDAcroForm acroForm = doc.getDocumentCatalog().getAcroForm();
- if (acroForm != null) {
- signatureField = acroForm.getFields();
- for (PDField pdField : signatureField) {
- if(pdField instanceof PDSignatureField && pdField.getPartialName()!=null)
- {
- signature = ((PDSignatureField) pdField).getSignature();
- if(signature == null) signatureFieldNames.add(pdField.getPartialName());
- }
- }
- }
- return signatureFieldNames;
- }
- /*
- Needed by PDF-OVER
- */
-
- /**
- * Returns the next unused signature placeholder
- * @param doc The document to be searched for signature placeholders
- * @return The next unused signature placeholder or null in case there is none
- */
- public static SignaturePlaceholderData getNextUnusedSignaturePlaceHolder(PDDocument doc) {
- try {
- String placeholderId = "1";
- int mode = PlaceholderExtractorConstants.PLACEHOLDER_MATCH_MODE_SORTED;
- SignaturePlaceholderExtractor signaturePlaceholderExtractor = new SignaturePlaceholderExtractor( placeholderId,
- mode, doc);
- List<SignaturePlaceholderData> results = signaturePlaceholderExtractor.extractList(doc, placeholderId,
- mode);
- if (results == null) {
- return null;
- }
- List<String> used = getExistingSignatureLocations(doc);
- //return first not used
- for(SignaturePlaceholderData result : results) {
- if(!used.contains(result.getPlaceholderName()))
- return result;
- }
- return null;
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- }
-
- public static SignaturePlaceholderData getSignaturePlaceHolder(PDDocument doc, String placeholderId,
- int mode) {
- try {
- SignaturePlaceholderExtractor signaturePlaceholderExtractor = new SignaturePlaceholderExtractor( placeholderId,
- mode, doc);
- return signaturePlaceholderExtractor.extract(doc, placeholderId, mode);
- } catch (Exception e) {
- e.printStackTrace();
- return null;
+ // Search for empty signature fields
+ public static List<String> findEmptySignatureFields(PDDocument doc) {
+ PDSignature signature;
+ List<PDField> signatureField;
+ final List<String> signatureFieldNames = new ArrayList<>();
+ final PDAcroForm acroForm = doc.getDocumentCatalog().getAcroForm();
+ if (acroForm != null) {
+ signatureField = acroForm.getFields();
+ for (final PDField pdField : signatureField) {
+ if (pdField instanceof PDSignatureField && pdField.getPartialName() != null) {
+ signature = ((PDSignatureField) pdField).getSignature();
+ if (signature == null) {
+ signatureFieldNames.add(pdField.getPartialName());
+ }
}
+ }
}
-
- public static List<SignaturePlaceholderData> getSignaturePlaceHolderList(PDDocument doc, String placeholderId, int mode) {
- try {
- SignaturePlaceholderExtractor signaturePlaceholderExtractor = new SignaturePlaceholderExtractor( placeholderId,
- mode, doc);
- return signaturePlaceholderExtractor.extractList(doc, placeholderId, mode);
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- }
-
- public static List<String> getExistingSignatureLocations(PDDocument doc) {
- List<String> existingLocations = new ArrayList<>();
- try {
- List <PDSignature> pdSignatureList = doc.getSignatureDictionaries();
- if(pdSignatureList.size() != 0) {
- for(PDSignature sig : pdSignatureList) {
- existingLocations.add(sig.getLocation());
- }
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- return existingLocations;
+ return signatureFieldNames;
+ }
+ /*
+ * Needed by PDF-OVER
+ */
+
+ /**
+ * Returns the next unused signature placeholder
+ *
+ * @param doc The document to be searched for signature placeholders
+ * @return The next unused signature placeholder or null in case there is none
+ */
+ public static SignaturePlaceholderData getNextUnusedSignaturePlaceHolder(PDDocument doc) {
+ try {
+ final String placeholderId = "1";
+ final int mode = PlaceholderExtractorConstants.PLACEHOLDER_MATCH_MODE_SORTED;
+ final SignaturePlaceholderExtractor signaturePlaceholderExtractor = new SignaturePlaceholderExtractor();
+ return signaturePlaceholderExtractor.extract(doc, placeholderId, mode);
+
+ } catch (final Exception e) {
+ e.printStackTrace();
+ return null;
}
+ }
}
diff --git a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/placeholder/SignaturePlaceholderExtractor.java b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/placeholder/SignaturePlaceholderExtractor.java
index 6df4f0b1..7cff90d6 100644
--- a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/placeholder/SignaturePlaceholderExtractor.java
+++ b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/placeholder/SignaturePlaceholderExtractor.java
@@ -3,19 +3,19 @@
* 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
@@ -50,34 +50,27 @@ import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.image.BufferedImage;
import java.io.IOException;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Hashtable;
+import java.util.List;
import java.util.Map.Entry;
-
-import javassist.bytecode.stackmap.TypeData.ClassName;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Vector;
+import java.util.stream.Collectors;
import org.apache.pdfbox.contentstream.PDFStreamEngine;
import org.apache.pdfbox.contentstream.operator.Operator;
import org.apache.pdfbox.contentstream.operator.OperatorProcessor;
import org.apache.pdfbox.cos.COSBase;
-import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
-import org.apache.pdfbox.pdmodel.font.PDFont;
-import org.apache.pdfbox.pdmodel.font.PDFontFactory;
import org.apache.pdfbox.pdmodel.graphics.PDXObject;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
+import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
import org.apache.pdfbox.util.Matrix;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import at.gv.egiz.pdfas.common.exceptions.PDFIOException;
-import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
-import at.gv.egiz.pdfas.common.exceptions.PlaceholderExtractionException;
-import at.gv.egiz.pdfas.lib.impl.placeholder.PlaceholderExtractorConstants;
-import at.gv.egiz.pdfas.lib.impl.placeholder.SignaturePlaceholderContext;
-import at.gv.egiz.pdfas.lib.impl.placeholder.SignaturePlaceholderData;
-import at.knowcenter.wag.egov.egiz.pdf.TablePos;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
@@ -90,425 +83,432 @@ import com.google.zxing.Result;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
+import at.gv.egiz.pdfas.common.exceptions.PDFIOException;
+import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.common.exceptions.PlaceholderExtractionException;
+import at.gv.egiz.pdfas.lib.impl.placeholder.PlaceholderExtractorConstants;
+import at.gv.egiz.pdfas.lib.impl.placeholder.SignaturePlaceholderData;
+import at.knowcenter.wag.egov.egiz.pdf.TablePos;
+import javassist.bytecode.stackmap.TypeData.ClassName;
+import lombok.extern.slf4j.Slf4j;
+
/**
* Extract all relevant information from a placeholder image.
*
* @author exthex
*
*/
-public class SignaturePlaceholderExtractor extends PDFStreamEngine implements PlaceholderExtractorConstants{
- /**
- * The log.
- */
- private static Logger logger = LoggerFactory
- .getLogger(SignaturePlaceholderExtractor.class);
-
- private List<SignaturePlaceholderData> placeholders = new ArrayList<>();
- private int currentPage = 0;
- private PDDocument doc;
-
- protected SignaturePlaceholderExtractor(String placeholderId,
- int placeholderMatchMode, PDDocument doc) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
- super();
-
- final Properties properties = new Properties();
- properties.load(ClassName.class.getClassLoader().getResourceAsStream("placeholder/pdfbox-reader-2.properties"));
-
- Set<Entry<Object, Object>> entries = properties.entrySet();
- for(Entry<Object, Object> entry:entries){
- String processorClassName = (String)entry.getValue();
- Class<?> klass = Class.forName( processorClassName );
- org.apache.pdfbox.contentstream.operator.OperatorProcessor processor =
- (OperatorProcessor) klass.newInstance();
-
- addOperator( processor );
- }
- this.doc = doc;
- }
-
- /**
- * Search the document for placeholder images and possibly included
- * additional info.<br/>
- * Searches only for the first placeholder page after page from top.
- *
- * @return all available info from the first found placeholder.
- * @throws PdfAsException
- * if the document could not be read.
- * @throws PlaceholderExtractionException
- * if STRICT matching mode was requested and no suitable
- * placeholder could be found.
- */
- public SignaturePlaceholderData extract(PDDocument doc,
- String placeholderId, int matchMode) throws PdfAsException {
- SignaturePlaceholderContext.setSignaturePlaceholderData(null);
-// SignaturePlaceholderExtractor extractor;
-// try {
-// extractor = new SignaturePlaceholderExtractor(placeholderId,
-// matchMode, doc);
-// } catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException e2) {
-// throw new PDFIOException("error.pdf.io.04", e2);
-// }
-
- int pageNr = 0;
- for(PDPage page : doc.getPages()){
- pageNr++;
-
- try {
- setCurrentPage(pageNr);
- if(page.getContents() != null && page.getResources() != null && page.getContentStreams() != null) {
- processPage(page); //TODO: pdfbox2 - right?
-
- }
- SignaturePlaceholderData ret = matchPlaceholderPage(
- placeholders, placeholderId, matchMode);
- if (ret != null) {
- SignaturePlaceholderContext
- .setSignaturePlaceholderData(ret);
- return ret;
- }
- } catch (IOException e1) {
- throw new PDFIOException("error.pdf.io.04", e1);
- } catch(Throwable e) {
- throw new PDFIOException("error.pdf.io.04", e);
- }
- }
- if (placeholders.size() > 0) {
- SignaturePlaceholderData ret = matchPlaceholderDocument(
- placeholders, placeholderId, matchMode);
- SignaturePlaceholderContext.setSignaturePlaceholderData(ret);
- return ret;
- }
- // no placeholders found, apply strict mode if set
- if (matchMode == PLACEHOLDER_MATCH_MODE_STRICT) {
- throw new PlaceholderExtractionException("error.pdf.stamp.09");
- }
-
- return null;
- }
-
- public List<SignaturePlaceholderData> extractList(PDDocument doc,
- String placeholderId, int matchMode) throws PdfAsException {
- SignaturePlaceholderContext.setSignaturePlaceholderData(null);
-
- int pageNr = 0;
- for(PDPage page : doc.getPages()){
- pageNr++;
-
- try {
- setCurrentPage(pageNr);
- if(page.getContents() != null && page.getResources() != null && page.getContentStreams() != null) {
- processPage(page); //TODO: pdfbox2 - right?
-
- }
- SignaturePlaceholderData ret = matchPlaceholderPage(
- placeholders, placeholderId, matchMode);
- if (ret != null) {
- SignaturePlaceholderContext
- .setSignaturePlaceholderData(ret);
- return placeholders;
- }
- } catch (IOException e1) {
- throw new PDFIOException("error.pdf.io.04", e1);
- } catch(Throwable e) {
- throw new PDFIOException("error.pdf.io.04", e);
- }
- }
- if (placeholders.size() > 0) {
- SignaturePlaceholderData ret = matchPlaceholderDocument(
- placeholders, placeholderId, matchMode);
- SignaturePlaceholderContext.setSignaturePlaceholderData(ret);
- return placeholders;
- }
- // no placeholders found, apply strict mode if set
- if (matchMode == PLACEHOLDER_MATCH_MODE_STRICT) {
- throw new PlaceholderExtractionException("error.pdf.stamp.09");
- }
- return null;
- }
-
- private SignaturePlaceholderData matchPlaceholderDocument(
- List<SignaturePlaceholderData> placeholders, String placeholderId,
- int matchMode) throws PlaceholderExtractionException {
-
- if (matchMode == PLACEHOLDER_MATCH_MODE_STRICT)
- throw new PlaceholderExtractionException("error.pdf.stamp.09");
-
- if (placeholders.size() == 0)
- return null;
-
- if (matchMode == PLACEHOLDER_MATCH_MODE_SORTED) {
- // sort all placeholders by the id string if all ids are null do nothing
- SignaturePlaceholderData currentFirstSpd = null;
- for (int i = 0; i < placeholders.size(); i++) {
- SignaturePlaceholderData spd = placeholders.get(i);
- if (spd.getId() != null) {
- if(currentFirstSpd == null) {
- currentFirstSpd = spd;
- logger.debug("Setting new current ID: {}",
- currentFirstSpd.getId());
- } else {
- String currentID = currentFirstSpd.getId();
- String testID = spd.getId();
- logger.debug("Testing placeholder current: {} compare to {}",
- currentID, testID);
- if(testID.compareToIgnoreCase(currentID) < 0) {
- currentFirstSpd = spd;
- logger.debug("Setting new current ID: {}",
- testID);
- }
- }
- }
- }
-
- if(currentFirstSpd != null) {
- logger.info("Running Placeholder sorted mode: using id: {}", currentFirstSpd.getId());
- return currentFirstSpd;
- } else {
- logger.info("Running Placeholder sorted mode: no placeholder with id found, fallback to first placeholder");
- }
- }
-
- for (int i = 0; i < placeholders.size(); i++) {
- SignaturePlaceholderData spd = placeholders.get(i);
- if (spd.getId() == null)
- return spd;
- }
-
- if (matchMode == PLACEHOLDER_MATCH_MODE_LENIENT)
- return placeholders.get(0);
-
- return null;
- }
-
- private SignaturePlaceholderData matchPlaceholderPage(
- List<SignaturePlaceholderData> placeholders, String placeholderId,
- int matchMode) {
-
- if(matchMode == PLACEHOLDER_MATCH_MODE_SORTED)
- return null;
-
- if (placeholders.size() == 0)
- return null;
- for (int i = 0; i < placeholders.size(); i++) {
- SignaturePlaceholderData data = placeholders.get(i);
- if (placeholderId != null && placeholderId.equals(data.getId()))
- return data;
- if (placeholderId == null && data.getId() == null)
- return data;
- }
- return null;
- }
-
-
-
- private void setCurrentPage(int pageNr) {
- this.currentPage = pageNr;
- }
-
- @Override
- protected void processOperator(Operator operator, List<COSBase> arguments)
- throws IOException {
- String operation = operator.getName();
- if (operation.equals("Do")) {
- COSName objectName = (COSName) arguments.get(0);
- PDXObject xobject = (PDXObject) getResources().getXObject(objectName);
- if (xobject instanceof PDImageXObject) {
- try {
- PDImageXObject image = (PDImageXObject) xobject;
- SignaturePlaceholderData data = checkImage(image);
- if (data != null) {
- PDPage page = getCurrentPage();
- Matrix ctm = getGraphicsState()
- .getCurrentTransformationMatrix();
- int pageRotation = page.getRotation();
- pageRotation = pageRotation % 360;
- double rotationInRadians = Math.toRadians(pageRotation);//(page.findRotation() * Math.PI) / 180;
-
- AffineTransform rotation = new AffineTransform();
- rotation.setToRotation(rotationInRadians);
- AffineTransform rotationInverse = rotation
- .createInverse();
- Matrix rotationInverseMatrix = new Matrix();
- rotationInverseMatrix
- .setFromAffineTransform(rotationInverse);
- Matrix rotationMatrix = new Matrix();
- rotationMatrix.setFromAffineTransform(rotation);
-
- Matrix unrotatedCTM = ctm
- .multiply(rotationInverseMatrix);
-
- float x = unrotatedCTM.getXPosition();
- float yPos = unrotatedCTM.getYPosition();
- float yScale = unrotatedCTM.getScaleY();
- float y = yPos + yScale;
- float w = unrotatedCTM.getScaleX();
-
- logger.debug("Page height: {}", page.getCropBox().getHeight());
- logger.debug("Page width: {}", page.getCropBox().getWidth());
-
- if(pageRotation == 90) {
- y = page.getCropBox().getWidth() - (y * (-1));
- } else if(pageRotation == 180) {
- x = page.getCropBox().getWidth() + x;
- y = page.getCropBox().getHeight() - (y * (-1));
- } else if(pageRotation == 270) {
- x = page.getCropBox().getHeight() + x;
- }
-
- String posString = "p:" + currentPage + ";x:" + x
- + ";y:" + y + ";w:" + w;
-
- logger.debug("Found Placeholder at: {}", posString);
- try {
- data.setTablePos(new TablePos(posString));
- data.setPlaceholderName(objectName.getName());
- placeholders.add(data);
- } catch (PdfAsException e) {
- throw new IOException();
- }
- }
- } catch (NoninvertibleTransformException e) {
- throw new IOException(e);
- }
- }
- } else {
- super.processOperator(operator, arguments);
- }
- }
-
- private Map<String, PDFont> fonts;
-
- //TODO: pdfbox2 - was override
- public Map<String, PDFont> getFonts() {
- if (fonts == null) {
- // at least an empty map will be returned
- // TODO we should return null instead of an empty map
- fonts = new HashMap<String, PDFont>();
- if(this.getResources() != null && this.getResources().getCOSObject() != null) {
- COSDictionary fontsDictionary = (COSDictionary) this.getResources().getCOSObject().getDictionaryObject(COSName.FONT);
- if (fontsDictionary == null) {
- // ignore we do not want to set anything, never when creating a signature!!!!!
- //fontsDictionary = new COSDictionary();
- //this.getResources().getCOSDictionary().setItem(COSName.FONT, fontsDictionary);
+@Slf4j
+public class SignaturePlaceholderExtractor extends PDFStreamEngine implements PlaceholderExtractorConstants {
+
+ private final List<SignaturePlaceholderData> placeholders = new ArrayList<>();
+ private int currentPage = 0;
+
+ protected SignaturePlaceholderExtractor() throws IOException, ClassNotFoundException,
+ InstantiationException, IllegalAccessException {
+ super();
+
+ final Properties properties = new Properties();
+ properties.load(ClassName.class.getClassLoader().getResourceAsStream(
+ "placeholder/pdfbox-reader-2.properties"));
+
+ final Set<Entry<Object, Object>> entries = properties.entrySet();
+ for (final Entry<Object, Object> entry : entries) {
+ final String processorClassName = (String) entry.getValue();
+ final Class<?> klass = Class.forName(processorClassName);
+ final org.apache.pdfbox.contentstream.operator.OperatorProcessor processor =
+ (OperatorProcessor) klass.newInstance();
+
+ addOperator(processor);
+
+ }
+ }
+
+ /**
+ * Search the document for placeholder images and possibly included additional
+ * info.<br/>
+ * Searches only for the first placeholder page after page from top.
+ *
+ * @return available info from the first found placeholder.
+ * @throws PdfAsException if the document could not be read.
+ * @throws PlaceholderExtractionException if STRICT matching mode was requested
+ * and no suitable placeholder could be
+ * found.
+ */
+ public SignaturePlaceholderData extract(PDDocument doc,
+ String placeholderId, int matchMode) throws PdfAsException {
+
+ List<String> extistingSignatureNames = existingExistingSignatureNames(doc);
+
+
+ int pageNr = 0;
+ for (final PDPage page : doc.getPages()) {
+ pageNr++;
+
+ try {
+ this.currentPage = pageNr;
+ if (page.getContents() != null && page.getResources() != null && page.getContentStreams() != null) {
+ processPage(page); // TODO: pdfbox2 - right?
+
+ }
+
+ final SignaturePlaceholderData ret = matchPlaceholderPage(
+ removeAlreadyUsePlaceholders(placeholders, extistingSignatureNames), placeholderId, matchMode);
+ if (ret != null) {
+ return ret;
+
+ }
+
+ } catch (final IOException e1) {
+ throw new PDFIOException("error.pdf.io.04", e1);
+
+ } catch (final Throwable e) {
+ throw new PDFIOException("error.pdf.io.04", e);
+
+ }
+ }
+
+ if (placeholders.size() > 0) {
+ final SignaturePlaceholderData ret = matchPlaceholderDocument(
+ removeAlreadyUsePlaceholders(placeholders, extistingSignatureNames), placeholderId, matchMode);
+ return ret;
+
+ }
+ // no placeholders found, apply strict mode if set
+ if (matchMode == PLACEHOLDER_MATCH_MODE_STRICT) {
+ throw new PlaceholderExtractionException("error.pdf.stamp.09");
+
+ }
+ return null;
+ }
+
+ @Override
+ protected void processOperator(Operator operator, List<COSBase> arguments)
+ throws IOException {
+ final String operation = operator.getName();
+ if (operation.equals("Do")) {
+ final COSName objectName = (COSName) arguments.get(0);
+ final PDXObject xobject = getResources().getXObject(objectName);
+ if (xobject instanceof PDImageXObject) {
+ try {
+ final PDImageXObject image = (PDImageXObject) xobject;
+ final SignaturePlaceholderData data = checkImage(image);
+ if (data != null) {
+ final PDPage page = getCurrentPage();
+ final Matrix ctm = getGraphicsState()
+ .getCurrentTransformationMatrix();
+ int pageRotation = page.getRotation();
+ pageRotation = pageRotation % 360;
+ final double rotationInRadians = Math.toRadians(pageRotation);// (page.findRotation() * Math.PI) /
+ // 180;
+
+ final AffineTransform rotation = new AffineTransform();
+ rotation.setToRotation(rotationInRadians);
+ final AffineTransform rotationInverse = rotation
+ .createInverse();
+ final Matrix rotationInverseMatrix = new Matrix();
+ rotationInverseMatrix
+ .setFromAffineTransform(rotationInverse);
+ final Matrix rotationMatrix = new Matrix();
+ rotationMatrix.setFromAffineTransform(rotation);
+
+ final Matrix unrotatedCTM = ctm
+ .multiply(rotationInverseMatrix);
+
+ float x = unrotatedCTM.getXPosition();
+ final float yPos = unrotatedCTM.getYPosition();
+ final float yScale = unrotatedCTM.getScaleY();
+ float y = yPos + yScale;
+ final float w = unrotatedCTM.getScaleX();
+
+ log.debug("Page height: {}", page.getCropBox().getHeight());
+ log.debug("Page width: {}", page.getCropBox().getWidth());
+
+ if (pageRotation == 90) {
+ y = page.getCropBox().getWidth() - y * -1;
+ } else if (pageRotation == 180) {
+ x = page.getCropBox().getWidth() + x;
+ y = page.getCropBox().getHeight() - y * -1;
+ } else if (pageRotation == 270) {
+ x = page.getCropBox().getHeight() + x;
}
- else {
- for (COSName fontName : fontsDictionary.keySet()) {
- COSBase font = fontsDictionary.getDictionaryObject(fontName);
- // data-000174.pdf contains a font that is a COSArray, looks to be an error in the
- // PDF, we will just ignore entries that are not dictionaries.
- if (font instanceof COSDictionary) {
- PDFont newFont = null;
- try {
- newFont = PDFontFactory.createFont((COSDictionary) font);
- }
- catch (IOException exception) {
- logger.error("error while creating a font", exception);
- }
- if (newFont != null) {
- fonts.put(fontName.getName(), newFont);
- }
- }
- }
+
+ final String posString = "p:" + currentPage + ";x:" + Math.floor(x)
+ + ";y:" + Math.ceil(y) + ";w:" + Math.ceil(w);
+
+ log.debug("Found Placeholder at: {}", posString);
+ try {
+ data.setTablePos(new TablePos(posString));
+ data.setPlaceholderName(objectName.getName());
+ placeholders.add(data);
+
+ } catch (final PdfAsException e) {
+ throw new IOException();
+
}
+ }
+ } catch (final NoninvertibleTransformException e) {
+ throw new IOException(e);
+ }
+ }
+ } else {
+ super.processOperator(operator, arguments);
+ }
+ }
+
+ private SignaturePlaceholderData matchPlaceholderPage(
+ List<SignaturePlaceholderData> placeholders, String placeholderId, int matchMode) {
+ log.debug("Searching requested placeholder:{} with matchMode:{} in single page ... ", placeholderId, matchMode);
+
+ if (placeholders.size() == 0) {
+ return null;
+
+ }
+
+ // check if find a placeholder with that ID
+ for (final SignaturePlaceholderData data : placeholders) {
+ if (placeholderId != null && data.getId() != null
+ && matchPlaceHolderId(placeholderId, data.getId())) {
+ return data;
+
+ }
+
+ if (matchMode != PLACEHOLDER_MATCH_MODE_SORTED
+ && placeholderId == null && data.getId() == null) {
+ return data;
+
+ }
+ }
+
+ return null;
+ }
+
+ private SignaturePlaceholderData matchPlaceholderDocument(
+ List<SignaturePlaceholderData> placeholders, String placeholderId,
+ int matchMode) throws PlaceholderExtractionException {
+
+ log.debug("Searching requested placeholder:{} with matchMode:{} on any page ... ", placeholderId, matchMode);
+
+ if (matchMode == PLACEHOLDER_MATCH_MODE_STRICT) {
+ throw new PlaceholderExtractionException("error.pdf.stamp.09");
+ }
+
+ if (placeholders.size() == 0) {
+ return null;
+ }
+
+ if (matchMode == PLACEHOLDER_MATCH_MODE_SORTED) {
+ // sort all placeholders by the id string if all ids are null do nothing
+ SignaturePlaceholderData currentFirstSpd = null;
+ for (final SignaturePlaceholderData spd : placeholders) {
+ if (spd.getId() != null) {
+ if (currentFirstSpd == null) {
+ currentFirstSpd = spd;
+ log.debug("Setting new current ID: {}",
+ currentFirstSpd.getId());
+ } else {
+ currentFirstSpd = placeHolderIdMatcher(currentFirstSpd, spd);
+
+ }
+ }
+ }
+
+ if (currentFirstSpd != null) {
+ log.info("Running Placeholder sorted mode: using id: {}", currentFirstSpd.getId());
+ return currentFirstSpd;
+
+ } else {
+ log.info(
+ "Running Placeholder sorted mode: no placeholder with id found, fallback to first placeholder");
+ }
+ }
+
+ for (final SignaturePlaceholderData spd : placeholders) {
+ if (spd.getId() == null) {
+ return spd;
+ }
+ }
+
+ if (matchMode == PLACEHOLDER_MATCH_MODE_LENIENT) {
+ return placeholders.get(0);
+ }
+
+ return null;
+ }
+
+ private boolean matchPlaceHolderId(String first, String second) {
+ try {
+ Integer firstIdInt = Integer.valueOf(first);
+ Integer secondIdInt = Integer.valueOf(second);
+ return firstIdInt == secondIdInt;
+
+ } catch (NumberFormatException e) {
+ log.trace("Can not compare placeholderId's on integer level. Using String compare ... ");
+ return first.equalsIgnoreCase(second);
+
+ }
+
+ }
+
+ private SignaturePlaceholderData placeHolderIdMatcher(SignaturePlaceholderData currentFirstSpd,
+ SignaturePlaceholderData spd) {
+ try {
+ Integer currentIDInt = Integer.valueOf(currentFirstSpd.getId());
+ Integer testIDInt = Integer.valueOf(spd.getId());
+
+ if (testIDInt < currentIDInt) {
+ log.debug("Setting new current ID: {}", testIDInt);
+ return spd;
+
+ } else {
+ return currentFirstSpd;
+
+ }
+ } catch (NumberFormatException e) {
+ log.trace("Can not compare placeholderId's on integer level. Using String compare ... ");
+ final String currentID = currentFirstSpd.getId();
+ final String testID = spd.getId();
+ log.debug("Testing placeholder current: {} compare to {}",
+ currentID, testID);
+ if (testID.compareToIgnoreCase(currentID) < 0) {
+ log.debug("Setting new current ID: {}",
+ testID);
+ return spd;
+
+ } else {
+ return currentFirstSpd;
+
+ }
+ }
+ }
+
+ private List<String> existingExistingSignatureNames(PDDocument doc) {
+ final List<String> existingLocations = new ArrayList<>();
+ try {
+ final List<PDSignature> pdSignatureList = doc.getSignatureDictionaries();
+ if (pdSignatureList.size() != 0) {
+ for (final PDSignature sig : pdSignatureList) {
+ existingLocations.add(sig.getLocation());
+ }
+ }
+ } catch (final IOException e) {
+ e.printStackTrace();
+ }
+ return existingLocations;
+ }
+
+ private List<SignaturePlaceholderData> removeAlreadyUsePlaceholders(
+ List<SignaturePlaceholderData> placeholders, List<String> existingPlaceholders) {
+ if (placeholders != null) {
+ List<SignaturePlaceholderData> result = placeholders.stream()
+ .filter(el -> !existingPlaceholders.contains(el.getPlaceholderName()))
+ .collect(Collectors.toList());
+ log.debug("Initial found #{} placeholders, but #{} removed because already used.",
+ placeholders.size(), placeholders.size() - result.size());
+ return result;
+
+ } else {
+ return Collections.emptyList();
+
+ }
+ }
+
+ /**
+ * Checks an image if it is a placeholder for a signature.
+ *
+ * @param image
+ * @return
+ * @throws IOException
+ */
+ private SignaturePlaceholderData checkImage(PDImageXObject image)
+ throws IOException {
+ final BufferedImage bimg = image.getImage();
+ if (bimg == null) {
+ String type = image.getSuffix();
+ if (type != null) {
+ type = type.toUpperCase() + " images";
+ } else {
+ type = "Image type";
+ }
+ log.info("Unable to extract image for QRCode analysis. "
+ + type
+ + " not supported. Add additional JAI Image filters to your classpath. Refer to https://jai.dev.java.net. Skipping image.");
+ return null;
+
+ }
+
+ if (bimg.getHeight() < 10 || bimg.getWidth() < 10) {
+ log.debug("Image too small for QRCode. Skipping image.");
+ return null;
+ }
+
+ final LuminanceSource source = new BufferedImageLuminanceSource(bimg);
+ final BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
+ Result result;
+ final long before = System.currentTimeMillis();
+ try {
+ final Hashtable<DecodeHintType, Object> hints = new Hashtable<>();
+ final Vector<BarcodeFormat> formats = new Vector<>();
+ formats.add(BarcodeFormat.QR_CODE);
+ hints.put(DecodeHintType.POSSIBLE_FORMATS, formats);
+ result = new MultiFormatReader().decode(bitmap, hints);
+
+ final String text = result.getText();
+ String profile = null;
+ String type = null;
+ String sigKey = null;
+ String id = null;
+ if (text != null) {
+ if (text.startsWith(QR_PLACEHOLDER_IDENTIFIER)) {
+
+ final String[] data = text.split(";");
+ if (data.length > 1) {
+ for (int i = 1; i < data.length; i++) {
+ final String kvPair = data[i];
+ final String[] kv = kvPair.split("=");
+ if (kv.length != 2) {
+ log.debug("Invalid parameter in placeholder data: "
+ + kvPair);
+ } else {
+ if (kv[0]
+ .equalsIgnoreCase(SignaturePlaceholderData.ID_KEY)) {
+ id = kv[1];
+ } else if (kv[0]
+ .equalsIgnoreCase(SignaturePlaceholderData.PROFILE_KEY)) {
+ profile = kv[1];
+ } else if (kv[0]
+ .equalsIgnoreCase(SignaturePlaceholderData.SIG_KEY_KEY)) {
+ sigKey = kv[1];
+ } else if (kv[0]
+ .equalsIgnoreCase(SignaturePlaceholderData.TYPE_KEY)) {
+ type = kv[1];
+ }
+ }
}
+ }
+ return new SignaturePlaceholderData(profile, type, sigKey,
+ id);
+ } else {
+ log.warn("QR-Code found but does not start with \""
+ + QR_PLACEHOLDER_IDENTIFIER
+ + "\". Ignoring QR placeholder.");
+ }
+ }
+ } catch (final ReaderException re) {
+ if (log.isDebugEnabled()) {
+ log.debug("Could not decode - not a placeholder. needed: "
+ + (System.currentTimeMillis() - before));
+ }
+ if (!(re instanceof NotFoundException)) {
+ if (log.isInfoEnabled()) {
+ log.info("Failed to decode image", re);
}
- return fonts;
- }
-
- /**
- * Checks an image if it is a placeholder for a signature.
- *
- * @param image
- * @return
- * @throws IOException
- */
- private SignaturePlaceholderData checkImage(PDImageXObject image)
- throws IOException {
- BufferedImage bimg = image.getImage();
- if (bimg == null) {
- String type = image.getSuffix();
- if (type != null) {
- type = type.toUpperCase() + " images";
- } else {
- type = "Image type";
- }
- logger.info("Unable to extract image for QRCode analysis. "
- + type
- + " not supported. Add additional JAI Image filters to your classpath. Refer to https://jai.dev.java.net. Skipping image.");
- return null;
- }
- if (bimg.getHeight() < 10 || bimg.getWidth() < 10) {
- logger.debug("Image too small for QRCode. Skipping image.");
- return null;
- }
-
- LuminanceSource source = new BufferedImageLuminanceSource(bimg);
- BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
- Result result;
- long before = System.currentTimeMillis();
- try {
- Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();
- Vector<BarcodeFormat> formats = new Vector<BarcodeFormat>();
- formats.add(BarcodeFormat.QR_CODE);
- hints.put(DecodeHintType.POSSIBLE_FORMATS, formats);
- result = new MultiFormatReader().decode(bitmap, hints);
-
- String text = result.getText();
- String profile = null;
- String type = null;
- String sigKey = null;
- String id = null;
- if (text != null) {
- if (text.startsWith(QR_PLACEHOLDER_IDENTIFIER)) {
-
- String[] data = text.split(";");
- if (data.length > 1) {
- for (int i = 1; i < data.length; i++) {
- String kvPair = data[i];
- String[] kv = kvPair.split("=");
- if (kv.length != 2) {
- logger.debug("Invalid parameter in placeholder data: "
- + kvPair);
- } else {
- if (kv[0]
- .equalsIgnoreCase(SignaturePlaceholderData.ID_KEY)) {
- id = kv[1];
- } else if (kv[0]
- .equalsIgnoreCase(SignaturePlaceholderData.PROFILE_KEY)) {
- profile = kv[1];
- } else if (kv[0]
- .equalsIgnoreCase(SignaturePlaceholderData.SIG_KEY_KEY)) {
- sigKey = kv[1];
- } else if (kv[0]
- .equalsIgnoreCase(SignaturePlaceholderData.TYPE_KEY)) {
- type = kv[1];
- }
- }
- }
- }
- return new SignaturePlaceholderData(profile, type, sigKey,
- id);
- } else {
- logger.warn("QR-Code found but does not start with \""
- + QR_PLACEHOLDER_IDENTIFIER
- + "\". Ignoring QR placeholder.");
- }
- }
- } catch (ReaderException re) {
- if (logger.isDebugEnabled()) {
- logger.debug("Could not decode - not a placeholder. needed: "
- + (System.currentTimeMillis() - before));
- }
- if (!(re instanceof NotFoundException)) {
- if (logger.isInfoEnabled()) {
- logger.info("Failed to decode image", re);
- }
- }
- } catch (ArrayIndexOutOfBoundsException e) {
- if (logger.isInfoEnabled()) {
- logger.info("Failed to decode image. Probably a zxing bug", e);
- }
- }
- return null;
- }
+ }
+ } catch (final ArrayIndexOutOfBoundsException e) {
+ if (log.isInfoEnabled()) {
+ log.info("Failed to decode image. Probably a zxing bug", e);
+ }
+ }
+ return null;
+ }
}
diff --git a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/positioning/Positioning.java b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/positioning/Positioning.java
index 13d1ebe6..d1d097aa 100644
--- a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/positioning/Positioning.java
+++ b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/positioning/Positioning.java
@@ -32,7 +32,9 @@ import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
+import at.gv.egiz.pdfas.common.settings.IProfileConstants;
import at.gv.egiz.pdfas.common.settings.ISettings;
+import at.gv.egiz.pdfas.common.settings.SignatureProfileSettings;
import at.gv.egiz.pdfas.lib.api.IConfigurationConstants;
import at.gv.egiz.pdfas.lib.impl.pdfbox2.utils.PdfBoxUtils;
import at.gv.egiz.pdfas.lib.impl.stamping.IPDFVisualObject;
@@ -64,18 +66,18 @@ public class Positioning {
*
* @param pos The absolute positioning parameter. If null it is
* sought in the profile definition.
- * @param signature_type The profile definition of the table to be written.
* @param pdfDataSource The pdf.
* @param pdf_table The pdf table to be written.
* @param settings
+ * @param signatureProfileSettings Signature-block settings
* @return Returns the PositioningInformation.
* @throws PdfAsException F.e.
*/
public static PositioningInstruction determineTablePositioning(
- TablePos pos, String signature_type, PDDocument pdfDataSource,
- IPDFVisualObject pdf_table, ISettings settings) throws PdfAsException {
+ TablePos pos, PDDocument pdfDataSource,
+ IPDFVisualObject pdf_table, ISettings settings, SignatureProfileSettings signatureProfileSettings) throws PdfAsException {
return adjustSignatureTableandCalculatePosition(pdfDataSource,
- pdf_table, pos, settings);
+ pdf_table, pos, settings, signatureProfileSettings);
}
/**
@@ -85,12 +87,13 @@ public class Positioning {
* @param pdfDataSource The PDF document.
* @param pdf_table The PDFPTable to be placed.
* @param settings
+ * @param profilConfig Signature-profile configuration
* @return Returns the position where the PDFPTable should be placed.
* @throws PdfAsException F.e.
*/
public static PositioningInstruction adjustSignatureTableandCalculatePosition(
final PDDocument pdfDataSource, IPDFVisualObject pdf_table,
- TablePos pos, ISettings settings) throws PdfAsException {
+ TablePos pos, ISettings settings, SignatureProfileSettings profilConfig) throws PdfAsException {
PdfBoxUtils.checkPDFPermissions(pdfDataSource);
final long numberOfExistingSignatures = getNumberOfExistingSignatures(pdfDataSource);
@@ -111,15 +114,9 @@ public class Positioning {
}
}
- make_new_page = checkIfNewPageIsAllowed(make_new_page, numberOfExistingSignatures, settings);
-
-
- if(make_new_page && numberOfExistingSignatures!=0) {
- make_new_page = false;
-
- }
-
+ make_new_page = checkIfNewPageIsAllowed(make_new_page, numberOfExistingSignatures, settings, profilConfig);
+
final PDPage pdPage = pdfDataSource.getPage(page - 1);
PDRectangle cropBox = pdPage.getCropBox();
@@ -216,13 +213,13 @@ public class Positioning {
// we do have an empty page or nothing in area above footerline
pos_y = page_height - SIGNATURE_MARGIN_VERTICAL;
return buildPostitionInfoOnSubpage(pdfDataSource, make_new_page, page, pos_x, pos_y, pos.rotation,
- pos.getFooterLine(), table_height, pos, page_height, numberOfExistingSignatures, settings);
+ pos.getFooterLine(), table_height, pos, page_height, numberOfExistingSignatures, settings, profilConfig);
} else {
// we do have text take SIGNATURE_MARGIN
pos_y = page_height - pre_page_length - SIGNATURE_MARGIN_VERTICAL;
return buildPostitionInfoOnSubpage(pdfDataSource, make_new_page, page, pos_x, pos_y, pos.rotation,
- pos.getFooterLine(), table_height, pos, page_height, numberOfExistingSignatures, settings);
+ pos.getFooterLine(), table_height, pos, page_height, numberOfExistingSignatures, settings, profilConfig);
}
}
@@ -245,12 +242,23 @@ public class Positioning {
}
- private static boolean checkIfNewPageIsAllowed(boolean make_new_page, long numberOfExistingSignatures, ISettings settings) throws PdfAsException {
- if(make_new_page && numberOfExistingSignatures!=0) {
- log.info("Signature-block would be need a new page, but new pages are not allowed on already signed documents.");
- if (isFailOnLessSpaceEnabled(settings)) {
- throw new PdfAsException("error.pdf.stamp.12");
+ private static boolean isNewPageOnSignedDocumentsEnabled(SignatureProfileSettings profilConfig) {
+ String value = profilConfig.getValue(IProfileConstants.SIG_NEWPAGE_FORCE);
+ return Boolean.valueOf(value);
+
+ }
+
+ private static boolean checkIfNewPageIsAllowed(boolean make_new_page, long numberOfExistingSignatures, ISettings settings,
+ SignatureProfileSettings profilConfig) throws PdfAsException {
+ if(make_new_page && numberOfExistingSignatures !=0 ) {
+ log.debug("Signature-block would be need a new page, but new pages are not allowed on already signed documents.");
+ if (isNewPageOnSignedDocumentsEnabled(profilConfig)) {
+ log.info("New pages not allowed on already signed documents, but force new page by configuration");
+ return make_new_page;
+ } else if (isFailOnLessSpaceEnabled(settings)) {
+ throw new PdfAsException("error.pdf.stamp.12");
+
} else {
log.info("Placing signature-block on last page without free-space checks ... ");
return false;
@@ -265,10 +273,10 @@ public class Positioning {
private static PositioningInstruction buildPostitionInfoOnSubpage(PDDocument pdfDataSource, boolean make_new_page, int page, float pos_x,
float pos_y, float rotation, float footer_line, float table_height, TablePos pos, float page_height,
- long numberOfExistingSignatures, ISettings settings) throws PdfAsException {
+ long numberOfExistingSignatures, ISettings settings, SignatureProfileSettings profilConfig) throws PdfAsException {
if (pos_y - footer_line <= table_height) {
- make_new_page = checkIfNewPageIsAllowed(true, numberOfExistingSignatures, settings);
+ make_new_page = checkIfNewPageIsAllowed(pos.isPauto(), numberOfExistingSignatures, settings, profilConfig);
if (make_new_page) {
page++;
diff --git a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox2/PADESPDFBOXSigner.java b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox2/PADESPDFBOXSigner.java
index 42f16598..36d7dade 100644
--- a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox2/PADESPDFBOXSigner.java
+++ b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox2/PADESPDFBOXSigner.java
@@ -70,8 +70,6 @@ import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.xmpbox.XMPMetadata;
import org.apache.xmpbox.schema.PDFAIdentificationSchema;
import org.apache.xmpbox.xml.DomXmpParser;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import at.gv.egiz.pdfas.common.exceptions.PDFASError;
import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
@@ -83,7 +81,6 @@ import at.gv.egiz.pdfas.lib.api.sign.IPlainSigner;
import at.gv.egiz.pdfas.lib.api.sign.SignParameter;
import at.gv.egiz.pdfas.lib.impl.ErrorExtractor;
import at.gv.egiz.pdfas.lib.impl.SignaturePositionImpl;
-import at.gv.egiz.pdfas.lib.impl.configuration.PlaceholderWebConfiguration;
import at.gv.egiz.pdfas.lib.impl.configuration.SignatureProfileConfiguration;
import at.gv.egiz.pdfas.lib.impl.pdfbox2.PDFBOXObject;
import at.gv.egiz.pdfas.lib.impl.pdfbox2.positioning.Positioning;
@@ -107,231 +104,123 @@ import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction;
import at.knowcenter.wag.egov.egiz.pdf.TablePos;
import at.knowcenter.wag.egov.egiz.table.Table;
import iaik.x509.X509Certificate;
+import lombok.extern.slf4j.Slf4j;
+@Slf4j
public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {
- private static final Logger logger = LoggerFactory.getLogger(PADESPDFBOXSigner.class);
- private boolean isAdobeSigForm = false;
+
@Override
public void signPDF(PDFObject genericPdfObject, RequestedSignature requestedSignature,
PDFASSignatureInterface genericSigner) throws PdfAsException {
- PDFAsVisualSignatureProperties properties = null;
- List<SignaturePlaceholderData> placeholders;
- List<SignaturePlaceholderData> availablePlaceholders;
- SignaturePlaceholderData signaturePlaceholderData = null;
-
- String placeholder_id = "";
-
- if (PlaceholderWebConfiguration.getValue(PLACEHOLDER_WEB_ID) != null && !PlaceholderWebConfiguration
- .getValue(PLACEHOLDER_WEB_ID).equalsIgnoreCase("")) {
- placeholder_id = PlaceholderWebConfiguration.getValue(PLACEHOLDER_WEB_ID);
- }
-
+
+ boolean isAdobeSigForm = false;
+
if (!(genericPdfObject instanceof PDFBOXObject)) {
- // tODO:
- throw new PdfAsException();
+ throw new PdfAsException("PDF to signObject is of wrong type: " + genericPdfObject.getClass().getName());
+
}
- final PDFBOXObject pdfObject = (PDFBOXObject) genericPdfObject;
-
if (!(genericSigner instanceof PDFASPDFBOXSignatureInterface)) {
- // tODO:
- throw new PdfAsException();
+ throw new PdfAsException("PDF signerObject is of wrong type:" + genericSigner.getClass().getName());
+
}
-
+
+ final PDFBOXObject pdfObject = (PDFBOXObject) genericPdfObject;
final PDFASPDFBOXSignatureInterface signer = (PDFASPDFBOXSignatureInterface) genericSigner;
- String pdfaVersion = null;
-
PDDocument doc = null;
SignatureOptions options = new SignatureOptions();
try {
-
doc = pdfObject.getDocument();
- // if signature already exists dont create new page
- final List<PDSignatureField> pdSignatureFieldList = doc.getSignatureFields();
- PDSignature signature;
+
// sign a PDF with an existing empty signature, as created by the
// CreateEmptySignatureForm example.
- String sigFieldName = pdfObject.getStatus().getSettings().getValue(SIGNATURE_FIELD_NAME);
- signature = findExistingSignature(doc, sigFieldName);
+ PDSignature signature = findExistingSignature(doc, getSignatureFieldNameConfig(pdfObject));
if (signature == null) {
// create signature dictionary
signature = new PDSignature();
+
} else {
isAdobeSigForm = true;
+
}
+ // set basic signature parameters
signature.setFilter(COSName.getPDFName(signer.getPDFFilter()));
signature.setSubFilter(COSName.getPDFName(signer.getPDFSubFilter()));
-// SignaturePlaceholderData signaturePlaceholderDataInit =
- placeholders = PlaceholderFilter.checkPlaceholderSignatureLocationList(pdfObject.getStatus(),
- pdfObject.getStatus().getSettings(), placeholder_id);
-
-// placeholders = SignaturePlaceholderExtractor.getPlaceholders();
- availablePlaceholders = listAvailablePlaceholders(placeholders, existingSignatureLocations(doc));
-
- if (placeholder_id.equalsIgnoreCase("")) {
- if (checkAvailablePlaceholders(placeholders, existingSignatureLocations(doc)) != null) {
- placeholder_id = checkAvailablePlaceholders(placeholders, existingSignatureLocations(doc)).getId();
- }
- }
-
- if (availablePlaceholders != null) {
- signaturePlaceholderData = PlaceholderFilter
- .checkPlaceholderSignatureLocation(pdfObject.getStatus(), pdfObject.getStatus().getSettings(),
- placeholder_id);
- }
-
- TablePos tablePos = null;
-
- if (signaturePlaceholderData != null) {
- signature.setLocation(signaturePlaceholderData.getPlaceholderName());
- }
-
- if (signaturePlaceholderData != null) {
- // Placeholder found!
- placeholders.clear();
- logger.info("Placeholder data found.");
- if (signaturePlaceholderData.getProfile() != null) {
- logger.debug("Placeholder Profile set to: " + signaturePlaceholderData.getProfile());
- requestedSignature.setSignatureProfileID(signaturePlaceholderData.getProfile());
- }
-
- tablePos = signaturePlaceholderData.getTablePos();
- if (tablePos != null) {
-
- final SignatureProfileConfiguration signatureProfileConfiguration = pdfObject.getStatus()
- .getSignatureProfileConfiguration(requestedSignature.getSignatureProfileID());
-
- final float minWidth = signatureProfileConfiguration.getMinWidth();
-
- if (minWidth > 0) {
- if (tablePos.getWidth() < minWidth) {
- tablePos.width = minWidth;
- logger.debug("Correcting placeholder with to minimum width {}", minWidth);
- }
+ signature.setSignDate(Calendar.getInstance());
+ log.debug("Signing @ " + signature.getSignDate().getTime().toString());
+
+ // extract next QR-code placeholder, if exists
+ SignaturePlaceholderData nextPlaceholderData = PlaceholderFilter.checkPlaceholderSignatureLocation(
+ pdfObject.getStatus(), pdfObject.getStatus().getSettings(),
+ pdfObject.getStatus().getSignParamter().getPlaceHolderId());
+
+ if (nextPlaceholderData != null) {
+ log.info("Placeholder data found.");
+ signature.setLocation(nextPlaceholderData.getPlaceholderName());
+
+ if (nextPlaceholderData.getProfile() != null) {
+ if (pdfObject.getStatus().getSettings().isValue(IConfigurationConstants.PLACEHOLDER_PROFILE_OVERWRITE, true)) {
+ log.debug("Placeholder Profile set to: {}", nextPlaceholderData.getProfile());
+ requestedSignature.setSignatureProfileID(nextPlaceholderData.getProfile());
+
+ } else {
+ log.debug("Placeholder profile over-write is disabled. Using profile from request ... ");
+
}
- logger.debug("Placeholder Position set to: " + tablePos.toString());
- }
- }
- final SignatureProfileSettings signatureProfileSettings = TableFactory.createProfile(
- requestedSignature.getSignatureProfileID(), pdfObject.getStatus().getSettings());
-
- // Check if input document is PDF-A conform
- if (signatureProfileSettings.isPDFA()) {
- final DataSource origDoc = pdfObject.getOriginalDocument();
- final InputStream stream = origDoc.getInputStream();
- // Run PreflightParser for checking conformity//
- // runPDFAPreflight(origDoc);
+ }
}
+
+
+ final SignatureProfileSettings signatureProfileSettings =
+ TableFactory.createProfile(requestedSignature.getSignatureProfileID(), pdfObject.getStatus().getSettings());
+
+ // set signature name
final ValueResolver resolver = new ValueResolver(requestedSignature, pdfObject.getStatus());
-
- final String signerName = resolver.resolve("SIG_SUBJECT", signatureProfileSettings.getValue(
- "SIG_SUBJECT"),
- signatureProfileSettings);
-
+ final String signerName = resolver.resolve("SIG_SUBJECT",
+ signatureProfileSettings.getValue("SIG_SUBJECT"), signatureProfileSettings);
signature.setName(signerName);
- signature.setSignDate(Calendar.getInstance());
- String signerReason = signatureProfileSettings.getSigningReason();
-
- if (signerReason == null) {
- signerReason = "PAdES Signature";
- }
+ // set signature reason
+ String signerReason = signatureProfileSettings.getSigningReason() != null
+ ? signatureProfileSettings.getSigningReason() : "PAdES Signature";
signature.setReason(signerReason);
- logger.debug("Signing reason: " + signerReason);
-
- logger.debug("Signing @ " + signer.getSigningDate().getTime().toString());
- // the signing date, needed for valid signature
- // signature.setSignDate(signer.getSigningDate());
+ log.debug("Signing reason: " + signerReason);
signer.setPDSignature(signature);
- int signatureSize = 0x1000;
- try {
- final String reservedSignatureSizeString = signatureProfileSettings.getValue(SIG_RESERVED_SIZE);
- if (reservedSignatureSizeString != null) {
- signatureSize = Integer.parseInt(reservedSignatureSizeString);
- }
- logger.debug("Reserving {} bytes for signature", signatureSize);
- } catch (final NumberFormatException e) {
- logger.warn("Invalid configuration value: {} should be a number using 0x1000", SIG_RESERVED_SIZE);
- }
- options.setPreferredSignatureSize(signatureSize);
-
+
if (signatureProfileSettings.isPDFA() || signatureProfileSettings.isPDFA3()) {
- pdfaVersion = getPDFAVersion(doc);
- signatureProfileSettings.setPDFAVersion(pdfaVersion);
+ signatureProfileSettings.setPDFAVersion(getPDFAVersion(doc));
+
}
- // Is visible Signature
- if (requestedSignature.isVisual()) {
- logger.info("Creating visual siganture block");
-
- final SignatureProfileConfiguration signatureProfileConfiguration = pdfObject.getStatus()
- .getSignatureProfileConfiguration(requestedSignature.getSignatureProfileID());
-
- if (tablePos == null) {
- // ================================================================
- // PositioningStage (visual) -> find position or use
- // fixed
- // position
-
- final String posString = pdfObject.getStatus().getSignParamter().getSignaturePosition();
-
- TablePos signaturePos = null;
-
- final String signaturePosString = signatureProfileConfiguration.getDefaultPositioning();
-
- if (signaturePosString != null) {
- logger.debug("using signature Positioning: " + signaturePos);
- signaturePos = new TablePos(signaturePosString);
- }
-
- logger.debug("using Positioning: " + posString);
-
- if (posString != null) {
- // Merge Signature Position
- tablePos = new TablePos(posString, signaturePos);
- } else {
- // Fallback to signature Position!
- tablePos = signaturePos;
- }
-
- if (tablePos == null) {
- // Last Fallback default position
- tablePos = new TablePos();
- }
- }
-
- // Legacy Modes not supported with pdfbox2 anymore
-// boolean legacy32Position = signatureProfileConfiguration.getLegacy32Positioning();
-// boolean legacy40Position = signatureProfileConfiguration.getLegacy40Positioning();
-
- // create Table describtion
+ // prepare basic signature options
+ options.setPreferredSignatureSize(calculateBlankAreaForSignature(signatureProfileSettings));
+
+ PDFAsVisualSignatureProperties properties = null;
+ if (requestedSignature.isVisual()) {
+ log.info("Creating visual siganture block");
+
+ final SignatureProfileConfiguration signatureProfileConfiguration =
+ pdfObject.getStatus().getSignatureProfileConfiguration(requestedSignature.getSignatureProfileID());
+ final TablePos tablePos = prepareTablePosition(nextPlaceholderData, signatureProfileConfiguration,
+ pdfObject.getStatus().getSignParamter().getSignaturePosition());
final Table main = TableFactory.createSigTable(signatureProfileSettings, MAIN, pdfObject.getStatus(),
requestedSignature);
final IPDFStamper stamper = StamperFactory.createDefaultStamper(pdfObject.getStatus().getSettings());
-
final IPDFVisualObject visualObject = stamper.createVisualPDFObject(pdfObject, main);
- /*
- * PDDocument originalDocument = PDDocument .load(new
- * ByteArrayInputStream(pdfObject.getStatus()
- * .getPdfObject().getOriginalDocument()));
- */
-
final PositioningInstruction positioningInstruction = Positioning.determineTablePositioning(tablePos,
- "",
- doc, visualObject, pdfObject.getStatus().getSettings());
-
- logger.debug("Positioning: {}", positioningInstruction.toString());
+ doc, visualObject, pdfObject.getStatus().getSettings(), signatureProfileSettings);
+ log.debug("Positioning: {}", positioningInstruction.toString());
if (!isAdobeSigForm) {
if (positioningInstruction.isMakeNewPage()) {
@@ -347,11 +236,11 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {
// handle rotated page
final int targetPageNumber = positioningInstruction.getPage();
- logger.debug("Target Page: " + targetPageNumber);
+ log.debug("Target Page: " + targetPageNumber);
final PDPage targetPage = doc.getPages().get(targetPageNumber - 1);
final int rot = targetPage.getRotation();
- logger.debug("Page rotation: " + rot);
- logger.debug("resulting Sign rotation: " + positioningInstruction.getRotation());
+ log.debug("Page rotation: " + rot);
+ log.debug("resulting Sign rotation: " + positioningInstruction.getRotation());
final SignaturePositionImpl position = new SignaturePositionImpl();
position.setX(positioningInstruction.getX());
@@ -361,44 +250,11 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {
position.setWidth(visualObject.getWidth());
requestedSignature.setSignaturePosition(position);
}
-
+
properties = new PDFAsVisualSignatureProperties(pdfObject.getStatus().getSettings(), pdfObject,
(PdfBoxVisualObject) visualObject, positioningInstruction, signatureProfileSettings, false);
-
properties.buildSignature();
- /*
- * ByteArrayOutputStream sigbos = new ByteArrayOutputStream();
- * sigbos.write(StreamUtils.inputStreamToByteArray (properties
- * .getVisibleSignature())); sigbos.close();
- */
-
- /*
- * if (signaturePlaceholderData != null) {
- *
- * InputStream fis =
- * PADESPDFBOXSigner.class.getResourceAsStream("/placeholder/empty.jpg");
- * PDImageXObject img = JPEGFactory.createFromStream(doc, fis);
- *
- * img.getCOSObject().setNeedToBeUpdated(true); // PDDocumentCatalog root =
- * doc.getDocumentCatalog(); // PDPageNode rootPages = root.getPages(); //
- * List<PDPage> kids = new ArrayList<PDPage>(); // rootPages.getAllKids(kids);
- * int pageNumber = positioningInstruction.getPage(); PDPage page =
- * doc.getPages().get(pageNumber - 1);
- *
- * logger.info("Placeholder name: " +
- * signaturePlaceholderData.getPlaceholderName()); COSDictionary
- * xobjectsDictionary = (COSDictionary) page.getResources().getCOSObject()
- * .getDictionaryObject(COSName.XOBJECT);
- *
- *
- * xobjectsDictionary.setItem(signaturePlaceholderData.getPlaceholderName(),
- * img); xobjectsDictionary.setNeedToBeUpdated(true);
- * page.getResources().getCOSObject().setNeedToBeUpdated(true);
- * logger.info("Placeholder name: " +
- * signaturePlaceholderData.getPlaceholderName()); }
- */
-
if (signatureProfileSettings.isPDFA() || signatureProfileSettings.isPDFA3()) {
final PDDocumentCatalog root = doc.getDocumentCatalog();
@@ -418,39 +274,30 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {
root.setOutputIntents(oi);
root.getCOSObject().setNeedToBeUpdated(true);
- logger.info("added Output Intent");
+ log.info("added Output Intent");
} catch (final Throwable e) {
e.printStackTrace();
throw new PdfAsException("Failed to add Output Intent", e);
+
} finally {
IOUtils.closeQuietly(colorProfile);
+
}
}
+
options.setPage(positioningInstruction.getPage() - 1);
options.setVisualSignature(properties.getVisibleSignature());
+
}
doc.addSignature(signature, signer, options);
-
- if (sigFieldName == null) {
- sigFieldName = "PDF-AS Signatur";
- }
- final int count = PdfBoxUtils.countSignatures(doc, sigFieldName);
-
- sigFieldName = sigFieldName + count;
-
- final PDAcroForm acroFormm = doc.getDocumentCatalog().getAcroForm();
-
- // PDStructureTreeRoot pdstRoot =
- // doc.getDocumentCatalog().getStructureTreeRoot();
- // COSDictionary dic =
- // doc.getDocumentCatalog().getCOSDictionary();
- // PDStructureElement el = new PDStructureElement("Widget",
- // pdstRoot);
-
+
+ String sigFieldName = buildNextSignatureFieldName(doc, pdfObject);
+
// this is not used for Adobe signature fields
if (!isAdobeSigForm) {
PDSignatureField signatureField = null;
+ final PDAcroForm acroFormm = doc.getDocumentCatalog().getAcroForm();
if (acroFormm != null) {
@SuppressWarnings("unchecked")
final List<PDField> fields = acroFormm.getFields();
@@ -473,7 +320,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {
}
}
} else {
- logger.warn("Failed to name Signature Field! [Cannot find Field list in acroForm!]");
+ log.warn("Failed to name Signature Field! [Cannot find Field list in acroForm!]");
}
if (signatureField != null) {
@@ -485,7 +332,8 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {
signatureField.setAlternateFieldName(sigFieldName);
}
} else {
- logger.warn("Failed to name Signature Field! [Cannot find acroForm!]");
+ log.warn("Failed to name Signature Field! [Cannot find acroForm!]");
+
}
}
@@ -493,194 +341,284 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {
final PDAcroForm acroForm = doc.getDocumentCatalog().getAcroForm();
if (acroForm != null) {
signatureField = (PDSignatureField) acroForm.getField(sigFieldName);
+
}
- // PDF-UA
- logger.info("Adding pdf/ua content.");
- try {
- final PDDocumentCatalog root = doc.getDocumentCatalog();
- final PDStructureTreeRoot structureTreeRoot = root.getStructureTreeRoot();
- if (structureTreeRoot != null) {
- logger.info("Tree Root: {}", structureTreeRoot.toString());
- final List<Object> kids = structureTreeRoot.getKids();
-
- if (kids == null) {
- logger.info("No kid-elements in structure tree Root, maybe not PDF/UA document");
- }
- PDStructureElement docElement = null;
- for (final Object k : kids) {
- if (k instanceof PDStructureElement) {
- docElement = (PDStructureElement) k;
- break;
+ injectPdfUaContent(doc, signatureField, sigFieldName, signatureProfileSettings);
+
+ performTechnicalSignature(doc, pdfObject, signatureProfileSettings);
+
- }
+ log.debug("Signature done!");
+
+ } catch (final IOException e) {
+ log.warn(MessageResolver.resolveMessage("error.pdf.sig.01"), e);
+ throw new PdfAsException("error.pdf.sig.01", e);
+
+ } catch (PDFASError e2) {
+ log.warn(e2.getInfo());
+ throw new PdfAsException("error.pdf.sig.01", e2);
+
+ } finally {
+ if (options != null) {
+ if (options.getVisualSignature() != null) {
+ try {
+ options.getVisualSignature().close();
+ options.close();
+ } catch (IOException e) {
+ log.debug("Failed to close VisualSignature!", e);
}
+ }
+ }
+
+ if (doc != null) {
+ try {
+ doc.close();
+ // SignaturePlaceholderExtractor.getPlaceholders().clear();
+ } catch (final IOException e) {
+ log.debug("Failed to close COS Doc!", e);
+ // Ignore
+ }
+ }
+ }
+ }
- final PDStructureElement sigBlock = new PDStructureElement("Form", docElement);
+ private void performTechnicalSignature(PDDocument doc, PDFBOXObject pdfObject,
+ SignatureProfileSettings signatureProfileSettings) throws PdfAsException {
+ try {
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ synchronized (doc) {
+ doc.saveIncremental(bos);
+ final byte[] outputDocument = bos.toByteArray();
+ pdfObject.setSignedDocument(outputDocument);
+ }
+ /* Check if resulting pdf is PDF-A conform */
+ if (signatureProfileSettings.isPDFA()) {
+ runPDFAPreflight(new ByteArrayDataSource(pdfObject.getSignedDocument()));
+ }
- // create object dictionary and add as child element
- final COSDictionary objectDic = new COSDictionary();
- objectDic.setName("Type", "OBJR");
+ } catch (final IOException e1) {
+ log.error("Can not save incremental update", e1);
- objectDic.setItem("Pg", signatureField.getWidget().getPage());
- objectDic.setItem("Obj", signatureField.getWidget());
+ }
+
+ System.gc();
+
+ }
- final List<Object> l = new ArrayList<>();
- l.add(objectDic);
- sigBlock.setKids(l);
- sigBlock.setPage(signatureField.getWidget().getPage());
+ private void injectPdfUaContent(PDDocument doc, PDSignatureField signatureField, String sigFieldName,
+ SignatureProfileSettings signatureProfileSettings) throws PdfAsException {
+ try {
+ log.info("Adding pdf/ua content .... ");
+ final PDDocumentCatalog root = doc.getDocumentCatalog();
+ final PDStructureTreeRoot structureTreeRoot = root.getStructureTreeRoot();
+ if (structureTreeRoot != null) {
+ log.info("Tree Root: {}", structureTreeRoot.toString());
+ final List<Object> kids = structureTreeRoot.getKids();
+
+ if (kids == null) {
+ log.info("No kid-elements in structure tree Root, maybe not PDF/UA document");
+ }
- sigBlock.setTitle("Signature Table");
- sigBlock.setParent(docElement);
- docElement.appendKid(sigBlock);
+ PDStructureElement docElement = null;
+ for (final Object k : kids) {
+ if (k instanceof PDStructureElement) {
+ docElement = (PDStructureElement) k;
+ break;
- // Create and add Attribute dictionary to mitigate PAC
- // warning
- final COSDictionary sigBlockDic = sigBlock.getCOSObject();
- final COSDictionary sub = new COSDictionary();
+ }
+ }
- sub.setName("O", "Layout");
- sub.setName("Placement", "Block");
- sigBlockDic.setItem(COSName.A, sub);
- sigBlockDic.setNeedToBeUpdated(true);
+ final PDStructureElement sigBlock = new PDStructureElement("Form", docElement);
- // Modify number tree
- PDNumberTreeNode ntn = structureTreeRoot.getParentTree();
- if (ntn == null) {
- ntn = new PDNumberTreeNode(objectDic, null);
- logger.info("No number-tree-node found!");
- }
+ // create object dictionary and add as child element
+ final COSDictionary objectDic = new COSDictionary();
+ objectDic.setName("Type", "OBJR");
- final COSArray ntnKids = (COSArray) ntn.getCOSObject().getDictionaryObject(COSName.KIDS);
- final COSArray ntnNumbers = (COSArray) ntn.getCOSObject().getDictionaryObject(COSName.NUMS);
+ objectDic.setItem("Pg", signatureField.getWidget().getPage());
+ objectDic.setItem("Obj", signatureField.getWidget());
- final int parentTreeNextKey = getParentTreeNextKey(structureTreeRoot);
+ final List<Object> l = new ArrayList<>();
+ l.add(objectDic);
+ sigBlock.setKids(l);
+ sigBlock.setPage(signatureField.getWidget().getPage());
- if (ntnNumbers == null && ntnKids != null) {// no number array, so continue with the kids array
- // create dictionary with limits and nums array
- final COSDictionary pTreeEntry = new COSDictionary();
- final COSArray limitsArray = new COSArray();
- // limits for exact one entry
- limitsArray.add(COSInteger.get(parentTreeNextKey));
- limitsArray.add(COSInteger.get(parentTreeNextKey));
+ sigBlock.setTitle("Signature Table");
+ sigBlock.setParent(docElement);
+ docElement.appendKid(sigBlock);
- final COSArray numsArray = new COSArray();
- numsArray.add(COSInteger.get(parentTreeNextKey));
- numsArray.add(sigBlock);
+ // Create and add Attribute dictionary to mitigate PAC
+ // warning
+ final COSDictionary sigBlockDic = sigBlock.getCOSObject();
+ final COSDictionary sub = new COSDictionary();
- pTreeEntry.setItem(COSName.NUMS, numsArray);
- pTreeEntry.setItem(COSName.LIMITS, limitsArray);
+ sub.setName("O", "Layout");
+ sub.setName("Placement", "Block");
+ sigBlockDic.setItem(COSName.A, sub);
+ sigBlockDic.setNeedToBeUpdated(true);
- final PDNumberTreeNode newKidsElement = new PDNumberTreeNode(pTreeEntry, PDNumberTreeNode.class);
+ // Modify number tree
+ PDNumberTreeNode ntn = structureTreeRoot.getParentTree();
+ if (ntn == null) {
+ ntn = new PDNumberTreeNode(objectDic, null);
+ log.info("No number-tree-node found!");
+ }
- ntnKids.add(newKidsElement);
- ntnKids.setNeedToBeUpdated(true);
+ final COSArray ntnKids = (COSArray) ntn.getCOSObject().getDictionaryObject(COSName.KIDS);
+ final COSArray ntnNumbers = (COSArray) ntn.getCOSObject().getDictionaryObject(COSName.NUMS);
- } else if (ntnNumbers != null && ntnKids == null) {
+ final int parentTreeNextKey = getParentTreeNextKey(structureTreeRoot);
- final int arrindex = ntnNumbers.size();
+ if (ntnNumbers == null && ntnKids != null) {// no number array, so continue with the kids array
+ // create dictionary with limits and nums array
+ final COSDictionary pTreeEntry = new COSDictionary();
+ final COSArray limitsArray = new COSArray();
+ // limits for exact one entry
+ limitsArray.add(COSInteger.get(parentTreeNextKey));
+ limitsArray.add(COSInteger.get(parentTreeNextKey));
- ntnNumbers.add(arrindex, COSInteger.get(parentTreeNextKey));
- ntnNumbers.add(arrindex + 1, sigBlock.getCOSObject());
+ final COSArray numsArray = new COSArray();
+ numsArray.add(COSInteger.get(parentTreeNextKey));
+ numsArray.add(sigBlock);
- ntnNumbers.setNeedToBeUpdated(true);
+ pTreeEntry.setItem(COSName.NUMS, numsArray);
+ pTreeEntry.setItem(COSName.LIMITS, limitsArray);
- structureTreeRoot.setParentTree(ntn);
+ final PDNumberTreeNode newKidsElement = new PDNumberTreeNode(pTreeEntry, PDNumberTreeNode.class);
- } else if (ntnNumbers == null && ntnKids == null) {
- // document is not pdfua conform before signature creation
- throw new PdfAsException("error.pdf.sig.pdfua.1");
- } else {
- // this is not allowed
- throw new PdfAsException("error.pdf.sig.pdfua.1");
- }
+ ntnKids.add(newKidsElement);
+ ntnKids.setNeedToBeUpdated(true);
- // set StructureParent for signature field annotation
- signatureField.getWidget().setStructParent(parentTreeNextKey);
+ } else if (ntnNumbers != null && ntnKids == null) {
- // Increase the next Key value in the structure tree root
- structureTreeRoot.setParentTreeNextKey(parentTreeNextKey + 1);
+ final int arrindex = ntnNumbers.size();
- // add the Tabs /S Element for Tabbing through annots
- final PDPage p = signatureField.getWidget().getPage();
- p.getCOSObject().setName("Tabs", "S");
- p.getCOSObject().setNeedToBeUpdated(true);
+ ntnNumbers.add(arrindex, COSInteger.get(parentTreeNextKey));
+ ntnNumbers.add(arrindex + 1, sigBlock.getCOSObject());
- // check alternative signature field name
- if (signatureField != null) {
- if (signatureField.getAlternateFieldName().equals("")) {
- signatureField.setAlternateFieldName(sigFieldName);
- }
- }
+ ntnNumbers.setNeedToBeUpdated(true);
- ntn.getCOSObject().setNeedToBeUpdated(true);
- sigBlock.getCOSObject().setNeedToBeUpdated(true);
- structureTreeRoot.getCOSObject().setNeedToBeUpdated(true);
- objectDic.setNeedToBeUpdated(true);
- docElement.getCOSObject().setNeedToBeUpdated(true);
- }
- } catch (final Throwable e) {
- if (signatureProfileSettings.isPDFUA() == true) {
- logger.error("Could not create PDF-UA conform document!");
- throw new PdfAsException("error.pdf.sig.pdfua.1", e);
+ structureTreeRoot.setParentTree(ntn);
+
+ } else if (ntnNumbers == null && ntnKids == null) {
+ // document is not pdfua conform before signature creation
+ throw new PdfAsException("error.pdf.sig.pdfua.1");
} else {
- logger.info("Could not create PDF-UA conform signature");
+ // this is not allowed
+ throw new PdfAsException("error.pdf.sig.pdfua.1");
}
- }
- try {
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
- synchronized (doc) {
- doc.saveIncremental(bos);
- final byte[] outputDocument = bos.toByteArray();
- pdfObject.setSignedDocument(outputDocument);
- }
- /* Check if resulting pdf is PDF-A conform */
- if (signatureProfileSettings.isPDFA()) {
- runPDFAPreflight(new ByteArrayDataSource(pdfObject.getSignedDocument()));
+ // set StructureParent for signature field annotation
+ signatureField.getWidget().setStructParent(parentTreeNextKey);
+
+ // Increase the next Key value in the structure tree root
+ structureTreeRoot.setParentTreeNextKey(parentTreeNextKey + 1);
+
+ // add the Tabs /S Element for Tabbing through annots
+ final PDPage p = signatureField.getWidget().getPage();
+ p.getCOSObject().setName("Tabs", "S");
+ p.getCOSObject().setNeedToBeUpdated(true);
+
+ // check alternative signature field name
+ if (signatureField != null) {
+ if (signatureField.getAlternateFieldName().equals("")) {
+ signatureField.setAlternateFieldName(sigFieldName);
+ }
}
- } catch (final IOException e1) {
- logger.error("Can not save incremental update", e1);
+ ntn.getCOSObject().setNeedToBeUpdated(true);
+ sigBlock.getCOSObject().setNeedToBeUpdated(true);
+ structureTreeRoot.getCOSObject().setNeedToBeUpdated(true);
+ objectDic.setNeedToBeUpdated(true);
+ docElement.getCOSObject().setNeedToBeUpdated(true);
+ }
+ } catch (final Throwable e) {
+ if (signatureProfileSettings.isPDFUA()) {
+ log.error("Could not create PDF-UA conform document!");
+ throw new PdfAsException("error.pdf.sig.pdfua.1", e);
+
+ } else {
+ log.info("Could not create PDF-UA conform signature");
+ }
+ }
+
+ }
+ private String buildNextSignatureFieldName(PDDocument doc, PDFBOXObject pdfObject) {
+ String sigFieldName = getSignatureFieldNameConfig(pdfObject);
+ if (sigFieldName == null) {
+ sigFieldName = "PDF-AS Signatur";
+
+ }
+ return sigFieldName + PdfBoxUtils.countSignatures(doc, sigFieldName);
+
+ }
+
+ private int calculateBlankAreaForSignature(SignatureProfileSettings signatureProfileSettings) {
+ int signatureSize = 0x1000;
+ try {
+ final String reservedSignatureSizeString = signatureProfileSettings.getValue(SIG_RESERVED_SIZE);
+ if (reservedSignatureSizeString != null) {
+ signatureSize = Integer.parseInt(reservedSignatureSizeString);
}
+ log.debug("Reserving {} bytes for signature", signatureSize);
- System.gc();
- logger.debug("Signature done!");
+ } catch (final NumberFormatException e) {
+ log.warn("Invalid configuration value: {} should be a number using 0x1000", SIG_RESERVED_SIZE);
- } catch (final IOException e) {
- logger.warn(MessageResolver.resolveMessage("error.pdf.sig.01"), e);
- throw new PdfAsException("error.pdf.sig.01", e);
+ }
- } catch (PDFASError e2) {
- logger.warn(e2.getInfo());
- throw new PdfAsException("error.pdf.sig.01", e2);
-
- } finally {
- if (options != null) {
- if (options.getVisualSignature() != null) {
- try {
- options.getVisualSignature().close();
- options.close();
- } catch (IOException e) {
- logger.debug("Failed to close VisualSignature!", e);
- }
+ return signatureSize;
+ }
+
+ private TablePos prepareTablePosition(SignaturePlaceholderData nextPlaceholderData,
+ SignatureProfileConfiguration signatureProfileConfiguration, String profilePosParam) throws PdfAsException {
+
+
+ if (nextPlaceholderData != null && nextPlaceholderData.getTablePos() != null) {
+ final float minWidth = signatureProfileConfiguration.getMinWidth();
+ TablePos tablePos = nextPlaceholderData.getTablePos();
+ if (minWidth > 0) {
+ if (tablePos.getWidth() < minWidth) {
+ tablePos.width = minWidth;
+ log.debug("Correcting placeholder with to minimum width {}", minWidth);
}
}
+ log.debug("Placeholder Position set to: " + tablePos.toString());
+ return tablePos;
- if (doc != null) {
- try {
- doc.close();
- // SignaturePlaceholderExtractor.getPlaceholders().clear();
- } catch (final IOException e) {
- logger.debug("Failed to close COS Doc!", e);
- // Ignore
- }
+ } else {
+ TablePos signaturePos = null;
+ final String signaturePosString = signatureProfileConfiguration.getDefaultPositioning();
+
+ if (signaturePosString != null) {
+ log.debug("using signature Positioning: " + signaturePosString);
+ signaturePos = new TablePos(signaturePosString);
+
+ }
+
+ log.debug("using Positioning: " + profilePosParam);
+
+ if (profilePosParam != null) {
+ // Merge Signature Position
+ return new TablePos(profilePosParam, signaturePos);
+
+ } else if (signaturePos != null){
+ // Fallback to signature Position!
+ return signaturePos;
+
+ } else {
+ return new TablePos();
+
}
}
}
+ private String getSignatureFieldNameConfig(PDFBOXObject pdfObject) {
+ return pdfObject.getStatus().getSettings().getValue(SIGNATURE_FIELD_NAME);
+ }
+
private int getParentTreeNextKey(PDStructureTreeRoot structureTreeRoot) throws IOException {
int nextKey = structureTreeRoot.getParentTreeNextKey();
if (nextKey < 0) {
@@ -717,31 +655,31 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {
document.close();
result = document.getResult();
- logger.info("PDF-A Validation Result: " + result.isValid());
+ log.info("PDF-A Validation Result: " + result.isValid());
if (result.getErrorsList().size() > 0) {
- logger.error("The following validation errors occured for PDF-A validation");
+ log.error("The following validation errors occured for PDF-A validation");
}
for (final ValidationResult.ValidationError ve : result.getErrorsList()) {
- logger.error("\t" + ve.getErrorCode() + ": " + ve.getDetails());
+ log.error("\t" + ve.getErrorCode() + ": " + ve.getDetails());
}
if (!result.isValid()) {
- logger.info("The file is not a valid PDF-A document");
+ log.info("The file is not a valid PDF-A document");
}
} catch (final SyntaxValidationException e) {
- logger.error("The file is syntactically invalid.", e);
+ log.error("The file is syntactically invalid.", e);
throw new PdfAsException("Resulting PDF Document is syntactically invalid.");
} catch (final ValidationException e) {
- logger.error("The file is not a valid PDF-A document.", e);
+ log.error("The file is not a valid PDF-A document.", e);
} catch (final IOException e) {
- logger.error("An IOException (" + e.getMessage()
+ log.error("An IOException (" + e.getMessage()
+ ") occurred, while validating the PDF-A conformance", e);
throw new PdfAsException("Failed validating PDF Document IOException.");
} catch (final RuntimeException e) {
- logger.debug("An RuntimeException (" + e.getMessage()
+ log.debug("An RuntimeException (" + e.getMessage()
+ ") occurred, while validating the PDF-A conformance", e);
throw new PdfAsException("Failed validating PDF Document RuntimeException.");
} finally {
@@ -819,11 +757,11 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {
final String signaturePosString = signatureProfileConfiguration.getDefaultPositioning();
PositioningInstruction positioningInstruction;
if (signaturePosString != null) {
- positioningInstruction = Positioning.determineTablePositioning(new TablePos(signaturePosString), "",
- origDoc, visualObject, pdfObject.getStatus().getSettings());
+ positioningInstruction = Positioning.determineTablePositioning(new TablePos(signaturePosString),
+ origDoc, visualObject, pdfObject.getStatus().getSettings(), signatureProfileSettings);
} else {
- positioningInstruction = Positioning.determineTablePositioning(new TablePos(), "", origDoc,
- visualObject, pdfObject.getStatus().getSettings());
+ positioningInstruction = Positioning.determineTablePositioning(new TablePos(), origDoc,
+ visualObject, pdfObject.getStatus().getSettings(), signatureProfileSettings);
}
origDoc.close();
@@ -877,10 +815,10 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {
return cutOut;
} catch (final PdfAsException e) {
- logger.warn("PDF-AS Exception", e);
+ log.warn("PDF-AS Exception", e);
throw ErrorExtractor.searchPdfAsError(e, status);
} catch (final Throwable e) {
- logger.warn("Unexpected Throwable Exception", e);
+ log.warn("Unexpected Throwable Exception", e);
throw ErrorExtractor.searchPdfAsError(e, status);
}
}
@@ -898,7 +836,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {
if (pdfaIdentificationSchema != null) {
final Integer pdfaversion = pdfaIdentificationSchema.getPart();
final String conformance = pdfaIdentificationSchema.getConformance();
- logger.info("Detected PDF/A Version: {} - {}", pdfaversion, conformance);
+ log.info("Detected PDF/A Version: {} - {}", pdfaversion, conformance);
if (pdfaversion != null) {
return String.valueOf(pdfaversion);
@@ -907,7 +845,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {
}
}
} catch (final Throwable e) {
- logger.warn("Failed to determine PDF/A Version!", e);
+ log.warn("Failed to determine PDF/A Version!", e);
}
return null;
}
@@ -931,75 +869,9 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {
}
}
return signature;
+
}
-
- private List<String> existingSignatureLocations(PDDocument doc) {
- final List<String> existingLocations = new ArrayList<>();
- try {
- final List<PDSignature> pdSignatureList = doc.getSignatureDictionaries();
- if (pdSignatureList.size() != 0) {
- for (final PDSignature sig : pdSignatureList) {
- existingLocations.add(sig.getLocation());
- }
- }
- } catch (final IOException e) {
- e.printStackTrace();
- }
- return existingLocations;
- }
-
- // find first placeholder_id
- public SignaturePlaceholderData checkAvailablePlaceholders(List<SignaturePlaceholderData> placeholders,
- List<String> existingPlaceholders) {
- SignaturePlaceholderData result = null;
-
- if (placeholders != null) {
- for (int i = 0; i < placeholders.size(); ++i) {
- // take smallest id
- if (!existingPlaceholders.contains(placeholders.get(i).getPlaceholderName())) {
- final SignaturePlaceholderData spd = placeholders.get(i);
- if (spd.getId() != null) {
- if (result == null) {
- result = spd;
- } else {
- try {
- final int currentID = Integer.parseInt(result.getId());
- final int testID = Integer.parseInt(spd.getId());
- if (testID < currentID) {
- result = spd;
- }
- } catch (final Exception e) {
- // fallback to string compare
- final String currentID = result.getId();
- final String testID = spd.getId();
- if (testID.compareToIgnoreCase(currentID) < 0) {
- result = spd;
- }
- }
- }
- }
- }
- }
- }
- return result;
- }
-
- // find first placeholder_id
- public List<SignaturePlaceholderData> listAvailablePlaceholders(List<SignaturePlaceholderData> placeholders,
- List<String> existingPlaceholders) {
- final List<SignaturePlaceholderData> result = new ArrayList<>();
-
- if (placeholders != null) {
- for (int i = 0; i < placeholders.size(); ++i) {
- // take smallest id
- if (!existingPlaceholders.contains(placeholders.get(i).getPlaceholderName())) {
- result.add(placeholders.get(i));
- }
- }
- }
- return result;
- }
-
+
static Map<Integer, COSObjectable> getNumberTreeAsMap(PDNumberTreeNode tree)
throws IOException {
Map<Integer, COSObjectable> numbers = tree.getNumbers();
diff --git a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox2/PDFAsVisualSignatureBuilder.java b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox2/PDFAsVisualSignatureBuilder.java
index d30604d3..a148b3ec 100644
--- a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox2/PDFAsVisualSignatureBuilder.java
+++ b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox2/PDFAsVisualSignatureBuilder.java
@@ -30,17 +30,25 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.MessageDigest;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
-import at.gv.egiz.pdfas.common.settings.SignatureProfileSettings;
import org.apache.commons.codec.binary.Hex;
-import org.apache.commons.io.IOUtils;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
-import org.apache.pdfbox.pdmodel.*;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.PDPageContentStream;
+import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.common.PDStream;
+import org.apache.pdfbox.pdmodel.font.PDFont;
+import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
import org.apache.pdfbox.pdmodel.graphics.image.JPEGFactory;
import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;
@@ -52,12 +60,12 @@ import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDVisibleS
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
-import org.apache.pdfbox.pdmodel.font.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
import at.gv.egiz.pdfas.common.settings.ISettings;
+import at.gv.egiz.pdfas.common.settings.SignatureProfileSettings;
import at.gv.egiz.pdfas.common.utils.ImageUtils;
import at.knowcenter.wag.egov.egiz.table.Entry;
@@ -260,7 +268,7 @@ public class PDFAsVisualSignatureBuilder extends PDVisibleSigBuilder implements
PDPageContentStream stream = new PDPageContentStream(template,
getStructure().getPage());
// stream.setFont(PDType1Font.COURIER, 5);
- TableDrawUtils.drawTable(getStructure().getPage(), stream, 1, 1,
+ TableDrawUtils.drawTable(getStructure().getPage(), stream, 0, 1,
designer.getWidth(), designer.getHeight(),
properties.getMainTable(), template, false,
innerFormResources, images, settings, this, properties);
diff --git a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox2/PDFAsVisualSignatureProperties.java b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox2/PDFAsVisualSignatureProperties.java
index 34093a9d..623347ff 100644
--- a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox2/PDFAsVisualSignatureProperties.java
+++ b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox2/PDFAsVisualSignatureProperties.java
@@ -104,7 +104,7 @@ public class PDFAsVisualSignatureProperties extends PDVisibleSigProperties {
logger.debug("ROT {}", rot);
logger.debug("COORD X {} Y {}", posx, posy);
designer.coordinates(posx, posy);
- float[] form_rect = new float[] {0,0, main.getWidth() + 2, main.getHeight() + 2};
+ float[] form_rect = new float[] {0,0, main.getWidth() + 1, main.getHeight() + 1};
logger.debug("AP Rect: {} {} {} {}", form_rect[0], form_rect[1], form_rect[2], form_rect[3]);
designer.formaterRectangleParams(form_rect);
//this.setPdVisibleSignature(designer);
diff --git a/pdf-as-pdfbox-2/src/test/java/at/gv/egiz/pdfas/lib/testpdfbox/PDFBoxPlaceholderExtractorTest.java b/pdf-as-pdfbox-2/src/test/java/at/gv/egiz/pdfas/lib/testpdfbox/PDFBoxPlaceholderExtractorTest.java
new file mode 100644
index 00000000..fbe3cdea
--- /dev/null
+++ b/pdf-as-pdfbox-2/src/test/java/at/gv/egiz/pdfas/lib/testpdfbox/PDFBoxPlaceholderExtractorTest.java
@@ -0,0 +1,51 @@
+package at.gv.egiz.pdfas.lib.testpdfbox;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.junit.Test;
+
+import at.gv.egiz.pdfas.lib.impl.pdfbox2.placeholder.SignatureFieldsAndPlaceHolderExtractor;
+import at.gv.egiz.pdfas.lib.impl.placeholder.SignaturePlaceholderData;
+import lombok.SneakyThrows;
+
+public class PDFBoxPlaceholderExtractorTest {
+
+ @Test
+ @SneakyThrows
+ public void nextPlaceholder() {
+ SignaturePlaceholderData result = getNextSignaturePlaceHolder("/data/platzhalter_en_de_test.pdf");
+ assertEquals("Im48", result.getPlaceholderName());
+
+ }
+
+ @Test
+ @SneakyThrows
+ public void allPlaceHolders() {
+ List<String> listOfPlaceHolders = getPlaceHolders("/data/platzhalter_en_de_test.pdf");
+ assertNotNull(listOfPlaceHolders);
+
+ }
+
+ private static List<String> getPlaceHolders(String filePath) throws IOException {
+ final PDDocument doc = PDDocument.load(PDFBoxPlaceholderExtractorTest.class.getResourceAsStream(
+ filePath));
+ final List<String> results = SignatureFieldsAndPlaceHolderExtractor.findEmptySignatureFields(doc);
+ return results;
+
+ }
+
+ private static SignaturePlaceholderData getNextSignaturePlaceHolder(String filePath) throws IOException {
+ final PDDocument doc = PDDocument.load(PDFBoxPlaceholderExtractorTest.class.getResourceAsStream(
+ filePath));
+ final SignaturePlaceholderData result =
+ SignatureFieldsAndPlaceHolderExtractor.getNextUnusedSignaturePlaceHolder(doc);
+ return result;
+
+ }
+
+}
diff --git a/pdf-as-pdfbox-2/src/test/java/at/gv/egiz/pdfas/lib/testpdfbox/SignatureFieldsAndPlaceHolderExtractorTest.java b/pdf-as-pdfbox-2/src/test/java/at/gv/egiz/pdfas/lib/testpdfbox/SignatureFieldsAndPlaceHolderExtractorTest.java
index 40522504..0ed05eb5 100644
--- a/pdf-as-pdfbox-2/src/test/java/at/gv/egiz/pdfas/lib/testpdfbox/SignatureFieldsAndPlaceHolderExtractorTest.java
+++ b/pdf-as-pdfbox-2/src/test/java/at/gv/egiz/pdfas/lib/testpdfbox/SignatureFieldsAndPlaceHolderExtractorTest.java
@@ -52,6 +52,14 @@ public class SignatureFieldsAndPlaceHolderExtractorTest {
SignaturePlaceholderData result = getNextSignaturePlaceHolder(getPath("manySignFields.pdf"));
Assert.assertEquals(null,result);
}
+
+ @Test
+ public void firstQrCodeOnUnsignedDoc() {
+ SignaturePlaceholderData result = getNextSignaturePlaceHolder(getPath("new_qr_2-2.pdf"));
+ Assert.assertEquals("Image5",result.getPlaceholderName());
+
+ }
+
@Test
public void subsequentCalls(){
SignaturePlaceholderData result = getNextSignaturePlaceHolder(getPath("new_qr_2_signed_signed_signed.pdf"));
diff --git a/pdf-as-pdfbox-2/src/test/resources/data/platzhalter_en_de_test.pdf b/pdf-as-pdfbox-2/src/test/resources/data/platzhalter_en_de_test.pdf
new file mode 100644
index 00000000..06b9aa0e
--- /dev/null
+++ b/pdf-as-pdfbox-2/src/test/resources/data/platzhalter_en_de_test.pdf
Binary files differ
diff --git a/pdf-as-web-db/build.gradle b/pdf-as-web-db/build.gradle
index e2ee78cf..d2b6fb02 100644
--- a/pdf-as-web-db/build.gradle
+++ b/pdf-as-web-db/build.gradle
@@ -17,9 +17,9 @@ dependencies {
implementation project (':pdf-as-web')
implementation project (':pdf-as-web-status')
implementation project (':pdf-as-web-statistic-api')
- api "org.hibernate:hibernate-core:5.6.14.Final"
- api "org.hibernate:hibernate-entitymanager:5.6.14.Final"
- implementation 'ch.qos.logback:logback-classic:1.2.11'
+ api "org.hibernate:hibernate-core:5.6.15.Final"
+ api "org.hibernate:hibernate-entitymanager:5.6.15.Final"
+ implementation 'ch.qos.logback:logback-classic:1.2.12'
implementation group: 'org.slf4j', name: 'slf4j-api', version: slf4jVersion
}
diff --git a/pdf-as-web-db/src/main/java/at/gv/egiz/pdfas/web/store/DBRequestStore.java b/pdf-as-web-db/src/main/java/at/gv/egiz/pdfas/web/store/DBRequestStore.java
index 5afb28e4..e5a789d2 100644
--- a/pdf-as-web-db/src/main/java/at/gv/egiz/pdfas/web/store/DBRequestStore.java
+++ b/pdf-as-web-db/src/main/java/at/gv/egiz/pdfas/web/store/DBRequestStore.java
@@ -4,12 +4,12 @@ import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
-import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
+import org.hibernate.query.Query;
import org.hibernate.service.ServiceRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -33,6 +33,8 @@ public class DBRequestStore implements IRequestStore {
public DBRequestStore() {
final Configuration cfg = new Configuration();
cfg.addAnnotatedClass(Request.class);
+ cfg.addAnnotatedClass(Response.class);
+ cfg.addAnnotatedClass(StatisticRequest.class);
cfg.setProperties(WebConfiguration.getHibernateProps());
serviceRegistry = new StandardServiceRegistryBuilder().applySettings(
@@ -46,7 +48,7 @@ public class DBRequestStore implements IRequestStore {
final Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND, -1 * seconds);
final Date date = calendar.getTime();
- final SimpleDateFormat dt = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss");
+ final SimpleDateFormat dt = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
logger.info("Clearing Entries before: " + dt.format(date));
Session session = null;
Transaction tx = null;
@@ -57,6 +59,7 @@ public class DBRequestStore implements IRequestStore {
+ " where req.created < :date");
query.setCalendar("date", calendar);
query.executeUpdate();
+ tx.commit();
} catch (final Throwable e) {
logger.error("Failed to save Request", e);
tx.rollback();
@@ -72,7 +75,7 @@ public class DBRequestStore implements IRequestStore {
final Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND, -1 * seconds);
final Date date = calendar.getTime();
- final SimpleDateFormat dt = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss");
+ final SimpleDateFormat dt = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
logger.info("Clearing Entries before: " + dt.format(date));
Session session = null;
try {
@@ -91,7 +94,7 @@ public class DBRequestStore implements IRequestStore {
+ " where req.created < :date");
queryResponse.setCalendar("date", calendar);
queryResponse.executeUpdate();
-
+
} finally {
if (session != null) {
session.close();
diff --git a/pdf-as-web/build.gradle b/pdf-as-web/build.gradle
index f5843650..3123668d 100644
--- a/pdf-as-web/build.gradle
+++ b/pdf-as-web/build.gradle
@@ -56,8 +56,7 @@ dependencies {
api project (':pdf-as-web-status')
api project (':pdf-as-web-statistic-api')
api project (':pdf-as-pdfbox-2')
- api group: 'commons-fileupload', name: 'commons-fileupload', version: '1.4'
- // Upgrade dependency of commons-fileupload from 2.2 to 2.8.0 to avoid CVE-2021-29425
+ api group: 'commons-fileupload', name: 'commons-fileupload', version: '1.5'
api group: 'commons-io', name: 'commons-io', version: '2.11.0'
api group: 'opensymphony', name: 'sitemesh', version: '2.4.2'
api group: 'javax.xml.bind', name: 'jaxb-api', version: '2.3.1'
@@ -69,12 +68,12 @@ dependencies {
api 'org.apache.cxf:cxf-rt-transports-http:3.5.5'
api 'org.apache.cxf:cxf-rt-frontend-jaxws:3.5.5'
api 'com.thetransactioncompany:cors-filter:2.10'
- api 'ch.qos.logback:logback-classic:1.2.11'
- api 'ch.qos.logback:logback-core:1.2.11'
- api 'org.json:json:20220924'
+ api 'ch.qos.logback:logback-classic:1.2.12'
+ api 'ch.qos.logback:logback-core:1.2.12'
+ api 'org.json:json:20230227'
api group: 'javax.jws', name: 'javax.jws-api', version: '1.1'
compileOnly 'javax.servlet:javax.servlet-api:3.0.1'
- testRuntime 'org.springframework:spring-test:5.2.22.RELEASE'
+ testImplementation 'org.springframework:spring-test:5.3.28'
}
diff --git a/pdf-as-web/src/main/configuration/pdf-as-web.properties b/pdf-as-web/src/main/configuration/pdf-as-web.properties
index 556fd667..fe6c9576 100644
--- a/pdf-as-web/src/main/configuration/pdf-as-web.properties
+++ b/pdf-as-web/src/main/configuration/pdf-as-web.properties
@@ -51,6 +51,7 @@ whitelist.enabled=true
whitelist.url.01=^.*$
public.url=http://localhost:8080/pdf-as-web
+#public.data.url=http://localhost:8088/pdf-as-web
#Request Store
# Default In Memory Store
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java
index 1fffb17d..81b60131 100644
--- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/config/WebConfiguration.java
@@ -39,6 +39,7 @@ import at.gv.egiz.pdfas.web.helper.PdfAsHelper;
public class WebConfiguration implements IConfigurationConstants {
public static final String PUBLIC_URL = "public.url";
+ public static final String PUBLIC_DATA_URL = "public.data.url";
public static final String LOCAL_BKU_ENABLED = "bku.sign.enabled";
public static final String ONLINE_BKU_ENABLED = "moc.sign.enabled";
public static final String MOBILE_BKU_ENABLED = "mobile.sign.enabled";
@@ -226,6 +227,10 @@ public class WebConfiguration implements IConfigurationConstants {
return properties.getProperty(PUBLIC_URL);
}
+ public static String getPublicDataURL() {
+ return properties.getProperty(PUBLIC_DATA_URL);
+ }
+
public static String getLocalBKUURL() {
if(getLocalBKUEnabled()) {
String overwrite = properties.getProperty(CONFIG_BKU_URL);
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/ExceptionCatchFilter.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/ExceptionCatchFilter.java
index 675b1d6b..5d1abc15 100644
--- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/ExceptionCatchFilter.java
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/ExceptionCatchFilter.java
@@ -24,7 +24,9 @@
package at.gv.egiz.pdfas.web.filter;
import java.io.IOException;
+import java.util.Collections;
import java.util.Enumeration;
+import java.util.List;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
@@ -34,26 +36,47 @@ import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import org.apache.commons.lang3.StringUtils;
import org.slf4j.MDC;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import at.gv.egiz.pdfas.web.helper.PdfAsHelper;
+import com.beust.jcommander.Strings;
+import com.beust.jcommander.internal.Lists;
+
+import lombok.extern.slf4j.Slf4j;
/**
* Servlet Filter implementation class ExceptionCatchFilter
*/
+@Slf4j
public class ExceptionCatchFilter implements Filter {
- private static final Logger logger = LoggerFactory.getLogger(ExceptionCatchFilter.class);
-
+ List<String> statelessPaths;
+
/**
* Default constructor.
*/
public ExceptionCatchFilter() {
}
+ /**
+ * @see Filter#init(FilterConfig)
+ */
+ public void init(FilterConfig fConfig) throws ServletException {
+ String statelessConfigStrings = fConfig.getInitParameter("statelessServlets");
+ if (statelessConfigStrings != null) {
+ statelessPaths = Lists.newArrayList(StringUtils.split(statelessConfigStrings, ","));
+
+ } else {
+ statelessPaths = Collections.emptyList();
+
+ }
+ log.info("Stateless paths set to: {}", Strings.join(", ", statelessPaths));
+
+ }
+
+
/**
* @see Filter#destroy()
*/
@@ -68,12 +91,15 @@ public class ExceptionCatchFilter implements Filter {
try {
if (request instanceof HttpServletRequest) {
- HttpServletRequest httpRequest = (HttpServletRequest) request;
- MDC.put("SESSION_ID", httpRequest.getSession().getId());
- logger.debug("Processing Parameters into Attributes");
- logger.warn("Access from IP {}", getClientIpAddr(httpRequest));
-
- PdfAsHelper.logAccess(httpRequest);
+ HttpServletRequest httpRequest = (HttpServletRequest) request;
+
+ HttpSession session = httpRequest.getSession(isStatefull(httpRequest.getServletPath()));
+ String sessionId = session != null ? session.getId() : "-";
+ MDC.put("SESSION_ID", sessionId);
+ log.info("Access from IP: {}", getClientIpAddr(httpRequest));
+ log.info("Access to: {} in Session: {}", httpRequest.getServletPath(), sessionId);
+
+ log.debug("Processing Parameters into Attributes");
@SuppressWarnings("unchecked")
Enumeration<String> parameterNames = httpRequest.getParameterNames();
while (parameterNames.hasMoreElements()) {
@@ -85,33 +111,41 @@ public class ExceptionCatchFilter implements Filter {
try {
chain.doFilter(request, response);
+
} finally {
- if (response != null) {
- if (response instanceof HttpServletResponse) {
- HttpServletResponse resp = (HttpServletResponse) response;
- logger.debug("Got response status: {}", resp.getStatus());
- } else {
- logger.warn("Response is not a HttpServletResponse!");
- }
- } else {
- logger.warn("Response is not a HttpServletResponse!");
+ if (response instanceof HttpServletResponse) {
+ HttpServletResponse resp = (HttpServletResponse) response;
+ log.debug("Got response status: {}", resp.getStatus());
+
+ } else {
+ log.warn("Response is not a HttpServletResponse!");
+
}
}
} catch (Throwable e) {
- logger.error("Unhandled exception found", e);
+ log.error("Unhandled exception found", e);
throw new ServletException(e.getMessage());
+
} finally {
MDC.remove("SESSION_ID");
+
}
/*
* } catch(Throwable e) {
* System.err.println("Unhandled Exception found!");
* e.printStackTrace(System.err);
- * logger.error("Unhandled Exception found!", e); }
+ * log.error("Unhandled Exception found!", e); }
*/
}
- public static String getClientIpAddr(HttpServletRequest request) {
+ private boolean isStatefull(String contextPath) {
+ boolean statefull = !statelessPaths.contains(contextPath);
+ log.trace("ServletPath: {} is marked as {}", contextPath, statefull ? "statefull" : "stateless");
+ return statefull;
+
+ }
+
+ public static String getClientIpAddr(HttpServletRequest request) {
String ip = request.getHeader("X-Forwarded-For");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
@@ -131,10 +165,4 @@ public class ExceptionCatchFilter implements Filter {
return ip;
}
- /**
- * @see Filter#init(FilterConfig)
- */
- public void init(FilterConfig fConfig) throws ServletException {
- }
-
}
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/UserAgentFilter.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/UserAgentFilter.java
index 504cf472..ef7d391d 100644
--- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/UserAgentFilter.java
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/filter/UserAgentFilter.java
@@ -10,14 +10,11 @@ import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import lombok.extern.slf4j.Slf4j;
+@Slf4j
public class UserAgentFilter implements Filter {
- private static final Logger logger = LoggerFactory
- .getLogger(UserAgentFilter.class);
-
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
@@ -37,7 +34,7 @@ public class UserAgentFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if(request instanceof HttpServletRequest) {
- logger.debug("Processing Parameters into Attributes");
+ log.debug("Processing Parameters into Attributes");
HttpServletRequest httpRequest = (HttpServletRequest)request;
requestUserAgent.set(httpRequest.getHeader("User-Agent"));
}
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsHelper.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsHelper.java
index 35b5a7ce..9900dda4 100644
--- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsHelper.java
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsHelper.java
@@ -161,7 +161,9 @@ public class PdfAsHelper {
reloadConfig();
}
- public static void init() {
+ public static void init() {
+ JsonSecurityUtils.getInstance();
+
log.info("PDF-AS Helper initialized");
}
@@ -536,7 +538,9 @@ public class PdfAsHelper {
// set Signature Position
signParameter.setSignaturePosition(documentToSign.getPosition());
-
+ signParameter.setPlaceHolderId(documentToSign.getPlaceHolderId());
+ signParameter.setPlaceHolderSearchEnabled(documentToSign.isPlaceholderSearchEnabled());
+
// Set Preprocessor
if (coreParams.getPreprocessor() != null) {
signParameter.setPreprocessorArguments(coreParams.getPreprocessor());
@@ -549,8 +553,7 @@ public class PdfAsHelper {
PDFASVerificationResponse verResponse = new PDFASVerificationResponse();
- verResponse.setSignerCertificate(signResult.getSignerCertificate()
- .getEncoded());
+ verResponse.setSignerCertificate(signResult.getSignerCertificate().getEncoded());
SignedDocument signPdfDoc = SignedDocument.builder()
@@ -660,7 +663,8 @@ public class PdfAsHelper {
// set Signature Position
signParameter.setSignaturePosition(pdfToSign.getPosition());
-
+ signParameter.setPlaceHolderId(pdfToSign.getPlaceHolderId());
+ signParameter.setPlaceHolderSearchEnabled(pdfToSign.isPlaceholderSearchEnabled());
signParameter.setDynamicSignatureBlockArguments(coreSignParams.getSignatureBlockParameters());
return pdfAs.startSign(signParameter);
@@ -787,12 +791,6 @@ public class PdfAsHelper {
PdfAsHelper.process(request, response, context);
}
- public static void logAccess(HttpServletRequest request) {
- HttpSession session = request.getSession();
- log.info("Access to " + request.getServletPath() + " in Session: "
- + session.getId());
- }
-
public static JSONStartResponse startJsonProcess(HttpServletRequest request,
HttpServletResponse response, ServletContext context)
throws Exception {
@@ -907,6 +905,10 @@ public class PdfAsHelper {
JsonObject sl20Req = null;
String reqId = UUID.randomUUID().toString();
if (WebConfiguration.isSL20SigningEnabled()) {
+ if (joseTools == null) {
+ throw new PdfAsException("error.config.sl20.01");
+ }
+
String signedCertCommand = SL20JSONBuilderUtils.createSignedCommand(
SL20Constants.SL20_COMMAND_IDENTIFIER_GETCERTIFICATE, getCertParams, joseTools);
sl20Req = SL20JSONBuilderUtils.createGenericRequest(reqId, null, null, signedCertCommand);
@@ -1361,29 +1363,35 @@ public class PdfAsHelper {
private static String generateURL(HttpServletRequest request,
HttpServletResponse response, String Servlet) {
- HttpSession session = request.getSession();
- String publicURL = WebConfiguration.getPublicURL();
- String dataURL = null;
- if (publicURL != null) {
- dataURL = publicURL + Servlet + ";jsessionid=" + session.getId();
- } else {
- if ((request.getScheme().equals("http") && request.getServerPort() == 80)
- || (request.getScheme().equals("https") && request
- .getServerPort() == 443)) {
- dataURL = request.getScheme() + "://" + request.getServerName()
- + request.getContextPath() + Servlet + ";jsessionid="
- + session.getId();
- } else {
- dataURL = request.getScheme() + "://" + request.getServerName()
- + ":" + request.getServerPort()
- + request.getContextPath() + Servlet + ";jsessionid="
- + session.getId();
- }
- }
- log.debug("Generated URL: " + dataURL);
- return dataURL;
+ return generateURL(request, response, Servlet, WebConfiguration.getPublicURL());
+
}
+ private static String generateURL(HttpServletRequest request,
+ HttpServletResponse response, String Servlet, String publicURL) {
+ HttpSession session = request.getSession();
+ String dataURL = null;
+ if (publicURL != null) {
+ dataURL = publicURL + Servlet + ";jsessionid=" + session.getId();
+ } else {
+ if ((request.getScheme().equals("http") && request.getServerPort() == 80)
+ || (request.getScheme().equals("https") && request
+ .getServerPort() == 443)) {
+ dataURL = request.getScheme() + "://" + request.getServerName()
+ + request.getContextPath() + Servlet + ";jsessionid="
+ + session.getId();
+ } else {
+ dataURL = request.getScheme() + "://" + request.getServerName()
+ + ":" + request.getServerPort()
+ + request.getContextPath() + Servlet + ";jsessionid="
+ + session.getId();
+ }
+ }
+ log.debug("Generated URL: " + dataURL);
+ return dataURL;
+ }
+
+
public static void regenerateSession(HttpServletRequest request) {
request.getSession(false).invalidate();
request.getSession(true);
@@ -1391,12 +1399,16 @@ public class PdfAsHelper {
public static String generateDataURLSL20(HttpServletRequest request,
HttpServletResponse response) {
- return generateURL(request, response, PDF_SL20_DATAURL_PAGE);
+ return generateURL(request, response, PDF_SL20_DATAURL_PAGE,
+ WebConfiguration.getPublicDataURL() != null
+ ? WebConfiguration.getPublicDataURL() : WebConfiguration.getPublicURL());
}
public static String generateDataURL(HttpServletRequest request,
HttpServletResponse response) {
- return generateURL(request, response, PDF_DATAURL_PAGE);
+ return generateURL(request, response, PDF_DATAURL_PAGE,
+ WebConfiguration.getPublicDataURL() != null
+ ? WebConfiguration.getPublicDataURL() : WebConfiguration.getPublicURL());
}
public static String generateProvideURL(HttpServletRequest request,
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsParameterExtractor.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsParameterExtractor.java
index 31fbf46d..1ed85e98 100644
--- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsParameterExtractor.java
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/helper/PdfAsParameterExtractor.java
@@ -30,11 +30,13 @@ import java.util.Map;
import javax.servlet.http.HttpServletRequest;
-import at.gv.egiz.pdfas.lib.api.IConfigurationConstants;
-import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter.SignatureVerificationLevel;
+import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import at.gv.egiz.pdfas.lib.api.IConfigurationConstants;
+import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter.SignatureVerificationLevel;
+
public class PdfAsParameterExtractor {
public static final String PARAM_CONNECTOR = "connector";
@@ -118,6 +120,16 @@ public class PdfAsParameterExtractor {
return (String)request.getAttribute(IConfigurationConstants.PLACEHOLDER_WEB_ID);
}
+ public static boolean isPlaceholderSearchEnabled(HttpServletRequest request) {
+ String value = (String)request.getAttribute(IConfigurationConstants.PLACEHOLDER_WEB_ENABLED);
+ if (StringUtils.isNotEmpty(value)) {
+ return Boolean.valueOf(value);
+
+ } else {
+ return true;
+ }
+ }
+
public static String getTransactionId(HttpServletRequest request) {
String transactionId = (String)request.getAttribute(PARAM_TRANSACTION_ID);
return transactionId;
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ErrorPage.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ErrorPage.java
index 72128a9c..42236f5e 100644
--- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ErrorPage.java
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/ErrorPage.java
@@ -42,8 +42,8 @@ import at.gv.egiz.pdfas.web.helper.HTMLFormater;
import at.gv.egiz.pdfas.web.helper.PdfAsHelper;
import at.gv.egiz.pdfas.web.helper.UrlParameterExtractor;
import at.gv.egiz.pdfas.web.stats.StatisticEvent;
-import at.gv.egiz.pdfas.web.stats.StatisticFrontend;
import at.gv.egiz.pdfas.web.stats.StatisticEvent.Status;
+import at.gv.egiz.pdfas.web.stats.StatisticFrontend;
/**
* Servlet implementation class ErrorPage
@@ -116,11 +116,14 @@ public class ErrorPage extends HttpServlet {
String template = PdfAsHelper.getErrorRedirectTemplateSL();
URL url = new URL(errorURL);
- String errorURLProcessed = url.getProtocol() + "://" + // "http" + "://
- url.getHost() + // "myhost"
- ":" + // ":"
- url.getPort() + // "8080"
- url.getPath();
+ String errorURLProcessed = url.getProtocol() + "://" + url.getHost();
+ if (url.getPort() != -1) {
+ errorURLProcessed += ":" + url.getPort();
+
+ }
+
+ errorURLProcessed += url.getPath();
+
template = template.replace("##ERROR_URL##", errorURLProcessed);
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 898e44e2..957614b1 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
@@ -46,10 +46,8 @@ import at.gv.egiz.pdfas.common.exceptions.PDFASError;
import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
import at.gv.egiz.pdfas.common.exceptions.PdfAsSettingsValidationException;
import at.gv.egiz.pdfas.common.settings.ISettings;
-import at.gv.egiz.pdfas.lib.api.IConfigurationConstants;
import at.gv.egiz.pdfas.lib.api.PdfAsFactory;
import at.gv.egiz.pdfas.lib.api.verify.VerifyParameter.SignatureVerificationLevel;
-import at.gv.egiz.pdfas.lib.impl.configuration.PlaceholderWebConfiguration;
import at.gv.egiz.pdfas.web.config.WebConfiguration;
import at.gv.egiz.pdfas.web.exception.PdfAsWebException;
import at.gv.egiz.pdfas.web.filter.UserAgentFilter;
@@ -346,20 +344,6 @@ public class ExternSignServlet extends HttpServlet {
String responseMode = PdfAsParameterExtractor.getResonseMode(request);
PdfAsHelper.setResponseMode(request, response, responseMode);
-
- //read and set placholder web id
- try{
- String placeholder_id = PdfAsParameterExtractor.getPlaceholderId(request);
- if(org.apache.commons.lang3.StringUtils.isNotEmpty(placeholder_id)) {
- PlaceholderWebConfiguration.setValue(IConfigurationConstants.PLACEHOLDER_WEB_ID, placeholder_id);
- } else {
- PlaceholderWebConfiguration.clear();
- }
-
- } catch(Exception e) {
- log.error(e.getLocalizedMessage());
- }
-
String filename = PdfAsParameterExtractor.getFilename(request);
if(filename != null) {
log.debug("Setting Filename in session: " + filename);
@@ -395,6 +379,9 @@ public class ExternSignServlet extends HttpServlet {
document.setInputData(pdfData);
document.setPosition(PdfAsHelper.buildPosString(request, response));
document.setProfile(PdfAsParameterExtractor.getSigType(request));
+ document.setPlaceHolderId(PdfAsParameterExtractor.getPlaceholderId(request));
+ log.debug("Add placeholderId: {} into process information", document.getPlaceHolderId());
+ document.setPlaceholderSearchEnabled(PdfAsParameterExtractor.isPlaceholderSearchEnabled(request));
document.setQrCodeContent(qrcodeContent);
document.setFileName(PdfAsHelper.getPDFFileName(request));
data.addDocumentToSign(document);
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PDFData.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PDFData.java
index bf45745d..96d02f16 100644
--- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PDFData.java
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PDFData.java
@@ -26,6 +26,8 @@ package at.gv.egiz.pdfas.web.servlets;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
import java.util.Iterator;
import java.util.List;
import java.util.zip.Deflater;
@@ -37,6 +39,7 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import at.gv.egiz.pdfas.api.processing.PdfasSignResponse;
import at.gv.egiz.pdfas.api.processing.SignedDocument;
import at.gv.egiz.pdfas.api.ws.PDFASVerificationResponse;
import at.gv.egiz.pdfas.web.config.WebConfiguration;
@@ -85,7 +88,15 @@ public class PDFData extends HttpServlet {
protected void process(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
- if (PdfAsHelper.getPdfSigningResponse(request).getSignedPdfs().isEmpty()) {
+ PdfasSignResponse resultObject = PdfAsHelper.getPdfSigningResponse(request);
+
+ if (resultObject == null) {
+ log.warn("No data for session with Id: {}", request.getSession().getId());
+ PdfAsHelper.setSessionException(request, response,
+ "No signed pdf document available.", null);
+ PdfAsHelper.gotoError(getServletContext(), request, response);
+
+ } else if (resultObject.getSignedPdfs().isEmpty()) {
log.info("No signed pdf document available.");
PdfAsHelper.setSessionException(request, response,
"No signed pdf document available.", null);
@@ -136,7 +147,7 @@ public class PDFData extends HttpServlet {
}
// build response
- response.setHeader("Content-Disposition", "inline;filename=multiple_documents.zip");
+ response.setHeader("Content-Disposition", "inline;filename=\"multiple_documents.zip\"");
response.setContentType("application/zip");
final OutputStream os = response.getOutputStream();
@@ -225,8 +236,13 @@ public class PDFData extends HttpServlet {
return;
}
}
- response.setHeader("Content-Disposition", "inline;filename="
- + PdfAsHelper.getPDFFileName(request));
+ response.setHeader("Content-Disposition", "inline;filename=\""
+ + PdfAsHelper.getPDFFileName(request) + "\"");
+
+ response.setHeader("X-FILENAME-BASE64URL",
+ Base64.getUrlEncoder().encodeToString(
+ PdfAsHelper.getPDFFileName(request).getBytes(StandardCharsets.UTF_8)));
+
final String pdfCert = signedFile.getSignerCertificate();
if (pdfCert != null) {
response.setHeader("Signer-Certificate", pdfCert);
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PlaceholderGeneratorServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PlaceholderGeneratorServlet.java
index f054db6a..b07293b1 100644
--- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PlaceholderGeneratorServlet.java
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/PlaceholderGeneratorServlet.java
@@ -32,6 +32,7 @@ public class PlaceholderGeneratorServlet extends HttpServlet implements Placehol
public static final String PARAM_ID = "id";
public static final String PARAM_PROFILE = "profile";
+ public static final String PARAM_LANG = "lang";
public static final String PARAM_WIDTH = "w";
public static final String PARAM_HEIGHT = "h";
public static final String PARAM_BORDER = "b";
@@ -62,6 +63,8 @@ public class PlaceholderGeneratorServlet extends HttpServlet implements Placehol
String id = req.getParameter(PARAM_ID);
String profile = req.getParameter(PARAM_PROFILE);
+ String lang = req.getParameter(PARAM_LANG) != null ? req.getParameter(PARAM_LANG) : "DE";
+
String buildString = QR_PLACEHOLDER_IDENTIFIER;
@@ -86,7 +89,7 @@ public class PlaceholderGeneratorServlet extends HttpServlet implements Placehol
if(profile != null && !profile.isEmpty()) {
buildString = buildString + ";" + SignaturePlaceholderData.PROFILE_KEY + "=" + profile;
- if(profile.endsWith("_EN")) {
+ if(lang.equalsIgnoreCase("EN")) {
baseImage = "/img/PLACEHOLDER-SIG_EN.png";
filename = filename + "_en";
} else {
@@ -103,7 +106,7 @@ public class PlaceholderGeneratorServlet extends HttpServlet implements Placehol
// default values set for pdf-as wai on buergerkarte.at
int height = 60;
int width = 300;
- int border = 2;
+ int border = 1;
if(req.getParameter(PARAM_HEIGHT) != null) {
try {
@@ -132,7 +135,7 @@ public class PlaceholderGeneratorServlet extends HttpServlet implements Placehol
}
}
- int qrSize = height - ( 2 * border);
+ int qrSize = height - (border);
InputStream is = this.getClass().getClassLoader().getResourceAsStream(baseImage);
if(is == null) {
@@ -146,6 +149,7 @@ public class PlaceholderGeneratorServlet extends HttpServlet implements Placehol
// generate QR code
try {
QRCodeGenerator.generateQRCode(buildString, baos, qrSize);
+
} catch (WriterException e) {
logger.warn("Failed to generate QR Code for placeholder generation", e);
resp.sendError(HttpStatus.SC_INTERNAL_SERVER_ERROR);
@@ -161,7 +165,7 @@ public class PlaceholderGeneratorServlet extends HttpServlet implements Placehol
Graphics g = off_Image.getGraphics();
g.setColor(Color.WHITE);
g.fillRect(0, 0, width, height);
- g.fillRect(border, border, width - (2 * border), height - (2 * border));
+ //g.fillRect(border, border, width - (2 * border), height - (2 * border));
//g.drawImage(base, 0, 0, 250, 98, 0, 0, base.getWidth(), base.getHeight(), null);
g.drawImage(qr, border, border, qrSize + border, qrSize + border, 0, 0, qr.getWidth(), qr.getHeight(), null);
@@ -180,7 +184,7 @@ public class PlaceholderGeneratorServlet extends HttpServlet implements Placehol
int start = (height - textHeight) / 2;
- if(profile != null && profile.endsWith("_EN")) {
+ if(lang.equalsIgnoreCase("EN")) {
g.drawString("placeholder for the", qrSize + ( 3 * border), start + lineSpace);
g.drawString("electronic signature", qrSize + ( 3 * border), start + (2 * lineSpace));
} else {
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/SoapServiceServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/SoapServiceServlet.java
index 71395304..ca005abe 100644
--- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/SoapServiceServlet.java
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/SoapServiceServlet.java
@@ -5,20 +5,12 @@ import javax.xml.ws.Endpoint;
import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
-import org.apache.cxf.feature.LoggingFeature;
-import org.apache.cxf.interceptor.LoggingInInterceptor;
-import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.transport.servlet.CXFNonSpringServlet;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import at.gv.egiz.pdfas.web.ws.PDFASSigningImpl;
import at.gv.egiz.pdfas.web.ws.PDFASVerificationImpl;
public class SoapServiceServlet extends CXFNonSpringServlet {
-
- private static final Logger logger = LoggerFactory
- .getLogger(SoapServiceServlet.class);
/**
*
diff --git a/pdf-as-web/src/main/resources/META-INF/context.xml b/pdf-as-web/src/main/resources/META-INF/context.xml
new file mode 100644
index 00000000..716b2233
--- /dev/null
+++ b/pdf-as-web/src/main/resources/META-INF/context.xml
@@ -0,0 +1,3 @@
+<Context>
+ <CookieProcessor sameSiteCookies="none" />
+</Context> \ No newline at end of file
diff --git a/pdf-as-web/src/main/webapp/WEB-INF/web.xml b/pdf-as-web/src/main/webapp/WEB-INF/web.xml
index 7920ad91..46ae8272 100644
--- a/pdf-as-web/src/main/webapp/WEB-INF/web.xml
+++ b/pdf-as-web/src/main/webapp/WEB-INF/web.xml
@@ -12,6 +12,10 @@
<display-name>ExceptionCatchFilter</display-name>
<description></description>
<filter-class>at.gv.egiz.pdfas.web.filter.ExceptionCatchFilter</filter-class>
+ <init-param>
+ <param-name>statelessServlets</param-name>
+ <param-value>/placeholder,/visblock</param-value>
+ </init-param>
</filter>
<filter>
<filter-name>UserAgentFilter</filter-name>
diff --git a/signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESSignerKeystore.java b/signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESSignerKeystore.java
index 6845adf2..4914833e 100644
--- a/signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESSignerKeystore.java
+++ b/signature-standards/sigs-pades/src/main/java/at/gv/egiz/pdfas/sigs/pades/PAdESSignerKeystore.java
@@ -23,23 +23,6 @@
******************************************************************************/
package at.gv.egiz.pdfas.sigs.pades;
-import at.gv.egiz.pdfas.lib.api.IConfigurationConstants;
-import iaik.asn1.ASN1Object;
-import iaik.asn1.CodingException;
-import iaik.asn1.ObjectID;
-import iaik.asn1.SEQUENCE;
-import iaik.asn1.UTF8String;
-import iaik.asn1.structures.AlgorithmID;
-import iaik.asn1.structures.Attribute;
-import iaik.asn1.structures.ChoiceOfTime;
-import iaik.cms.ContentInfo;
-import iaik.cms.IssuerAndSerialNumber;
-import iaik.cms.SignedData;
-import iaik.cms.SignerInfo;
-import iaik.smime.ess.ESSCertID;
-import iaik.smime.ess.ESSCertIDv2;
-import iaik.x509.X509Certificate;
-
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -63,6 +46,7 @@ import at.gv.egiz.pdfas.common.exceptions.ErrorConstants;
import at.gv.egiz.pdfas.common.exceptions.PDFASError;
import at.gv.egiz.pdfas.common.exceptions.PdfAsException;
import at.gv.egiz.pdfas.common.exceptions.PdfAsSignatureException;
+import at.gv.egiz.pdfas.lib.api.IConfigurationConstants;
import at.gv.egiz.pdfas.lib.api.PdfAsFactory;
import at.gv.egiz.pdfas.lib.api.sign.IPlainSigner;
import at.gv.egiz.pdfas.lib.api.sign.SignParameter;
@@ -70,6 +54,21 @@ import at.gv.egiz.pdfas.lib.api.verify.VerifyResult;
import at.gv.egiz.pdfas.lib.impl.status.RequestedSignature;
import at.gv.egiz.pdfas.lib.util.CertificateUtils;
import at.gv.egiz.pdfas.lib.util.SignatureUtils;
+import iaik.asn1.ASN1Object;
+import iaik.asn1.CodingException;
+import iaik.asn1.ObjectID;
+import iaik.asn1.SEQUENCE;
+import iaik.asn1.UTF8String;
+import iaik.asn1.structures.AlgorithmID;
+import iaik.asn1.structures.Attribute;
+import iaik.asn1.structures.ChoiceOfTime;
+import iaik.cms.ContentInfo;
+import iaik.cms.IssuerAndSerialNumber;
+import iaik.cms.SignedData;
+import iaik.cms.SignerInfo;
+import iaik.smime.ess.ESSCertID;
+import iaik.smime.ess.ESSCertIDv2;
+import iaik.x509.X509Certificate;
public class PAdESSignerKeystore implements IPlainSigner, PAdESConstants {
@@ -83,85 +82,6 @@ public class PAdESSignerKeystore implements IPlainSigner, PAdESConstants {
PrivateKey privKey;
X509Certificate cert;
- private void readKeyStore(KeyStore ks, String alias, String keypassword) throws Throwable {
- if (keypassword == null) {
- throw new PdfAsException("error.pdf.sig.16");
- }
- PasswordProtection pwdProt = new PasswordProtection(
- keypassword.toCharArray());
-
- logger.info("Opening Alias: [" + alias + "]");
-
- Entry entry = ks.getEntry(alias, pwdProt);
-
- if (!(entry instanceof PrivateKeyEntry)) {
- throw new PdfAsException("error.pdf.sig.18");
- }
-
- PrivateKeyEntry privateEntry = (PrivateKeyEntry) entry;
-
- privKey = privateEntry.getPrivateKey();
-
- if (privKey == null) {
- throw new PdfAsException("error.pdf.sig.13");
- }
-
- Certificate c = privateEntry.getCertificate();
-
- if (c == null) {
- if (privateEntry.getCertificateChain() != null) {
- if (privateEntry.getCertificateChain().length > 0) {
- c = privateEntry.getCertificateChain()[0];
- }
- }
- }
-
- if (c == null) {
- throw new PdfAsException("error.pdf.sig.17");
- }
-
- cert = new X509Certificate(c.getEncoded());
- }
-
- private KeyStore buildKeyStoreFromFile(String file, String kspassword,
- String type, String provider) throws Throwable {
- String viusalProvider = (provider == null ? "IAIK" : provider);
- logger.trace("Opening Keystore: " + file + " with [" + viusalProvider
- + "]");
-
- KeyStore ks = null;
- if (provider == null) {
- ks = KeyStore.getInstance(type);
- } else {
- ks = KeyStore.getInstance(type, provider);
- }
-
- if (ks == null) {
- throw new PdfAsException("error.pdf.sig.14");
- }
- if (kspassword == null) {
- throw new PdfAsException("error.pdf.sig.15");
- }
- FileInputStream is = null;
- try {
- is = new FileInputStream(file);
- ks.load(is, kspassword.toCharArray());
- } finally {
- if (is != null) {
- is.close();
- }
- }
- return ks;
- }
-
- private void loadKeystore(String file, String alias, String kspassword,
- String keypassword, String type, String provider) throws Throwable {
-
- KeyStore ks = buildKeyStoreFromFile(file, kspassword, type, provider);
-
- readKeyStore(ks, alias, keypassword);
- }
-
public PAdESSignerKeystore(KeyStore ks, String alias,
String keypassword) throws PDFASError {
try {
@@ -221,6 +141,160 @@ public class PAdESSignerKeystore implements IPlainSigner, PAdESConstants {
return cert;
}
+ public byte[] sign(byte[] input, int[] byteRange, SignParameter parameter,
+ RequestedSignature requestedSignature) throws PdfAsException {
+ try {
+ logger.info("Creating PAdES signature.");
+
+ requestedSignature.getStatus().getMetaInformations()
+ .put(ErrorConstants.STATUS_INFO_SIGDEVICE, SIGNATURE_DEVICE);
+ requestedSignature.getStatus().getMetaInformations()
+ .put(ErrorConstants.STATUS_INFO_SIGDEVICEVERSION, PdfAsFactory.getVersion());
+
+ IssuerAndSerialNumber issuer = new IssuerAndSerialNumber(cert);
+
+ AlgorithmID[] algorithms = CertificateUtils.getAlgorithmIDs(cert);
+
+ SignerInfo signer1 = new SignerInfo(issuer, algorithms[1],
+ algorithms[0], privKey);
+
+ SignedData si = new SignedData(input, SignedData.EXPLICIT);
+ si.addCertificates(new Certificate[] { cert });
+
+
+ //Check PAdES Flag
+ if (parameter.getConfiguration().hasValue(IConfigurationConstants.SIG_PADES_FORCE_FLAG))
+ {
+ if (IConfigurationConstants.TRUE.equalsIgnoreCase(parameter.getConfiguration().getValue(IConfigurationConstants.SIG_PADES_FORCE_FLAG)))
+ {
+ setAttributes(cert, signer1);
+ }
+ else
+ {
+ setAttributes("application/pdf", cert, new Date(), signer1);
+ }
+ }
+ else
+ {
+ setAttributes("application/pdf", cert, new Date(), signer1);
+ }
+
+ si.addSignerInfo(signer1);
+ InputStream dataIs = si.getInputStream();
+ byte[] buf = new byte[1024];
+ @SuppressWarnings("unused")
+ int r;
+ while ((r = dataIs.read(buf)) > 0)
+ ; // skip data
+ ContentInfo ci = new ContentInfo(si);
+ byte[] signature = ci.getEncoded();
+
+ VerifyResult verifyResult = SignatureUtils.verifySignature(
+ signature, input);
+
+ return signature;
+ } catch (NoSuchAlgorithmException e) {
+ throw new PdfAsSignatureException("error.pdf.sig.01", e);
+ } catch (iaik.cms.CMSException e) {
+ throw new PdfAsSignatureException("error.pdf.sig.01", e);
+ } catch (IOException e) {
+ throw new PdfAsSignatureException("error.pdf.sig.01", e);
+ } catch (CertificateException e) {
+ throw new PdfAsSignatureException("error.pdf.sig.01", e);
+ } catch (CodingException e) {
+ throw new PdfAsSignatureException("error.pdf.sig.01", e);
+ } catch (PDFASError e) {
+ throw new PdfAsSignatureException("error.pdf.sig.01", e);
+ }
+ }
+
+ public String getPDFSubFilter() {
+ return SUBFILTER_ETSI_CADES_DETACHED;
+ }
+
+ public String getPDFFilter() {
+ return FILTER_ADOBE_PPKLITE;
+ }
+
+ private void readKeyStore(KeyStore ks, String alias, String keypassword) throws Throwable {
+ if (keypassword == null) {
+ throw new PdfAsException("error.pdf.sig.16");
+ }
+ PasswordProtection pwdProt = new PasswordProtection(
+ keypassword.toCharArray());
+
+ logger.info("Opening Alias: [" + alias + "]");
+
+ Entry entry = ks.getEntry(alias, pwdProt);
+
+ if (!(entry instanceof PrivateKeyEntry)) {
+ throw new PdfAsException("error.pdf.sig.18");
+ }
+
+ PrivateKeyEntry privateEntry = (PrivateKeyEntry) entry;
+
+ privKey = privateEntry.getPrivateKey();
+
+ if (privKey == null) {
+ throw new PdfAsException("error.pdf.sig.13");
+ }
+
+ Certificate c = privateEntry.getCertificate();
+
+ if (c == null) {
+ if (privateEntry.getCertificateChain() != null) {
+ if (privateEntry.getCertificateChain().length > 0) {
+ c = privateEntry.getCertificateChain()[0];
+ }
+ }
+ }
+
+ if (c == null) {
+ throw new PdfAsException("error.pdf.sig.17");
+ }
+
+ cert = new X509Certificate(c.getEncoded());
+ }
+
+ private KeyStore buildKeyStoreFromFile(String file, String kspassword,
+ String type, String provider) throws Throwable {
+ String viusalProvider = (provider == null ? "IAIK" : provider);
+ logger.trace("Opening Keystore: " + file + " with [" + viusalProvider
+ + "]");
+
+ KeyStore ks = null;
+ if (provider == null) {
+ ks = KeyStore.getInstance(type);
+ } else {
+ ks = KeyStore.getInstance(type, provider);
+ }
+
+ if (ks == null) {
+ throw new PdfAsException("error.pdf.sig.14");
+ }
+ if (kspassword == null) {
+ throw new PdfAsException("error.pdf.sig.15");
+ }
+ FileInputStream is = null;
+ try {
+ is = new FileInputStream(file);
+ ks.load(is, kspassword.toCharArray());
+ } finally {
+ if (is != null) {
+ is.close();
+ }
+ }
+ return ks;
+ }
+
+ private void loadKeystore(String file, String alias, String kspassword,
+ String keypassword, String type, String provider) throws Throwable {
+
+ KeyStore ks = buildKeyStoreFromFile(file, kspassword, type, provider);
+
+ readKeyStore(ks, alias, keypassword);
+ }
+
private void setMimeTypeAttrib(List<Attribute> attributes, String mimeType) {
String oidStr = "0.4.0.1733.2.1";
String name = "mime-type";
@@ -292,79 +366,4 @@ public class PAdESSignerKeystore implements IPlainSigner, PAdESConstants {
signerInfo.setSignedAttributes(attributeArray);
}
- public byte[] sign(byte[] input, int[] byteRange, SignParameter parameter,
- RequestedSignature requestedSignature) throws PdfAsException {
- try {
- logger.info("Creating PAdES signature.");
-
- requestedSignature.getStatus().getMetaInformations()
- .put(ErrorConstants.STATUS_INFO_SIGDEVICE, SIGNATURE_DEVICE);
- requestedSignature.getStatus().getMetaInformations()
- .put(ErrorConstants.STATUS_INFO_SIGDEVICEVERSION, PdfAsFactory.getVersion());
-
- IssuerAndSerialNumber issuer = new IssuerAndSerialNumber(cert);
-
- AlgorithmID[] algorithms = CertificateUtils.getAlgorithmIDs(cert);
-
- SignerInfo signer1 = new SignerInfo(issuer, algorithms[1],
- algorithms[0], privKey);
-
- SignedData si = new SignedData(input, SignedData.EXPLICIT);
- si.addCertificates(new Certificate[] { cert });
-
-
- //Check PAdES Flag
- if (parameter.getConfiguration().hasValue(IConfigurationConstants.SIG_PADES_FORCE_FLAG))
- {
- if (IConfigurationConstants.TRUE.equalsIgnoreCase(parameter.getConfiguration().getValue(IConfigurationConstants.SIG_PADES_FORCE_FLAG)))
- {
- setAttributes(cert, signer1);
- }
- else
- {
- setAttributes("application/pdf", cert, new Date(), signer1);
- }
- }
- else
- {
- setAttributes("application/pdf", cert, new Date(), signer1);
- }
-
- si.addSignerInfo(signer1);
- InputStream dataIs = si.getInputStream();
- byte[] buf = new byte[1024];
- @SuppressWarnings("unused")
- int r;
- while ((r = dataIs.read(buf)) > 0)
- ; // skip data
- ContentInfo ci = new ContentInfo(si);
- byte[] signature = ci.getEncoded();
-
- VerifyResult verifyResult = SignatureUtils.verifySignature(
- signature, input);
-
- return signature;
- } catch (NoSuchAlgorithmException e) {
- throw new PdfAsSignatureException("error.pdf.sig.01", e);
- } catch (iaik.cms.CMSException e) {
- throw new PdfAsSignatureException("error.pdf.sig.01", e);
- } catch (IOException e) {
- throw new PdfAsSignatureException("error.pdf.sig.01", e);
- } catch (CertificateException e) {
- throw new PdfAsSignatureException("error.pdf.sig.01", e);
- } catch (CodingException e) {
- throw new PdfAsSignatureException("error.pdf.sig.01", e);
- } catch (PDFASError e) {
- throw new PdfAsSignatureException("error.pdf.sig.01", e);
- }
- }
-
- public String getPDFSubFilter() {
- return SUBFILTER_ETSI_CADES_DETACHED;
- }
-
- public String getPDFFilter() {
- return FILTER_ADOBE_PPKLITE;
- }
-
}