aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab-ci.yml1
-rw-r--r--build.gradle8
-rw-r--r--pdf-as-common/build.gradle4
-rw-r--r--pdf-as-legacy/build.gradle4
-rw-r--r--pdf-as-lib/build.gradle12
-rw-r--r--pdf-as-lib/src/main/java/at/gv/egiz/pdfas/lib/impl/PdfAsImpl.java10
-rw-r--r--pdf-as-moa/build.gradle2
-rw-r--r--pdf-as-pdfbox-2/build.gradle10
-rw-r--r--pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/pdfbox2/placeholder/SignaturePlaceholderExtractor.java214
-rw-r--r--pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox2/PADESPDFBOXSigner.java27
-rw-r--r--pdf-as-pdfbox-2/src/main/java/at/knowcenter/wag/egov/egiz/pdfbox2/pdf/PDFUtilities.java45
-rw-r--r--pdf-as-pdfbox-2/src/test/java/at/gv/egiz/pdfas/lib/testpdfbox/PDFBoxPlaceholderExtractorTest.java23
-rw-r--r--pdf-as-pdfbox-2/src/test/resources/data/Test-sign.pdfbin0 -> 62464 bytes
-rw-r--r--pdf-as-pdfbox-2/src/test/resources/data/Testdoc_Signatur.pdfbin0 -> 84684 bytes
-rw-r--r--pdf-as-pdfbox-2/src/test/resources/data/own_Testdoc+Signatur-sign-sign-4_sign-sign.pdfbin0 -> 260014 bytes
-rw-r--r--pdf-as-pdfbox-2/src/test/resources/data/own_Testdoc+Signatur-sign-sign-4_sign.pdfbin0 -> 216197 bytes
-rw-r--r--pdf-as-pdfbox-2/src/test/resources/data/own_Testdoc+Signatur-sign-sign.pdfbin0 -> 172415 bytes
-rw-r--r--pdf-as-pdfbox-2/src/test/resources/data/own_Testdoc+Signatur-sign.pdfbin0 -> 128804 bytes
-rw-r--r--pdf-as-tests/build.gradle3
-rw-r--r--pdf-as-web-client/build.gradle2
-rw-r--r--pdf-as-web-statistic-api/build.gradle2
-rw-r--r--pdf-as-web-status/build.gradle2
-rw-r--r--pdf-as-web/build.gradle12
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/exception/PdfAsSecurityLayerException.java5
-rw-r--r--pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/DataURLServlet.java42
-rw-r--r--signature-standards/sigs-pades/build.gradle2
-rw-r--r--signature-standards/sigs-pkcs7detached/build.gradle2
27 files changed, 293 insertions, 139 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index a900b385..dafafa86 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -90,7 +90,6 @@ release:
script: |
echo "Releasing version $VERSION of $LIB_NAME"
echo "Publishing version $VERSION to public EGIZ maven"
- cd ./moaSig
./gradlew release
artifacts:
name: "${CI_PROJECT_NAME}-${CI_COMMIT_SHORT_SHA}-release"
diff --git a/build.gradle b/build.gradle
index b2ca5772..836f06b3 100644
--- a/build.gradle
+++ b/build.gradle
@@ -18,7 +18,7 @@ allprojects {
url "https://repo.spring.io/milestone/"
}
}
- version = '4.4.2-SNAPSHOT'
+ version = '4.4.3'
}
subprojects {
@@ -88,11 +88,9 @@ subprojects {
version = version
pdfasversion = version
revision = getCheckedOutGitCommitHash()
- //tomcatVersion = '7.0.54';
- //tomcatVersion = '8.0.36';
- tomcatVersion = '9.0.93';
+ tomcatVersion = '9.0.115';
slf4jVersion = '1.7.36'
- cxfVersion = '3.5.9'
+ cxfVersion = '3.5.11'
}
jar { manifest.attributes provider: 'EGIZ', 'Specification-Version': getCheckedOutGitCommitHash(), 'Implementation-Version': project.version }
diff --git a/pdf-as-common/build.gradle b/pdf-as-common/build.gradle
index 24eeac30..7dfaf71d 100644
--- a/pdf-as-common/build.gradle
+++ b/pdf-as-common/build.gradle
@@ -22,8 +22,8 @@ releases.dependsOn sourcesJar
dependencies {
api group: 'org.slf4j', name: 'slf4j-api', version: slf4jVersion
api group: 'commons-collections', name: 'commons-collections', version: '3.2.2'
- api group: 'commons-io', name: 'commons-io', version: '2.16.1'
- api group: 'ognl', name: 'ognl', version: '3.3.4'
+ api group: 'commons-io', name: 'commons-io', version: '2.21.0'
+ api group: 'ognl', name: 'ognl', version: '3.3.5'
api group: 'javax.xml.bind', name: 'jaxb-api', version: '2.3.1'
api 'commons-codec:commons-codec:1.17.1'
api group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '2.3.3'
diff --git a/pdf-as-legacy/build.gradle b/pdf-as-legacy/build.gradle
index 5f1fe5d4..de310b1c 100644
--- a/pdf-as-legacy/build.gradle
+++ b/pdf-as-legacy/build.gradle
@@ -19,8 +19,8 @@ dependencies {
implementation project (':pdf-as-moa')
implementation project (':signature-standards:sigs-pkcs7detached')
implementation project (':signature-standards:sigs-pades')
- implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.17.0'
- implementation group: 'commons-codec', name: 'commons-codec', version: '1.17.1'
+ implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.20.0'
+ implementation group: 'commons-codec', name: 'commons-codec', version: '1.21.0'
}
task releases(type: Copy) {
diff --git a/pdf-as-lib/build.gradle b/pdf-as-lib/build.gradle
index e95937fa..d02ae9b2 100644
--- a/pdf-as-lib/build.gradle
+++ b/pdf-as-lib/build.gradle
@@ -62,18 +62,18 @@ repositories {
dependencies {
api project (':pdf-as-common')
- api group: 'org.apache.commons', name: 'commons-lang3', version: '3.17.0'
+ api group: 'org.apache.commons', name: 'commons-lang3', version: '3.20.0'
api group: 'org.apache.httpcomponents', name: 'httpmime', version: '4.5.14'
api group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.14'
- api group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.70'
+ api group: 'org.bouncycastle', name: 'bcprov-jdk18on', version: '1.82'
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.11.0'
+ api group: 'com.google.code.gson', name: 'gson', version: '2.13.2'
api group: 'org.bitbucket.b_c', name: 'jose4j', version: '0.9.6'
- api group: 'commons-io', name: 'commons-io', version: '2.16.1'
+ api group: 'commons-io', name: 'commons-io', version: '2.21.0'
api group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '2.3.3'
- api 'org.apache.commons:commons-collections4:4.4'
- api group: 'ognl', name: 'ognl', version: '3.3.4'
+ api 'org.apache.commons:commons-collections4:4.5.0'
+ api group: 'ognl', name: 'ognl', version: '3.3.5'
api files('libs/iaik_eccelerate_cms-6.02.jar')
api files('libs/iaik_eccelerate-6.02.jar')
api files('libs/iaik_jce_full-5.63_moa.jar')
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 ebd8ec90..255c76e6 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
@@ -537,7 +537,15 @@ public class PdfAsImpl implements PdfAs, IConfigurationConstants,
}
private SignResult createSignResult(OperationStatus status)
- throws IOException {
+ throws IOException, PDFASError {
+
+ if (status.getPdfObject().getSignedDocument() == null
+ || status.getPdfObject().getSignedDocument().length <= 0) {
+ logger.warn("No signed document in session. Maybe signing-service communication stopped by an error");
+ throw new PDFASError(ERROR_SIG_INVALID_STATUS,
+ "No signed document in session. Maybe signing-service communication stopped by an error");
+ }
+
// ================================================================
// Create SignResult
final SignResultImpl result = new SignResultImpl();
diff --git a/pdf-as-moa/build.gradle b/pdf-as-moa/build.gradle
index f9938f88..f7f46a1e 100644
--- a/pdf-as-moa/build.gradle
+++ b/pdf-as-moa/build.gradle
@@ -13,7 +13,7 @@ buildscript {
mavenLocal()
mavenCentral()
}
- dependencies { classpath("commons-io:commons-io:2.15.1") }
+ dependencies { classpath("commons-io:commons-io:2.21.0") }
}
sourceSets {
diff --git a/pdf-as-pdfbox-2/build.gradle b/pdf-as-pdfbox-2/build.gradle
index b71f0939..ef71aefe 100644
--- a/pdf-as-pdfbox-2/build.gradle
+++ b/pdf-as-pdfbox-2/build.gradle
@@ -33,11 +33,11 @@ dependencies {
implementation project (':pdf-as-lib')
implementation group: 'org.slf4j', name: 'slf4j-api', version: slf4jVersion
implementation 'org.slf4j:jcl-over-slf4j:1.7.36'
- api group: 'org.apache.pdfbox', name: 'pdfbox', version: '2.0.32'
- api group: 'org.apache.pdfbox', name: 'pdfbox-tools', version: '2.0.32'
- api group: 'org.apache.pdfbox', name: 'preflight', version: '2.0.32'
- implementation group: 'commons-io', name: 'commons-io', version: '2.16.1'
- implementation group: 'ognl', name: 'ognl', version: '3.3.4'
+ api group: 'org.apache.pdfbox', name: 'pdfbox', version: '2.0.35'
+ api group: 'org.apache.pdfbox', name: 'pdfbox-tools', version: '2.0.35'
+ api group: 'org.apache.pdfbox', name: 'preflight', version: '2.0.35'
+ implementation group: 'commons-io', name: 'commons-io', version: '2.21.0'
+ implementation group: 'ognl', name: 'ognl', version: '3.3.5'
api group: 'com.github.jai-imageio', name: 'jai-imageio-jpeg2000', version: '1.4.0'
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'
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 7cff90d6..0b148551 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
@@ -52,9 +52,11 @@ import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Map.Entry;
+import java.util.Objects;
import java.util.Properties;
import java.util.Set;
import java.util.Vector;
@@ -69,6 +71,8 @@ import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.graphics.PDXObject;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
+import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDPropBuild;
+import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDPropBuildDataDict;
import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
import org.apache.pdfbox.util.Matrix;
@@ -101,6 +105,9 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
public class SignaturePlaceholderExtractor extends PDFStreamEngine implements PlaceholderExtractorConstants {
+ public static final String PREFIX = "PDF-AS_";
+
+ private final Set<String> placeholderNames = new HashSet<>();
private final List<SignaturePlaceholderData> placeholders = new ArrayList<>();
private int currentPage = 0;
@@ -137,51 +144,36 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine implements Pl
*/
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++;
+ log.debug("Initial found #{} already used placeholders", extistingSignatureNames.size());
- 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);
-
- }
- }
+ SignaturePlaceholderData foundOnSinglePage =
+ parseDocumentAndSearchOnSiglePages(doc, extistingSignatureNames, placeholderId, matchMode);
- 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");
+ if (foundOnSinglePage != null) {
+ return foundOnSinglePage;
+ } else {
+ return searchOnAnyPage(extistingSignatureNames, matchMode);
+
}
- return null;
}
+ /**
+ * Set a placeholderId into signature directory.
+ *
+ * @param signature Signature
+ * @param placeholderId placeholderId
+ */
+ public static void setPlaceholderId(PDSignature signature, String placeholderId) {
+ PDPropBuild sigProps = getOrNew(signature);
+ PDPropBuildDataDict appProps = getOrNew(sigProps);
+ appProps.setName(PREFIX + placeholderId);
+ sigProps.setPDPropBuildApp(appProps);
+ signature.setPropBuild(sigProps);
+
+ }
+
@Override
protected void processOperator(Operator operator, List<COSBase> arguments)
throws IOException {
@@ -235,12 +227,14 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine implements Pl
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());
+
+ data.setPlaceholderName(buildUniqueObjectName(objectName));
+ log.debug("Found Placeholder at: {}", data.toString());
placeholders.add(data);
+ placeholderNames.add(data.getPlaceholderName());
} catch (final PdfAsException e) {
throw new IOException();
@@ -255,8 +249,78 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine implements Pl
super.processOperator(operator, arguments);
}
}
+
+ private SignaturePlaceholderData searchOnAnyPage(List<String> extistingSignatureNames, int matchMode) throws PlaceholderExtractionException {
+ if (placeholders.size() > 0) {
+ final SignaturePlaceholderData ret = matchPlaceholderDocument(
+ removeAlreadyUsePlaceholders(placeholders, extistingSignatureNames), 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;
+
+ }
+
+ private SignaturePlaceholderData parseDocumentAndSearchOnSiglePages(PDDocument doc, List<String> extistingSignatureNames,
+ String placeholderId, int matchMode) throws PDFIOException {
+ int pageNr = 0;
+ for (final PDPage page : doc.getPages()) {
+ pageNr++;
+
+ SignaturePlaceholderData ret = processSinglePage(page, pageNr, extistingSignatureNames, placeholderId, matchMode);
+ if (ret != null) {
+ log.debug("Found placeholder to use on page: {}. Stopping further search ... ", this.currentPage);
+ return ret;
+
+ }
+ }
+
+ return null;
+
+ }
+
+ private SignaturePlaceholderData processSinglePage(PDPage page, int pageNr, List<String> extistingSignatureNames,
+ String placeholderId, int matchMode) throws PDFIOException {
+ try {
+ this.currentPage = pageNr;
+ if (page.getContents() != null && page.getResources() != null && page.getContentStreams() != null) {
+ processPage(page); // TODO: pdfbox2 - right?
+
+ }
+
+ return matchPlaceholderOnSinglePage(
+ removeAlreadyUsePlaceholders(placeholders, extistingSignatureNames), placeholderId, matchMode);
+
+ } catch (final Throwable e) {
+ throw new PDFIOException("error.pdf.io.04", e);
+
+ }
+ }
+
+
+ /**
+ * Builds unique placeholderId from PDF element.
+ *
+ * @param name PDF element name
+ * @return unique identifier
+ */
+ private String buildUniqueObjectName(COSName name) {
+ final String baseName = name.getName();
+ int i = 0;
+ String candidate = baseName;
+ while (placeholderNames.contains(candidate)) {
+ candidate = baseName + "_" + (++i);
+ }
+ return candidate;
+ }
- private SignaturePlaceholderData matchPlaceholderPage(
+ private SignaturePlaceholderData matchPlaceholderOnSinglePage(
List<SignaturePlaceholderData> placeholders, String placeholderId, int matchMode) {
log.debug("Searching requested placeholder:{} with matchMode:{} in single page ... ", placeholderId, matchMode);
@@ -264,15 +328,22 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine implements Pl
return null;
}
-
- // check if find a placeholder with that ID
+
for (final SignaturePlaceholderData data : placeholders) {
+
+ /*
+ * If specific placeholderId is requested and placeholder as an Id, check if it already matches
+ */
if (placeholderId != null && data.getId() != null
&& matchPlaceHolderId(placeholderId, data.getId())) {
return data;
}
+ /*
+ * If mode is not sorted and there is no specific placeholderId requested
+ * and placeholder contains no Id use the first one found
+ */
if (matchMode != PLACEHOLDER_MATCH_MODE_SORTED
&& placeholderId == null && data.getId() == null) {
return data;
@@ -284,10 +355,9 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine implements Pl
}
private SignaturePlaceholderData matchPlaceholderDocument(
- List<SignaturePlaceholderData> placeholders, String placeholderId,
- int matchMode) throws PlaceholderExtractionException {
+ List<SignaturePlaceholderData> placeholders, int matchMode) throws PlaceholderExtractionException {
- log.debug("Searching requested placeholder:{} with matchMode:{} on any page ... ", placeholderId, matchMode);
+ log.debug("Searching requested placeholder with matchMode:{} on any page ... ", matchMode);
if (matchMode == PLACEHOLDER_MATCH_MODE_STRICT) {
throw new PlaceholderExtractionException("error.pdf.stamp.09");
@@ -382,19 +452,20 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine implements Pl
}
}
+
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());
- }
- }
+ final List<PDSignature> pdSignatureList = doc.getSignatureDictionaries();
+ return pdSignatureList.stream()
+ .map(el -> readPlaceHolderId(el))
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+
} catch (final IOException e) {
- e.printStackTrace();
+ log.warn("Can not parse signature dictionaries", e);
+ return Collections.emptyList();
+
}
- return existingLocations;
}
private List<SignaturePlaceholderData> removeAlreadyUsePlaceholders(
@@ -403,7 +474,7 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine implements Pl
List<SignaturePlaceholderData> result = placeholders.stream()
.filter(el -> !existingPlaceholders.contains(el.getPlaceholderName()))
.collect(Collectors.toList());
- log.debug("Initial found #{} placeholders, but #{} removed because already used.",
+ log.trace("Initial found #{} placeholders, but #{} removed because already used.",
placeholders.size(), placeholders.size() - result.size());
return result;
@@ -511,4 +582,33 @@ public class SignaturePlaceholderExtractor extends PDFStreamEngine implements Pl
}
return null;
}
+
+ /**
+ * Read placeholderId from signature.
+ *
+ * @param signature Signature
+ * @return placeholderId or <code>null</code> if there is no placeholderId.
+ */
+ private static String readPlaceHolderId(PDSignature signature) {
+ PDPropBuild sigProps = getOrNew(signature);
+ PDPropBuildDataDict appProps = getOrNew(sigProps);
+ String newHolderId = appProps.getName() != null && appProps.getName().startsWith(PREFIX)
+ ? appProps.getName().substring(PREFIX.length())
+ : appProps.getName();
+
+ // read placeHolderId from old location element as backup
+ return newHolderId != null ? newHolderId : signature.getLocation();
+
+ }
+
+ private static final PDPropBuildDataDict getOrNew(PDPropBuild sigProps) {
+ PDPropBuildDataDict props = sigProps.getApp();
+ return props != null ? props : new PDPropBuildDataDict();
+ }
+
+ private static final PDPropBuild getOrNew(PDSignature signature) {
+ PDPropBuild sigProps = signature.getPropBuild();
+ return sigProps != null ? sigProps : new PDPropBuild();
+
+ }
}
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 37ceee97..d8a25a9a 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
@@ -85,6 +85,7 @@ import at.gv.egiz.pdfas.lib.impl.ErrorExtractor;
import at.gv.egiz.pdfas.lib.impl.SignaturePositionImpl;
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.placeholder.SignaturePlaceholderExtractor;
import at.gv.egiz.pdfas.lib.impl.pdfbox2.positioning.Positioning;
import at.gv.egiz.pdfas.lib.impl.pdfbox2.utils.PdfBoxUtils;
import at.gv.egiz.pdfas.lib.impl.placeholder.PlaceholderFilter;
@@ -163,9 +164,9 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {
pdfObject.getStatus().getSignParamter().getPlaceHolderId());
if (nextPlaceholderData != null) {
- log.info("Placeholder data found.");
- signature.setLocation(nextPlaceholderData.getPlaceholderName());
-
+ log.info("Placeholder data found. Injection placeholderId ...");
+ SignaturePlaceholderExtractor.setPlaceholderId(signature, nextPlaceholderData.getPlaceholderName());
+
if (nextPlaceholderData.getProfile() != null) {
if (pdfObject.getStatus().getSettings().isValue(IConfigurationConstants.PLACEHOLDER_PROFILE_OVERWRITE, true)) {
log.debug("Placeholder Profile set to: {}", nextPlaceholderData.getProfile());
@@ -613,24 +614,24 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants {
return tablePos;
} else {
- TablePos signaturePos = null;
- final String signaturePosString = signatureProfileConfiguration.getDefaultPositioning();
+ TablePos defaultSignaturePos = null;
+ final String defaultPosString = signatureProfileConfiguration.getDefaultPositioning();
- if (signaturePosString != null) {
- log.debug("using signature Positioning: " + signaturePosString);
- signaturePos = new TablePos(signaturePosString);
+
+ if (defaultPosString != null) {
+ log.debug("Default signature positioning is: {}", defaultPosString);
+ defaultSignaturePos = new TablePos(defaultPosString);
}
- log.debug("using Positioning: " + profilePosParam);
-
if (profilePosParam != null) {
+ log.debug("Find positioning parameter: {} Merge it with default ...", profilePosParam);
// Merge Signature Position
- return new TablePos(profilePosParam, signaturePos);
+ return new TablePos(profilePosParam, defaultSignaturePos);
- } else if (signaturePos != null){
+ } else if (defaultSignaturePos != null){
// Fallback to signature Position!
- return signaturePos;
+ return defaultSignaturePos;
} else {
return new TablePos();
diff --git a/pdf-as-pdfbox-2/src/main/java/at/knowcenter/wag/egov/egiz/pdfbox2/pdf/PDFUtilities.java b/pdf-as-pdfbox-2/src/main/java/at/knowcenter/wag/egov/egiz/pdfbox2/pdf/PDFUtilities.java
index 995b4e10..741860e2 100644
--- a/pdf-as-pdfbox-2/src/main/java/at/knowcenter/wag/egov/egiz/pdfbox2/pdf/PDFUtilities.java
+++ b/pdf-as-pdfbox-2/src/main/java/at/knowcenter/wag/egov/egiz/pdfbox2/pdf/PDFUtilities.java
@@ -68,33 +68,37 @@ public abstract class PDFUtilities implements IConfigurationConstants{
public static float getMaxYPosition(
PDDocument pdfDataSource, int page, IPDFVisualObject pdfTable, float signatureMarginVertical, float footer_line, ISettings settings) throws IOException {
-
- PositioningRenderer renderer = new PositioningRenderer(pdfDataSource);
- //BufferedImage bim = renderer.renderImage(page);
-
- int width = (int) pdfDataSource.getPage(page).getCropBox().getWidth();
- int height = (int) pdfDataSource.getPage(page).getCropBox().getHeight();
- BufferedImage bim = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+ int width = (int) pdfDataSource.getPage(page).getCropBox().getWidth();
+ int height = (int) pdfDataSource.getPage(page).getCropBox().getHeight();
+
+ // flip image in case of page rotation is 90 or 270
+ BufferedImage bim = (pdfDataSource.getPage(page).getRotation() % 180 == 0)
+ ? new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB)
+ : new BufferedImage(height, width, BufferedImage.TYPE_INT_ARGB);
+
Graphics2D graphics = bim.createGraphics();
graphics.setBackground(MAGIC_COLOR);
-
+
+ PositioningRenderer renderer = new PositioningRenderer(pdfDataSource);
renderer.renderPageToGraphics(page, graphics);
- Color bgColor = MAGIC_COLOR;
-
- if("true".equals(settings.getValue(BG_COLOR_DETECTION))){ //only used if background color should be determined automatically
- bgColor = determineBackgroundColor(bim);
- }
-
+ /*
+ * Only used if background color should be determined automatically.
+ * That can be necessary of PDF contains page-size images.
+ */
+ Color bgColor = "true".equals(settings.getValue(BG_COLOR_DETECTION))
+ ? determineBackgroundColor(bim)
+ : MAGIC_COLOR;
+
int yCoord = bim.getHeight() - 1 - (int)footer_line;
for(int row = yCoord; row >= 0; row--)
{
- if (row == 0)
- yCoord = row;
- else
- {
+ if (row == 0) {
+ yCoord = row;
+
+ } else {
for(int col = 0; col < bim.getWidth(); col++){
int val = bim.getRGB(col, row);
if(val != bgColor.getRGB()){
@@ -105,11 +109,14 @@ public abstract class PDFUtilities implements IConfigurationConstants{
}
}
}
+
String outFile = settings.getValue(SIG_PLACEMENT_DEBUG_OUTPUT);
- if(outFile!=null){
+ if(outFile != null){
ImageIOUtil.writeImage(bim, outFile, 72);
}
+
return yCoord;
+
}
public static Color determineBackgroundColor(BufferedImage bim){
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
index fbe3cdea..8bd733c3 100644
--- 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
@@ -2,11 +2,13 @@ package at.gv.egiz.pdfas.lib.testpdfbox;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.util.List;
import org.apache.pdfbox.pdmodel.PDDocument;
+import org.junit.Ignore;
import org.junit.Test;
import at.gv.egiz.pdfas.lib.impl.pdfbox2.placeholder.SignatureFieldsAndPlaceHolderExtractor;
@@ -20,7 +22,6 @@ public class PDFBoxPlaceholderExtractorTest {
public void nextPlaceholder() {
SignaturePlaceholderData result = getNextSignaturePlaceHolder("/data/platzhalter_en_de_test.pdf");
assertEquals("Im48", result.getPlaceholderName());
-
}
@Test
@@ -28,9 +29,29 @@ public class PDFBoxPlaceholderExtractorTest {
public void allPlaceHolders() {
List<String> listOfPlaceHolders = getPlaceHolders("/data/platzhalter_en_de_test.pdf");
assertNotNull(listOfPlaceHolders);
+ assertTrue(listOfPlaceHolders.isEmpty());
}
+ @Test
+ @SneakyThrows
+ public void nextPlaceholderDuplicateElements() {
+ assertEquals("Im0_1", getNextSignaturePlaceHolder("/data/Testdoc_Signatur.pdf").getPlaceholderName());
+ assertEquals("Im0_2", getNextSignaturePlaceHolder("/data/own_Testdoc+Signatur-sign-sign.pdf").getPlaceholderName());
+ assertEquals("Im0_2", getNextSignaturePlaceHolder("/data/own_Testdoc+Signatur-sign-sign-4_sign.pdf").getPlaceholderName());
+ assertEquals("Im0", getNextSignaturePlaceHolder("/data/own_Testdoc+Signatur-sign-sign-4_sign-sign.pdf").getPlaceholderName());
+
+ }
+
+ @Test
+ @Ignore
+ @SneakyThrows
+ public void placeHolderInAnnotation() {
+ SignaturePlaceholderData listOfPlaceHolders = getNextSignaturePlaceHolder("/data/Test-sign.pdf");
+ assertNotNull(listOfPlaceHolders);
+
+ }
+
private static List<String> getPlaceHolders(String filePath) throws IOException {
final PDDocument doc = PDDocument.load(PDFBoxPlaceholderExtractorTest.class.getResourceAsStream(
filePath));
diff --git a/pdf-as-pdfbox-2/src/test/resources/data/Test-sign.pdf b/pdf-as-pdfbox-2/src/test/resources/data/Test-sign.pdf
new file mode 100644
index 00000000..7395663e
--- /dev/null
+++ b/pdf-as-pdfbox-2/src/test/resources/data/Test-sign.pdf
Binary files differ
diff --git a/pdf-as-pdfbox-2/src/test/resources/data/Testdoc_Signatur.pdf b/pdf-as-pdfbox-2/src/test/resources/data/Testdoc_Signatur.pdf
new file mode 100644
index 00000000..81af9006
--- /dev/null
+++ b/pdf-as-pdfbox-2/src/test/resources/data/Testdoc_Signatur.pdf
Binary files differ
diff --git a/pdf-as-pdfbox-2/src/test/resources/data/own_Testdoc+Signatur-sign-sign-4_sign-sign.pdf b/pdf-as-pdfbox-2/src/test/resources/data/own_Testdoc+Signatur-sign-sign-4_sign-sign.pdf
new file mode 100644
index 00000000..d1623f5e
--- /dev/null
+++ b/pdf-as-pdfbox-2/src/test/resources/data/own_Testdoc+Signatur-sign-sign-4_sign-sign.pdf
Binary files differ
diff --git a/pdf-as-pdfbox-2/src/test/resources/data/own_Testdoc+Signatur-sign-sign-4_sign.pdf b/pdf-as-pdfbox-2/src/test/resources/data/own_Testdoc+Signatur-sign-sign-4_sign.pdf
new file mode 100644
index 00000000..72d6007f
--- /dev/null
+++ b/pdf-as-pdfbox-2/src/test/resources/data/own_Testdoc+Signatur-sign-sign-4_sign.pdf
Binary files differ
diff --git a/pdf-as-pdfbox-2/src/test/resources/data/own_Testdoc+Signatur-sign-sign.pdf b/pdf-as-pdfbox-2/src/test/resources/data/own_Testdoc+Signatur-sign-sign.pdf
new file mode 100644
index 00000000..5c472d46
--- /dev/null
+++ b/pdf-as-pdfbox-2/src/test/resources/data/own_Testdoc+Signatur-sign-sign.pdf
Binary files differ
diff --git a/pdf-as-pdfbox-2/src/test/resources/data/own_Testdoc+Signatur-sign.pdf b/pdf-as-pdfbox-2/src/test/resources/data/own_Testdoc+Signatur-sign.pdf
new file mode 100644
index 00000000..1bda36c6
--- /dev/null
+++ b/pdf-as-pdfbox-2/src/test/resources/data/own_Testdoc+Signatur-sign.pdf
Binary files differ
diff --git a/pdf-as-tests/build.gradle b/pdf-as-tests/build.gradle
index 1ee5e964..95b953d6 100644
--- a/pdf-as-tests/build.gradle
+++ b/pdf-as-tests/build.gradle
@@ -37,9 +37,6 @@ dependencies {
implementation group: 'javax.activation', name: 'activation', version: '1.1.1'
implementation project (':pdf-as-pdfbox-2')
- //compile group: 'org.apache.pdfbox', name: 'preflight', version: '2.0.21'
- //compile group: 'org.apache.pdfbox', name: 'pdfbox', version: '2.0.21'
- //compile group: 'org.apache.pdfbox', name: 'pdfbox-tools', version: '2.0.21'
}
diff --git a/pdf-as-web-client/build.gradle b/pdf-as-web-client/build.gradle
index 494f8cb3..781ee45b 100644
--- a/pdf-as-web-client/build.gradle
+++ b/pdf-as-web-client/build.gradle
@@ -13,7 +13,7 @@ repositories {
}
dependencies {
- implementation 'org.apache.commons:commons-collections4:4.4'
+ implementation 'org.apache.commons:commons-collections4:4.5.0'
implementation group: 'javax.xml.ws', name: 'jaxws-api', version: '2.3.1'
implementation project (':pdf-as-common')
}
diff --git a/pdf-as-web-statistic-api/build.gradle b/pdf-as-web-statistic-api/build.gradle
index 10f02252..4b6b8c0a 100644
--- a/pdf-as-web-statistic-api/build.gradle
+++ b/pdf-as-web-statistic-api/build.gradle
@@ -22,7 +22,7 @@ sourceSets.test.runtimeClasspath += configurations.providedCompile
dependencies {
implementation group: 'org.slf4j', name: 'slf4j-api', version: slf4jVersion
- implementation 'org.apache.commons:commons-lang3:3.17.0'
+ implementation 'org.apache.commons:commons-lang3:3.20.0'
testImplementation group: 'junit', name: 'junit', version: '4.+'
}
diff --git a/pdf-as-web-status/build.gradle b/pdf-as-web-status/build.gradle
index 550a205c..4f6c222c 100644
--- a/pdf-as-web-status/build.gradle
+++ b/pdf-as-web-status/build.gradle
@@ -22,7 +22,7 @@ sourceSets.test.runtimeClasspath += configurations.providedCompile
dependencies {
implementation group: 'org.slf4j', name: 'slf4j-api', version: slf4jVersion
- implementation 'org.apache.commons:commons-lang3:3.17.0'
+ implementation 'org.apache.commons:commons-lang3:3.20.0'
compileOnly 'javax.servlet:javax.servlet-api:3.0.1'
}
diff --git a/pdf-as-web/build.gradle b/pdf-as-web/build.gradle
index 926d19fd..319aa7f8 100644
--- a/pdf-as-web/build.gradle
+++ b/pdf-as-web/build.gradle
@@ -57,7 +57,7 @@ dependencies {
api project (':pdf-as-web-statistic-api')
api project (':pdf-as-pdfbox-2')
api group: 'commons-fileupload', name: 'commons-fileupload', version: '1.5'
- api group: 'commons-io', name: 'commons-io', version: '2.16.1'
+ api group: 'commons-io', name: 'commons-io', version: '2.21.0'
api group: 'opensymphony', name: 'sitemesh', version: '2.4.2'
api group: 'javax.xml.bind', name: 'jaxb-api', version: '2.3.1'
api group: 'javax.xml.ws', name: 'jaxws-api', version: '2.3.1'
@@ -65,16 +65,16 @@ dependencies {
api "commons-codec:commons-codec:1.17.1"
api 'org.apache.commons:commons-lang3:3.17.0'
api group: 'org.apache.commons', name: 'commons-collections4', version: '4.4'
- api 'org.apache.cxf:cxf-rt-transports-http:3.5.9'
- api 'org.apache.cxf:cxf-rt-frontend-jaxws:3.5.9'
+ api 'org.apache.cxf:cxf-rt-transports-http:3.5.11'
+ api 'org.apache.cxf:cxf-rt-frontend-jaxws:3.5.11'
api 'com.thetransactioncompany:cors-filter:2.10'
api 'ch.qos.logback:logback-classic:1.2.13'
api 'ch.qos.logback:logback-core:1.2.13'
- api 'org.json:json:20240303'
+ api 'org.json:json:20251224'
api group: 'javax.jws', name: 'javax.jws-api', version: '1.1'
compileOnly 'javax.servlet:javax.servlet-api:3.0.1'
- testImplementation 'org.springframework:spring-test:5.3.31'
- testImplementation 'org.springframework:spring-web:5.3.31'
+ testImplementation 'org.springframework:spring-test:5.3.39'
+ testImplementation 'org.springframework:spring-web:5.3.39'
}
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/exception/PdfAsSecurityLayerException.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/exception/PdfAsSecurityLayerException.java
index 08577034..bc5a4d02 100644
--- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/exception/PdfAsSecurityLayerException.java
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/exception/PdfAsSecurityLayerException.java
@@ -33,5 +33,10 @@ public class PdfAsSecurityLayerException extends Exception {
public PdfAsSecurityLayerException(String info, int errorcode) {
super("SecurityLayer Error: [" + errorcode + "] " + info);
}
+
+ public PdfAsSecurityLayerException(String info, int errorcode, Exception e) {
+ super("SecurityLayer Error: [" + errorcode + "] " + info, e);
+
+ }
}
diff --git a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/DataURLServlet.java b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/DataURLServlet.java
index 50c3b063..18e14c97 100644
--- a/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/DataURLServlet.java
+++ b/pdf-as-web/src/main/java/at/gv/egiz/pdfas/web/servlets/DataURLServlet.java
@@ -32,6 +32,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.JAXBElement;
+import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -78,41 +79,58 @@ public class DataURLServlet extends HttpServlet {
}
protected void process(HttpServletRequest request,
- HttpServletResponse response) throws ServletException, IOException {
- try {
+ HttpServletResponse response) throws ServletException, IOException {
+ String xmlResponse = null;
+ try {
if(!PdfAsHelper.checkDataUrlAccess(request)) {
throw new Exception("No valid dataURL access");
+
}
PdfAsHelper.setFromDataUrl(request);
- String xmlResponse = request.getParameter("XMLResponse");
+ xmlResponse = request.getParameter("XMLResponse");
- //System.out.println(xmlResponse);
+ if (StringUtils.isEmpty(xmlResponse)) {
+ logger.error("SL response is null or empty");
+ throw new PdfAsSecurityLayerException("SL response is null or empty", 9999);
+
+ }
JAXBElement<?> jaxbObject = (JAXBElement<?>) SLMarschaller.unmarshalFromString(xmlResponse);
if(jaxbObject.getValue() instanceof InfoboxReadResponseType) {
InfoboxReadResponseType infoboxReadResponseType = (InfoboxReadResponseType)jaxbObject.getValue();
logger.info("Got InfoboxReadResponseType");
PdfAsHelper.injectCertificate(request, response, PdfAsHelper.getCertificate(infoboxReadResponseType), getServletContext());
+
} else if(jaxbObject.getValue() instanceof CreateCMSSignatureResponseType) {
CreateCMSSignatureResponseType createCMSSignatureResponseType = (CreateCMSSignatureResponseType)jaxbObject.getValue();
logger.info("Got CreateCMSSignatureResponseType");
PdfAsHelper.injectSignature(request, response, createCMSSignatureResponseType.getCMSSignature(), getServletContext());
+
} else if(jaxbObject.getValue() instanceof ErrorResponseType) {
ErrorResponseType errorResponseType = (ErrorResponseType)jaxbObject.getValue();
logger.warn("SecurityLayer: " + errorResponseType.getErrorCode() + " " + errorResponseType.getInfo());
- throw new PdfAsSecurityLayerException(errorResponseType.getInfo(),
- errorResponseType.getErrorCode());
+ throw new PdfAsSecurityLayerException(errorResponseType.getInfo(), errorResponseType.getErrorCode());
+
} else {
logger.error("Unknown SL response {}", xmlResponse);
- throw new PdfAsSecurityLayerException("Unknown SL response",
- 9999);
+ throw new PdfAsSecurityLayerException("Unknown SL response", 9999);
+
}
- } catch (Exception e) {
- logger.warn("Error in DataURL Servlet. " , e);
- PdfAsHelper.setSessionException(request, response, e.getMessage(),
- e);
+
+ } catch (PdfAsSecurityLayerException e) {
+ PdfAsHelper.setSessionException(request, response, e.getMessage(), e);
+ PdfAsHelper.gotoError(getServletContext(), request, response);
+
+ } catch (Exception e) {
+ logger.debug("Receive XML response from VDA: {}",
+ StringUtils.isNotEmpty(xmlResponse) ? xmlResponse : " ...empty response...");
+ logger.warn("General Error in DataURL Servlet. " , e);
+
+ PdfAsHelper.setSessionException(request, response, e.getMessage(),
+ new PdfAsSecurityLayerException("Invalid SL response", 9999, e));
PdfAsHelper.gotoError(getServletContext(), request, response);
+
}
}
diff --git a/signature-standards/sigs-pades/build.gradle b/signature-standards/sigs-pades/build.gradle
index d28d5da5..be7777c0 100644
--- a/signature-standards/sigs-pades/build.gradle
+++ b/signature-standards/sigs-pades/build.gradle
@@ -23,7 +23,7 @@ releases.dependsOn sourcesJar
dependencies {
implementation project (':pdf-as-lib')
implementation project (':pdf-as-common')
- implementation 'org.apache.commons:commons-collections4:4.4'
+ implementation 'org.apache.commons:commons-collections4:4.5.0'
testImplementation group: 'junit', name: 'junit', version: '4.+'
}
diff --git a/signature-standards/sigs-pkcs7detached/build.gradle b/signature-standards/sigs-pkcs7detached/build.gradle
index 6b0e2870..3107252f 100644
--- a/signature-standards/sigs-pkcs7detached/build.gradle
+++ b/signature-standards/sigs-pkcs7detached/build.gradle
@@ -23,7 +23,7 @@ releases.dependsOn sourcesJar
dependencies {
implementation project (':pdf-as-lib')
implementation project (':pdf-as-common')
- implementation 'org.apache.commons:commons-collections4:4.4'
+ implementation 'org.apache.commons:commons-collections4:4.5.0'
testImplementation group: 'junit', name: 'junit', version: '4.+'
}