From ba44d7d68696e76b86a82e51ecc02b1f2a3d9aa9 Mon Sep 17 00:00:00 2001 From: emusic Date: Thu, 14 Nov 2019 14:34:50 +0100 Subject: Adobe signature field search enabled --- .../pdfas/lib/api/IConfigurationConstants.java | 6 ++ .../impl/signing/pdfbox2/PADESPDFBOXSigner.java | 102 ++++++++++++++++++--- .../pdfbox2/PDFAsVisualSignatureProperties.java | 20 ++-- 3 files changed, 104 insertions(+), 24 deletions(-) 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 a9b8bb2f..610f5eba 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 @@ -54,6 +54,12 @@ public interface IConfigurationConstants { public static final String CONFIG_BKU_URL = "bku.sign.url"; + /*Acrobat Signature Fields */ + + public static final String SIGNATURE_FIELD_NAME = "signature_field_name"; + + + /** * MOA SS Signing Key Identifier */ 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 326ba74f..ccf99902 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 @@ -102,10 +102,10 @@ import java.util.List; public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { private static final Logger logger = LoggerFactory.getLogger(PADESPDFBOXSigner.class); + private boolean isAdobeSigForm = false; public void signPDF(PDFObject genericPdfObject, RequestedSignature requestedSignature, PDFASSignatureInterface genericSigner) throws PdfAsException { - //String fisTmpFile = null; PDFAsVisualSignatureProperties properties = null; @@ -163,7 +163,25 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { } } - PDSignature signature = new PDSignature(); + //PDSignature signature = new PDSignature(); + + 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); + //signature = findExistingSignature(doc, "ownerSignature"); + if (signature == null) + { + // create signature dictionary + signature = new PDSignature(); + + } + else + { + isAdobeSigForm = true; + } + signature.setFilter(COSName.getPDFName(signer.getPDFFilter())); // default // filter signature.setSubFilter(COSName.getPDFName(signer.getPDFSubFilter())); @@ -219,6 +237,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { signatureProfileSettings.setPDFAVersion(pdfaVersion); } + // Is visible Signature if (requestedSignature.isVisual()) { logger.info("Creating visual siganture block"); @@ -264,6 +283,8 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { // boolean legacy40Position = signatureProfileConfiguration.getLegacy40Positioning(); // create Table describtion + + Table main = TableFactory.createSigTable(signatureProfileSettings, MAIN, pdfObject.getStatus(), requestedSignature); @@ -282,6 +303,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { logger.debug("Positioning: {}", positioningInstruction.toString()); + if(!isAdobeSigForm){ if (positioningInstruction.isMakeNewPage()) { int last = doc.getNumberOfPages() - 1; PDDocumentCatalog root = doc.getDocumentCatalog(); @@ -311,6 +333,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { position.setWidth(visualObject.getWidth()); requestedSignature.setSignaturePosition(position); + } properties = new PDFAsVisualSignatureProperties(pdfObject.getStatus().getSettings(), pdfObject, (PdfBoxVisualObject) visualObject, positioningInstruction, signatureProfileSettings); @@ -381,6 +404,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { IOUtils.closeQuietly(colorProfile); } } + options.setPage(positioningInstruction.getPage()-1); options.setVisualSignature(properties.getVisibleSignature()); } @@ -389,9 +413,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { doc.addSignature(signature, signer, options); - - - String sigFieldName = signatureProfileSettings.getSignFieldValue(); + //String sigFieldName = "ownerSignature"; if (sigFieldName == null) { sigFieldName = "PDF-AS Signatur"; @@ -410,7 +432,9 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { // PDStructureElement el = new PDStructureElement("Widget", // pdstRoot); - PDSignatureField signatureField = null; + //this is not used for Adobe signature fields + if(!isAdobeSigForm){ + PDSignatureField signatureField = null; if (acroFormm != null) { @SuppressWarnings("unchecked") List fields = acroFormm.getFields(); @@ -447,6 +471,14 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { } else { logger.warn("Failed to name Signature Field! [Cannot find acroForm!]"); } + } + + + PDSignatureField signatureField = null; + PDAcroForm acroForm = doc.getDocumentCatalog().getAcroForm(); + if (acroForm != null) { + signatureField = (PDSignatureField) acroForm.getField(sigFieldName); + } // PDF-UA logger.info("Adding pdf/ua content."); @@ -586,16 +618,13 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); - synchronized (doc) { doc.saveIncremental(bos); byte[] outputDocument = bos.toByteArray(); doc.save(bos); pdfObject.setSignedDocument(outputDocument); } - /* - Check if resulting pdf is PDF-A conform - */ + /* Check if resulting pdf is PDF-A conform */ if (signatureProfileSettings.isPDFA()) { runPDFAPreflight(new ByteArrayDataSource(pdfObject.getSignedDocument())); } @@ -620,8 +649,6 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { if (doc != null) { try { doc.close(); - - } catch (IOException e) { logger.debug("Failed to close COS Doc!", e); // Ignore @@ -841,4 +868,55 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { } return null; } + + // Find an existing signature. + private PDSignature findExistingSignature(PDDocument doc, String sigFieldName) + { + findEmptySignatureFields(doc); + PDSignature signature = null; + PDSignatureField signatureField; + PDAcroForm acroForm = doc.getDocumentCatalog().getAcroForm(); + if (acroForm != null) + { + signatureField = (PDSignatureField) acroForm.getField(sigFieldName); + if (signatureField != null) + { + // retrieve signature dictionary + signature = signatureField.getSignature(); + if (signature == null) + { + signature = new PDSignature(); + // after solving PDFBOX-3524 + // signatureField.setValue(signature) + // until then: + signatureField.getCOSObject().setItem(COSName.V, signature); + } + else + { + throw new IllegalStateException("The signature field " + sigFieldName + " is already signed."); + } + } + } + return signature; + } + + //Find empty signature fields + private List findEmptySignatureFields(PDDocument doc) + { + PDSignature signature; + List signatureField; + List 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; + } } \ No newline at end of file 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 adfd6694..f482f49f 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 @@ -23,9 +23,12 @@ ******************************************************************************/ package at.gv.egiz.pdfas.lib.impl.stamping.pdfbox2; -import java.io.IOException; -import java.util.List; - +import at.gv.egiz.pdfas.common.exceptions.PdfAsException; +import at.gv.egiz.pdfas.common.exceptions.PdfAsWrappedIOException; +import at.gv.egiz.pdfas.common.settings.ISettings; +import at.gv.egiz.pdfas.common.settings.SignatureProfileSettings; +import at.gv.egiz.pdfas.lib.impl.pdfbox2.PDFBOXObject; +import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageTree; @@ -33,12 +36,7 @@ import org.apache.pdfbox.pdmodel.interactive.digitalsignature.visible.PDVisibleS import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import at.gv.egiz.pdfas.common.exceptions.PdfAsException; -import at.gv.egiz.pdfas.common.exceptions.PdfAsWrappedIOException; -import at.gv.egiz.pdfas.common.settings.ISettings; -import at.gv.egiz.pdfas.common.settings.SignatureProfileSettings; -import at.gv.egiz.pdfas.lib.impl.pdfbox2.PDFBOXObject; -import at.knowcenter.wag.egov.egiz.pdf.PositioningInstruction; +import java.io.IOException; public class PDFAsVisualSignatureProperties extends PDVisibleSigProperties { @@ -124,8 +122,7 @@ public class PDFAsVisualSignatureProperties extends PDVisibleSigProperties { public PDFBoxTable getMainTable() { return main; } - - + public float getRotation() { return this.rotationAngle; } @@ -145,5 +142,4 @@ public class PDFAsVisualSignatureProperties extends PDVisibleSigProperties { public void setAlternativeTableCaption(String alternativeTableCaption) { this.alternativeTableCaption = alternativeTableCaption; } - } -- cgit v1.2.3