diff options
author | Andreas Fitzek <andreas.fitzek@iaik.tugraz.at> | 2015-05-06 13:12:27 +0200 |
---|---|---|
committer | Andreas Fitzek <andreas.fitzek@iaik.tugraz.at> | 2015-05-06 13:12:27 +0200 |
commit | d389d024c2e4c6922e8f44af40be32218244887f (patch) | |
tree | f7aa41ae74db9b518136c50b8e59ea02b0bc14d7 /pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing | |
parent | ec4490769f0fc9c1562688b2393e97885f39a04b (diff) | |
parent | ea72400ae232d20c76ddd2be91f39a1bbbdb4e71 (diff) | |
download | pdf-as-4-d389d024c2e4c6922e8f44af40be32218244887f.tar.gz pdf-as-4-d389d024c2e4c6922e8f44af40be32218244887f.tar.bz2 pdf-as-4-d389d024c2e4c6922e8f44af40be32218244887f.zip |
merge PDFUA
Diffstat (limited to 'pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing')
-rw-r--r-- | pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java | 170 |
1 files changed, 136 insertions, 34 deletions
diff --git a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java index d1337ce2..8095911d 100644 --- a/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java +++ b/pdf-as-pdfbox/src/main/java/at/gv/egiz/pdfas/lib/impl/signing/pdfbox/PADESPDFBOXSigner.java @@ -39,8 +39,10 @@ import java.util.Calendar; import java.util.List; import org.apache.commons.io.IOUtils; +import org.apache.pdfbox.cos.COSArray; import org.apache.pdfbox.cos.COSBase; import org.apache.pdfbox.cos.COSDictionary; +import org.apache.pdfbox.cos.COSInteger; import org.apache.pdfbox.cos.COSName; import org.apache.pdfbox.cos.COSString; import org.apache.pdfbox.exceptions.COSVisitorException; @@ -50,8 +52,13 @@ import org.apache.pdfbox.pdmodel.PDDocumentCatalog; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageNode; import org.apache.pdfbox.pdmodel.PDResources; +import org.apache.pdfbox.pdmodel.common.PDNumberTreeNode; +import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDAttributeObject; +import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureElement; +import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureTreeRoot; import org.apache.pdfbox.pdmodel.graphics.color.PDOutputIntent; import org.apache.pdfbox.pdmodel.graphics.xobject.PDJpeg; +import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget; import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature; import org.apache.pdfbox.pdmodel.interactive.digitalsignature.SignatureOptions; import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm; @@ -105,6 +112,8 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { PDFASSignatureInterface genericSigner) throws PdfAsException { String fisTmpFile = null; + PDFAsVisualSignatureProperties properties=null; + if (!(genericPdfObject instanceof PDFBOXObject)) { // tODO: throw new PdfAsException(); @@ -152,8 +161,8 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { logger.debug("Placeholder Profile set to: " + signaturePlaceholderData.getProfile()); requestedSignature - .setSignatureProfileID(signaturePlaceholderData - .getProfile()); + .setSignatureProfileID(signaturePlaceholderData + .getProfile()); } tablePos = signaturePlaceholderData.getTablePos(); @@ -165,7 +174,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { PDSignature signature = new PDSignature(); signature.setFilter(COSName.getPDFName(signer.getPDFFilter())); // default - // filter + // filter signature.setSubFilter(COSName.getPDFName(signer .getPDFSubFilter())); @@ -313,7 +322,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { requestedSignature.setSignaturePosition(position); - PDFAsVisualSignatureProperties properties = new PDFAsVisualSignatureProperties( + properties = new PDFAsVisualSignatureProperties( pdfObject.getStatus().getSettings(), pdfObject, (PdfBoxVisualObject) visualObject, positioningInstruction, signatureProfileSettings); @@ -348,7 +357,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { logger.info("Placeholder name: " + signaturePlaceholderData - .getPlaceholderName()); + .getPlaceholderName()); COSDictionary xobjectsDictionary = (COSDictionary) page .findResources().getCOSDictionary() .getDictionaryObject(COSName.XOBJECT); @@ -356,10 +365,10 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { .getPlaceholderName(), img); xobjectsDictionary.setNeedToBeUpdate(true); page.findResources().getCOSObject() - .setNeedToBeUpdate(true); + .setNeedToBeUpdate(true); logger.info("Placeholder name: " + signaturePlaceholderData - .getPlaceholderName()); + .getPlaceholderName()); } finally { IOUtils.closeQuietly(is); } @@ -397,23 +406,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { } } - // if (signatureProfileSettings.isPDFA()) { // Check for - // PDF-UA - // PDDocumentCatalog root = doc.getDocumentCatalog(); - // PDStructureTreeRoot treeRoot = - // root.getStructureTreeRoot(); - // if (treeRoot != null) { // Handle as PDF-UA - // logger.info("Tree Root: {}", treeRoot.toString()); - // PDStructureElement docElement = PDFBoxTaggingUtils - // .getDocumentElement(treeRoot); - // PDStructureElement sigBlock = new PDStructureElement( - // "Table", docElement); - // root.getCOSObject().setNeedToBeUpdate(true); - // docElement.getCOSObject().setNeedToBeUpdate(true); - // treeRoot.getCOSObject().setNeedToBeUpdate(true); - // sigBlock.setTitle("Signature Table"); - // } - // } + options.setPage(positioningInstruction.getPage()); options.setVisualSignature(properties.getVisibleSignature()); @@ -433,25 +426,35 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { sigFieldName = sigFieldName + count; PDAcroForm acroFormm = doc.getDocumentCatalog().getAcroForm(); + + // PDStructureTreeRoot pdstRoot = doc.getDocumentCatalog().getStructureTreeRoot(); + // COSDictionary dic = doc.getDocumentCatalog().getCOSDictionary(); + // PDStructureElement el = new PDStructureElement("Widget", pdstRoot); + + + + PDSignatureField signatureField = null; if (acroFormm != null) { @SuppressWarnings("unchecked") List<PDField> fields = acroFormm.getFields(); - PDSignatureField signatureField = null; + if (fields != null) { for (PDField pdField : fields) { if (pdField != null) { if (pdField instanceof PDSignatureField) { PDSignatureField tmpSigField = (PDSignatureField) pdField; + if (tmpSigField.getSignature() != null && tmpSigField.getSignature() - .getDictionary() != null) { + .getDictionary() != null) { if (tmpSigField .getSignature() .getDictionary() .equals(signature .getDictionary())) { signatureField = (PDSignatureField) pdField; + } } } @@ -462,12 +465,111 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { } if (signatureField != null) { - signatureField.setPartialName(sigFieldName); + signatureField.setPartialName(sigFieldName); + } + if(properties!=null){ + signatureField.setAlternateFieldName(properties.getAlternativeTableCaption()); + }else{ + signatureField.setAlternateFieldName(sigFieldName); } } else { logger.warn("Failed to name Signature Field! [Cannot find acroForm!]"); } + // PDF-UA + logger.info("Adding pdf/ua content."); + try{ + PDDocumentCatalog root = doc.getDocumentCatalog(); + PDStructureTreeRoot treeRoot = root.getStructureTreeRoot(); + + logger.info("Tree Root: {}", treeRoot.toString()); + List<Object> kids = treeRoot.getKids(); + + if(kids==null){ + logger.info("No kid-elements in structure tree Root, maybe not PDF/UA document"); + } + + PDStructureElement docElement = null; + for(Object k: kids){ + if(k instanceof PDStructureElement){ + docElement=(PDStructureElement) k; + break; + // if(((PDStructureElement) k).getStructureType().equals("Document")){ + // docElement=(PDStructureElement) k; + // } + } + } + + PDStructureElement sigBlock = new PDStructureElement( + "Form", docElement); + + //create object dictionary and add as child element + COSDictionary objectdic= new COSDictionary(); + objectdic.setName("Type", "OBJR"); + objectdic.setItem("Pg", signatureField.getWidget().getPage()); + objectdic.setItem("Obj", signatureField.getWidget()); + + List<Object> l = new ArrayList<Object>(); + l.add(objectdic); + sigBlock.setKids(l); + + sigBlock.setTitle("Signature Table"); + sigBlock.setParent(docElement); + docElement.appendKid(sigBlock); + + //Create and add Attribute dictionary to mitigate PAC warning + COSDictionary sigBlockDic = (COSDictionary) sigBlock.getCOSObject(); + COSDictionary sub = new COSDictionary(); + + sub.setName("O", "Layout"); + sub.setName("Placement", "Block"); + sigBlockDic.setItem(COSName.A, sub); + sigBlockDic.setNeedToBeUpdate(true); + + + //Modify number tree + PDNumberTreeNode ntn = treeRoot.getParentTree(); + if(ntn==null){ + ntn = new PDNumberTreeNode(objectdic, null); + logger.info("No number-tree-node found!"); + } + + COSDictionary ntndic=ntn.getCOSDictionary(); + COSArray ntndicnumbersarray = (COSArray)ntndic.getDictionaryObject(COSName.NUMS); + int arrindex = ntndicnumbersarray.size(); + int treeindex = arrindex/2; + + ntndicnumbersarray.add(arrindex, COSInteger.get(treeindex)); + ntndicnumbersarray.add(arrindex+1, sigBlock.getCOSObject()); + + treeRoot.setParentTree(ntn); + treeRoot.setParentTreeNextKey(treeindex+1); + + //setStructureParent + PDAnnotationWidget widg=signatureField.getWidget(); + widg.setStructParent(treeindex); + + //add the Tabs /S Element for Tabbing through annots + PDPage p = signatureField.getWidget().getPage(); + p.getCOSDictionary().setName("Tabs", "S"); + p.getCOSObject().setNeedToBeUpdate(true); + + ntndic.setNeedToBeUpdate(true); + sigBlock.getCOSObject().setNeedToBeUpdate(true); + treeRoot.getCOSObject().setNeedToBeUpdate(true); + objectdic.getCOSObject().setNeedToBeUpdate(true); + docElement.getCOSObject().setNeedToBeUpdate(true); + + + }catch(Throwable e){ + if (signatureProfileSettings.isPDFUA()==true){ + logger.error("Could not create PDF-UA conform document!"); + throw new PdfAsException("error.pdf.sig.pdfua.1", e); + }else{ + logger.info("Could not create PDF-UA conform signature"); + } + } + if (requestedSignature.isVisual()) { // if(requestedSignature.getSignaturePosition().) @@ -559,7 +661,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { // Ignore } } - + if(fisTmpFile != null) { helper.deleteFile(fisTmpFile); } @@ -609,7 +711,7 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { public Image generateVisibleSignaturePreview(SignParameter parameter, java.security.cert.X509Certificate cert, int resolution, OperationStatus status, RequestedSignature requestedSignature) - throws PDFASError { + throws PDFASError { try { PDFBOXObject pdfObject = (PDFBOXObject) status.getPdfObject(); @@ -693,11 +795,11 @@ public class PADESPDFBOXSigner implements IPdfSigner, IConfigurationConstants { graphics.drawImage(outputImage, 0, 0, cutOut.getWidth(), cutOut .getHeight(), (int) (1 * factor), (int) (outputImage - .getHeight() - ((position.getHeight() + 1) * factor)), - (int) ((1 + position.getWidth()) * factor), - (int) (outputImage.getHeight() - - ((position.getHeight() + 1) * factor) + (position - .getHeight() * factor)), null); + .getHeight() - ((position.getHeight() + 1) * factor)), + (int) ((1 + position.getWidth()) * factor), + (int) (outputImage.getHeight() + - ((position.getHeight() + 1) * factor) + (position + .getHeight() * factor)), null); return cutOut; } catch (PdfAsException e) { logger.warn("PDF-AS Exception", e); |