diff options
Diffstat (limited to 'pdf-as-pdfbox-2')
4 files changed, 129 insertions, 88 deletions
diff --git a/pdf-as-pdfbox-2/build.gradle b/pdf-as-pdfbox-2/build.gradle index 1f6dcc55..b71f0939 100644 --- a/pdf-as-pdfbox-2/build.gradle +++ b/pdf-as-pdfbox-2/build.gradle @@ -33,10 +33,10 @@ 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.30' - api group: 'org.apache.pdfbox', name: 'pdfbox-tools', version: '2.0.30' - api group: 'org.apache.pdfbox', name: 'preflight', version: '2.0.30' - implementation group: 'commons-io', name: 'commons-io', version: '2.11.0' + 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: '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' 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 b32935c6..37ceee97 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 @@ -431,11 +431,13 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { final PDDocumentCatalog root = doc.getDocumentCatalog(); final PDStructureTreeRoot structureTreeRoot = root.getStructureTreeRoot(); if (structureTreeRoot != null) { - log.info("Tree Root: {}", structureTreeRoot.toString()); + log.debug("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"); + if (kids == null || kids.isEmpty()) { + log.info("No kid-elements in structure tree Root, maybe not PDF/UA document. Skipping PDF/UA injection ... "); + return; + } PDStructureElement docElement = null; @@ -556,7 +558,12 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { throw new PdfAsException("error.pdf.sig.pdfua.1", e); } else { - log.info("Could not create PDF-UA conform signature"); + if (log.isDebugEnabled()) { + log.debug("Could not create PDF-UA conform signature. Reason: {}", e.getMessage(), e); + + } else { + log.info("Could not create PDF-UA conform signature. Reason: {}", e.getMessage()); + } } } diff --git a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox2/PDFBoxFont.java b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox2/PDFBoxFont.java index a63d9d6f..5607d582 100644 --- a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox2/PDFBoxFont.java +++ b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/stamping/pdfbox2/PDFBoxFont.java @@ -27,8 +27,6 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; -import at.gv.egiz.pdfas.common.settings.SignatureProfileSettings; -import at.gv.egiz.pdfas.lib.impl.stamping.TableFactory; import org.apache.pdfbox.pdmodel.font.PDFont; import org.apache.pdfbox.pdmodel.font.PDType0Font; import org.apache.pdfbox.pdmodel.font.PDType1Font; @@ -158,23 +156,17 @@ public class PDFBoxFont { // return null; // } - private PDFont generateTTF(String fonttype, PDFBOXObject pdfObject) - throws IOException { - - + private PDFont generateTTF(String fonttype, PDFBOXObject pdfObject) throws IOException { ttfFontDesc = fonttype; String fontName = fonttype.replaceFirst("TTF:", ""); - String fontPath = this.settings.getWorkingDirectory() + File.separator - + "fonts" + File.separator + fontName; + String fontPath = this.settings.getWorkingDirectory() + File.separator + "fonts" + File.separator + fontName; logger.debug("Font from: \"" + fontPath + "\"."); - - - PDFAsFontCache fontCache = pdfObject.getSigBlockFontCache(); - + PDFAsFontCache fontCache = pdfObject.getSigBlockFontCache(); if(fontCache.contains(fontPath)){ logger.debug("Using cached font."); return fontCache.getFont(fontPath); + } @@ -209,6 +201,7 @@ public class PDFBoxFont { if (fonttype.startsWith("TTF:")) { // Load TTF Font return generateTTF(fonttype, pdfObject); + } else { if (fontder == null) { fontder = NORMAL; @@ -219,8 +212,10 @@ public class PDFBoxFont { if (font == null) { pdfObject.getSigBlockFontCache().showAvailableFonts(); throw new IOException("Invalid font descriptor \"" + fontDesc + "\""); - } + + } return font; + } } diff --git a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/pdfbox2/PDFBOXVerifier.java b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/pdfbox2/PDFBOXVerifier.java index 270e9e28..1fab2793 100644 --- a/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/pdfbox2/PDFBOXVerifier.java +++ b/pdf-as-pdfbox-2/src/main/java/at/gv/egiz/pdfas/lib/impl/verify/pdfbox2/PDFBOXVerifier.java @@ -33,7 +33,7 @@ public class PDFBOXVerifier implements VerifyBackend { @Override public List<VerifyResult> verify(VerifyParameter parameter) throws PDFASError { int signatureToVerify = parameter.getWhichSignature(); - int currentSignature = 0; + PDDocument doc = null; try { List<VerifyResult> result = new ArrayList<VerifyResult>(); @@ -62,97 +62,136 @@ public class PDFBOXVerifier implements VerifyBackend { return result; } - int lastSig = -1; - for (int i = 0; i < fields.size(); i++) { - COSDictionary field = (COSDictionary) fields.getObject(i); - String type = field.getNameAsString("FT"); - if ("Sig".equals(type)) { - lastSig = i; - } - } - + int lastSig = selectLastSigIndex(fields); byte[] inputData = IOUtils.toByteArray(parameter.getDataSource().getInputStream()); + int currentSignature = 0; for (int i = 0; i < fields.size(); i++) { COSDictionary field = (COSDictionary) fields.getObject(i); String type = field.getNameAsString("FT"); - if ("Sig".equals(type)) { - boolean verifyThis = true; - - if (signatureToVerify >= 0) { - // verify only specific siganture! - verifyThis = signatureToVerify == currentSignature; - } - - if (signatureToVerify == -2) { - verifyThis = i == lastSig; - } - - if (verifyThis) { - logger.trace("Found Signature: "); + if ("Sig".equals(type)) { + if (verifyCurrentSig(signatureToVerify, i, lastSig, currentSignature)) { + logger.trace("Found Signature Form: "); COSBase base = field.getDictionaryObject("V"); - COSDictionary dict = (COSDictionary) base; - - logger.debug("Signer: " + dict.getNameAsString("Name")); - logger.debug("SubFilter: " + dict.getNameAsString("SubFilter")); - logger.debug("Filter: " + dict.getNameAsString("Filter")); - logger.debug("Modified: " + dict.getNameAsString("M")); - COSArray byteRange = (COSArray) dict.getDictionaryObject("ByteRange"); - - StringBuilder sb = new StringBuilder(); - int[] bytes = new int[byteRange.size()]; - for (int j = 0; j < byteRange.size(); j++) { - bytes[j] = byteRange.getInt(j); - sb.append(" " + bytes[j]); - } - - logger.debug("ByteRange" + sb.toString()); - - COSString content = (COSString) dict.getDictionaryObject("Contents"); - - ByteArrayOutputStream contentData = new ByteArrayOutputStream(); - for (int j = 0; j < bytes.length; j = j + 2) { - int offset = bytes[j]; - int length = bytes[j + 1]; - - contentData.write(inputData, offset, length); - } - contentData.close(); - - IVerifyFilter verifyFilter = verifier.getVerifier(dict.getNameAsString("Filter"), - dict.getNameAsString("SubFilter")); - - IVerifier lvlVerifier = verifier.getVerifierByLevel(parameter.getSignatureVerificationLevel()); - synchronized (lvlVerifier) { - lvlVerifier.setConfiguration(parameter.getConfiguration()); - if (verifyFilter != null) { - List<VerifyResult> results = verifyFilter.verify(contentData.toByteArray(), - content.getBytes(), parameter.getVerificationTime(), bytes, lvlVerifier); - if (results != null && !results.isEmpty()) { - result.addAll(results); - } - } + if (base != null) { + checkTechicalSig(base, inputData, verifier, parameter, result, i); + + } else { + logger.info("Skipping signature form, because it looks empty"); + } + } - currentSignature++; + + currentSignature++; } - } + } return result; + } catch (IOException e) { logger.warn("Failed to verify document", e); throw ErrorExtractor.searchPdfAsError(e, null); + } catch (PdfAsException e) { logger.warn("Failed to verify document", e); throw ErrorExtractor.searchPdfAsError(e, null); + } finally { if (doc != null) { try { doc.close(); + } catch (IOException e) { logger.info("Failed to close doc"); + } } } } + private boolean verifyCurrentSig(int signatureToVerify, int i, int lastSig, int currentSignature) { + if (signatureToVerify >= 0) { + // verify only specific siganture! + return signatureToVerify == currentSignature; + + } + + if (signatureToVerify == -2) { + return i == lastSig; + + } + + return true; + } + + private int selectLastSigIndex(COSArray fields) { + int lastSig = -1; + for (int i = 0; i < fields.size(); i++) { + COSDictionary field = (COSDictionary) fields.getObject(i); + String type = field.getNameAsString("FT"); + if ("Sig".equals(type)) { + lastSig = i; + } + } + + return lastSig; + + } + + private void checkTechicalSig(COSBase base, byte[] inputData, VerifierDispatcher verifier, VerifyParameter parameter, + List<VerifyResult> result, int i) throws IOException, PdfAsException { + try { + COSDictionary dict = (COSDictionary) base; + + logger.debug("Signer: " + dict.getNameAsString("Name")); + logger.debug("SubFilter: " + dict.getNameAsString("SubFilter")); + logger.debug("Filter: " + dict.getNameAsString("Filter")); + logger.debug("Modified: " + dict.getNameAsString("M")); + COSArray byteRange = (COSArray) dict.getDictionaryObject("ByteRange"); + + StringBuilder sb = new StringBuilder(); + int[] bytes = new int[byteRange.size()]; + for (int j = 0; j < byteRange.size(); j++) { + bytes[j] = byteRange.getInt(j); + sb.append(" " + bytes[j]); + } + + logger.debug("ByteRange" + sb.toString()); + + COSString content = (COSString) dict.getDictionaryObject("Contents"); + + ByteArrayOutputStream contentData = new ByteArrayOutputStream(); + for (int j = 0; j < bytes.length; j = j + 2) { + int offset = bytes[j]; + int length = bytes[j + 1]; + + contentData.write(inputData, offset, length); + } + contentData.close(); + + IVerifyFilter verifyFilter = verifier.getVerifier(dict.getNameAsString("Filter"), + dict.getNameAsString("SubFilter")); + + IVerifier lvlVerifier = verifier.getVerifierByLevel(parameter.getSignatureVerificationLevel()); + synchronized (lvlVerifier) { + lvlVerifier.setConfiguration(parameter.getConfiguration()); + if (verifyFilter != null) { + List<VerifyResult> results = verifyFilter.verify(contentData.toByteArray(), + content.getBytes(), parameter.getVerificationTime(), bytes, lvlVerifier); + if (results != null && !results.isEmpty()) { + result.addAll(results); + } + } + } + + } catch (NullPointerException e) { + logger.info("Verification of signature #{} failed with generic error", i); + } + + } + } + + + + |
